aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java16
-rw-r--r--java/src/com/android/inputmethod/compat/SettingsSecureCompatUtils.java34
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java9
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java76
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java9
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java4
6 files changed, 103 insertions, 45 deletions
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
index dcebb1c04..1836f27b3 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
@@ -21,6 +21,7 @@ import android.content.SharedPreferences;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.os.SystemClock;
+import android.provider.Settings;
import android.util.Log;
import android.view.MotionEvent;
import android.view.accessibility.AccessibilityEvent;
@@ -31,6 +32,7 @@ import com.android.inputmethod.compat.AccessibilityManagerCompatWrapper;
import com.android.inputmethod.compat.AudioManagerCompatWrapper;
import com.android.inputmethod.compat.InputTypeCompatUtils;
import com.android.inputmethod.compat.MotionEventCompatUtils;
+import com.android.inputmethod.compat.SettingsSecureCompatUtils;
import com.android.inputmethod.latin.R;
public class AccessibilityUtils {
@@ -113,13 +115,23 @@ public class AccessibilityUtils {
}
/**
- * @return {@code true} if the device should not speak text (eg.
- * non-control) characters
+ * Returns whether the device should obscure typed password characters.
+ * Typically this means speaking "dot" in place of non-control characters.
+ *
+ * @return {@code true} if the device should obscure password characters.
*/
public boolean shouldObscureInput(EditorInfo editorInfo) {
if (editorInfo == null)
return false;
+ // The user can optionally force speaking passwords.
+ if (SettingsSecureCompatUtils.ACCESSIBILITY_SPEAK_PASSWORD != null) {
+ final boolean speakPassword = Settings.Secure.getInt(mContext.getContentResolver(),
+ SettingsSecureCompatUtils.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0;
+ if (speakPassword)
+ return false;
+ }
+
// Always speak if the user is listening through headphones.
if (mAudioManager.isWiredHeadsetOn() || mAudioManager.isBluetoothA2dpOn())
return false;
diff --git a/java/src/com/android/inputmethod/compat/SettingsSecureCompatUtils.java b/java/src/com/android/inputmethod/compat/SettingsSecureCompatUtils.java
new file mode 100644
index 000000000..1b79992f0
--- /dev/null
+++ b/java/src/com/android/inputmethod/compat/SettingsSecureCompatUtils.java
@@ -0,0 +1,34 @@
+/*
+ * 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.compat;
+
+import java.lang.reflect.Field;
+
+public class SettingsSecureCompatUtils {
+ private static final Field FIELD_ACCESSIBILITY_SPEAK_PASSWORD = CompatUtils.getField(
+ android.provider.Settings.Secure.class, "ACCESSIBILITY_SPEAK_PASSWORD");
+
+ private SettingsSecureCompatUtils() {
+ // This class is non-instantiable.
+ }
+
+ /**
+ * Whether to speak passwords while in accessibility mode.
+ */
+ public static final String ACCESSIBILITY_SPEAK_PASSWORD = (String) CompatUtils.getFieldValue(
+ null, null, FIELD_ACCESSIBILITY_SPEAK_PASSWORD);
+}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 840857778..ecc821a4b 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.keyboard;
+import android.text.TextUtils;
import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.compat.EditorInfoCompatUtils;
@@ -177,6 +178,14 @@ public class KeyboardId {
);
}
+ public static boolean equivalentEditorInfoForKeyboard(EditorInfo a, EditorInfo b) {
+ if (a == null && b == null) return true;
+ if (a == null || b == null) return false;
+ return a.inputType == b.inputType
+ && a.imeOptions == b.imeOptions
+ && TextUtils.equals(a.privateImeOptions, b.privateImeOptions);
+ }
+
public static String modeName(int mode) {
switch (mode) {
case MODE_TEXT: return "text";
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 32aabf928..71a71d6fd 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -106,6 +106,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
+ // TODO: Move this to KeyboardState.
private class KeyboardLayoutState {
private boolean mIsValid;
private boolean mIsAlphabetMode;
@@ -113,43 +114,36 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private boolean mIsShifted;
public void save() {
- if (mCurrentId == null) {
- return;
- }
mIsAlphabetMode = isAlphabetMode();
if (mIsAlphabetMode) {
mIsShiftLocked = mState.isShiftLocked();
mIsShifted = !mIsShiftLocked && mState.isShiftedOrShiftLocked();
} else {
mIsShiftLocked = false;
- mIsShifted = mCurrentId.equals(mSymbolsShiftedKeyboardId);
+ mIsShifted = isSymbolShifted();
}
mIsValid = true;
}
- public KeyboardId getKeyboardId() {
- if (!mIsValid) return mMainKeyboardId;
-
- if (mIsAlphabetMode) {
- return mMainKeyboardId;
+ public void restore() {
+ mPrevMainKeyboardWasShiftLocked = false;
+ if (!mIsValid || mIsAlphabetMode) {
+ setAlphabetKeyboard();
} else {
- return mIsShifted ? mSymbolsShiftedKeyboardId : mSymbolsKeyboardId;
+ if (mIsShifted) {
+ setSymbolsShiftedKeyboard();
+ } else {
+ setSymbolsKeyboard();
+ }
}
- }
- public void restore() {
if (!mIsValid) return;
mIsValid = false;
if (mIsAlphabetMode) {
- final boolean isAlphabetMode = isAlphabetMode();
- final boolean isShiftLocked = isAlphabetMode && mState.isShiftLocked();
- final boolean isShifted = !isShiftLocked && mState.isShiftedOrShiftLocked();
- if (mIsShiftLocked != isShiftLocked) {
- toggleCapsLock();
- } else if (mIsShifted != isShifted) {
- onPressShift(false);
- onReleaseShift(false);
+ setShiftLocked(mIsShiftLocked);
+ if (!mIsShiftLocked) {
+ setShifted(mIsShifted ? MANUAL_SHIFT : UNSHIFT);
}
}
}
@@ -205,8 +199,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
mMainKeyboardId = getKeyboardId(editorInfo, false, false, settingsValues);
mSymbolsKeyboardId = getKeyboardId(editorInfo, true, false, settingsValues);
mSymbolsShiftedKeyboardId = getKeyboardId(editorInfo, true, true, settingsValues);
+ mState.onLoadKeyboard();
mLayoutSwitchBackSymbols = mResources.getString(R.string.layout_switch_back_symbols);
- setKeyboard(getKeyboard(mSavedKeyboardState.getKeyboardId()));
mSavedKeyboardState.restore();
} catch (RuntimeException e) {
Log.w(TAG, "loading keyboard failed: " + mMainKeyboardId, e);
@@ -215,7 +209,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
public void saveKeyboardState() {
- mSavedKeyboardState.save();
+ if (mCurrentId != null) {
+ mSavedKeyboardState.save();
+ }
}
public void onFinishInputView() {
@@ -382,6 +378,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
private void setShifted(int shiftMode) {
+ mInputMethodService.mHandler.cancelUpdateShiftState();
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard == null)
return;
@@ -405,19 +402,25 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
private void setShiftLocked(boolean shiftLocked) {
+ mInputMethodService.mHandler.cancelUpdateShiftState();
LatinKeyboard latinKeyboard = getLatinKeyboard();
if (latinKeyboard == null)
return;
mState.setShiftLocked(shiftLocked);
latinKeyboard.setShiftLocked(shiftLocked);
mKeyboardView.invalidateAllKeys();
+ if (!shiftLocked) {
+ // To be able to turn off caps lock by "double tap" on shift key, we should ignore
+ // the second tap of the "double tap" from now for a while because we just have
+ // already turned off caps lock above.
+ mKeyboardView.startIgnoringDoubleTap();
+ }
}
/**
* Toggle keyboard shift state triggered by user touch event.
*/
public void toggleShift() {
- mInputMethodService.mHandler.cancelUpdateShiftState();
if (DEBUG_STATE) {
Log.d(TAG, "toggleShift: " + mState);
}
@@ -429,16 +432,16 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
public void toggleCapsLock() {
- mInputMethodService.mHandler.cancelUpdateShiftState();
if (DEBUG_STATE) {
Log.d(TAG, "toggleCapsLock: " + mState);
}
if (isAlphabetMode()) {
if (mState.isShiftLocked()) {
+ setShiftLocked(false);
+ // TODO: Remove this.
// Shift key is long pressed while caps lock state, we will toggle back to normal
// state. And mark as if shift key is released.
- setShiftLocked(false);
- mState.onToggleCapsLock();
+ mState.onReleaseCapsLock();
} else {
setShiftLocked(true);
}
@@ -452,12 +455,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
toggleAlphabetAndSymbols();
}
- private void startIgnoringDoubleTap() {
- if (mKeyboardView != null) {
- mKeyboardView.startIgnoringDoubleTap();
- }
- }
-
/**
* Update keyboard shift state triggered by connected EditText status change.
*/
@@ -505,7 +502,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
// shifted state.
} else {
// In base layout, chording or manual temporary upper case mode is started.
- toggleShift();
+ setShifted(MANUAL_SHIFT);
}
} else {
// In symbol mode, just toggle symbol and symbol more keyboard.
@@ -531,26 +528,22 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
if (isAlphabetMode) {
if (mState.isShiftKeyMomentary()) {
// After chording input while normal state.
- toggleShift();
+ setShifted(UNSHIFT);
} else if (isShiftLocked && !isShiftLockShifted && (mState.isShiftKeyPressing()
|| mState.isShiftKeyPressingOnShifted()) && !withSliding) {
// Shift has been long pressed, ignore this release.
} else if (isShiftLocked && !mState.isShiftKeyIgnoring() && !withSliding) {
// Shift has been pressed without chording while caps lock state.
- toggleCapsLock();
- // To be able to turn off caps lock by "double tap" on shift key, we should ignore
- // the second tap of the "double tap" from now for a while because we just have
- // already turned off caps lock above.
- startIgnoringDoubleTap();
+ setShiftLocked(false);
} else if (isShiftedOrShiftLocked && mState.isShiftKeyPressingOnShifted()
&& !withSliding) {
// Shift has been pressed without chording while shifted state.
- toggleShift();
+ setShifted(UNSHIFT);
} else if (isManualTemporaryUpperCaseFromAuto && mState.isShiftKeyPressing()
&& !withSliding) {
// Shift has been pressed without chording while manual temporary upper case
// transited from automatic temporary upper case.
- toggleShift();
+ setShifted(UNSHIFT);
}
} else {
// In symbol mode, snap back to the previous keyboard mode if the user chords the shift
@@ -601,6 +594,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
}
+ // TODO: Move this variable to KeyboardState.
private boolean mPrevMainKeyboardWasShiftLocked;
private void setSymbolsKeyboard() {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index fd7e77863..e56159405 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -27,6 +27,13 @@ public class KeyboardState {
public KeyboardState() {
}
+ public void onLoadKeyboard() {
+ mKeyboardShiftState.setShifted(false);
+ mKeyboardShiftState.setShiftLocked(false);
+ mShiftKeyState.onRelease();
+ mSymbolKeyState.onRelease();
+ }
+
public boolean isShiftLocked() {
return mKeyboardShiftState.isShiftLocked();
}
@@ -91,7 +98,7 @@ public class KeyboardState {
return mShiftKeyState.isPressingOnShifted();
}
- public void onToggleCapsLock() {
+ public void onReleaseCapsLock() {
mShiftKeyState.onRelease();
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 5f446a5c4..c2656b891 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -62,6 +62,7 @@ import com.android.inputmethod.deprecated.VoiceProxy;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
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;
@@ -442,7 +443,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
public void onStartInputView(EditorInfo editorInfo, boolean restarting) {
- if (hasMessages(MSG_PENDING_IMS_CALLBACK) && editorInfo == mAppliedEditorInfo) {
+ if (hasMessages(MSG_PENDING_IMS_CALLBACK)
+ && KeyboardId.equivalentEditorInfoForKeyboard(editorInfo, mAppliedEditorInfo)) {
// Typically this is the second onStartInputView after orientation changed.
resetPendingImsCallback();
} else {