From cc4b63ec4c3d3622f778c647eb584c68a3c00615 Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Thu, 21 Jul 2011 10:49:16 -0700 Subject: Updated check for touch exploration enabled state Bug: 5061704 Change-Id: Id2c0cce953f7bdb2b4c18b68f9e318d95eabc1b8 --- .../com/android/inputmethod/accessibility/AccessibilityUtils.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java') diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index ae614b7e0..7e71b5f36 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -16,7 +16,6 @@ package com.android.inputmethod.accessibility; -import android.accessibilityservice.AccessibilityServiceInfo; import android.content.Context; import android.content.SharedPreferences; import android.inputmethodservice.InputMethodService; @@ -82,10 +81,8 @@ public class AccessibilityUtils { */ public boolean isTouchExplorationEnabled() { return ENABLE_ACCESSIBILITY - && AccessibilityEventCompatUtils.supportsTouchExploration() && mAccessibilityManager.isEnabled() - && !mCompatManager.getEnabledAccessibilityServiceList( - AccessibilityServiceInfo.FEEDBACK_SPOKEN).isEmpty(); + && mCompatManager.isTouchExplorationEnabled(); } /** -- cgit v1.2.3-83-g751a From b0c8db018d53b103dcb4b699be27a4e1a2c2f92c Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Wed, 5 Oct 2011 16:59:31 -0700 Subject: Let accessibility users know to connect a headset when the IME connects to a password field. Change-Id: If96cd7626950dd12e88a8a97f5e405d303d41e06 --- java/res/values/strings.xml | 3 ++ .../accessibility/AccessibilityUtils.java | 45 +++++++++++++++++++++- .../accessibility/AccessibleKeyboardViewProxy.java | 27 +------------ .../com/android/inputmethod/latin/LatinIME.java | 6 +++ 4 files changed, 54 insertions(+), 27 deletions(-) (limited to 'java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java') diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml index a1f34887b..8bc97f66e 100644 --- a/java/res/values/strings.xml +++ b/java/res/values/strings.xml @@ -142,6 +142,9 @@ Wait + + Plug in a headset to hear password keys spoken aloud. + Current text is "%s" diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index 7e71b5f36..4a2542dec 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -19,15 +19,19 @@ package com.android.inputmethod.accessibility; import android.content.Context; import android.content.SharedPreferences; import android.inputmethodservice.InputMethodService; +import android.media.AudioManager; import android.os.SystemClock; import android.util.Log; import android.view.MotionEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; +import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.compat.AccessibilityEventCompatUtils; 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.latin.R; public class AccessibilityUtils { private static final String TAG = AccessibilityUtils.class.getSimpleName(); @@ -37,8 +41,10 @@ public class AccessibilityUtils { private static final AccessibilityUtils sInstance = new AccessibilityUtils(); + private Context mContext; private AccessibilityManager mAccessibilityManager; private AccessibilityManagerCompatWrapper mCompatManager; + private AudioManagerCompatWrapper mAudioManager; /* * Setting this constant to {@code false} will disable all keyboard @@ -67,9 +73,14 @@ public class AccessibilityUtils { } private void initInternal(Context context, SharedPreferences prefs) { + mContext = context; mAccessibilityManager = (AccessibilityManager) context .getSystemService(Context.ACCESSIBILITY_SERVICE); mCompatManager = new AccessibilityManagerCompatWrapper(mAccessibilityManager); + + final AudioManager audioManager = (AudioManager) context + .getSystemService(Context.AUDIO_SERVICE); + mAudioManager = new AudioManagerCompatWrapper(audioManager); } /** @@ -101,6 +112,22 @@ public class AccessibilityUtils { || action == MotionEventCompatUtils.ACTION_HOVER_MOVE; } + /** + * @return {@code true} if the device should not speak text (eg. + * non-control) characters + */ + public boolean shouldObscureInput(EditorInfo attribute) { + if (attribute == null) + return false; + + // Always speak if the user is listening through headphones. + if (mAudioManager.isWiredHeadsetOn() || mAudioManager.isBluetoothA2dpOn()) + return false; + + // Don't speak if the IME is connected to a password field. + return InputTypeCompatUtils.isPasswordInputType(attribute.inputType); + } + /** * Sends the specified text to the {@link AccessibilityManager} to be * spoken. @@ -117,7 +144,7 @@ public class AccessibilityUtils { // class. Instead, we're just forcing a fake AccessibilityEvent into // the screen reader to make it speak. final AccessibilityEvent event = AccessibilityEvent - .obtain(AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_ENTER); + .obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED); event.setPackageName(PACKAGE); event.setClassName(CLASS); @@ -127,4 +154,18 @@ public class AccessibilityUtils { mAccessibilityManager.sendAccessibilityEvent(event); } + + /** + * Handles speaking the "connect a headset to hear passwords" notification + * when connecting to a password field. + * + * @param attribute The input connection's editor info attribute. + * @param restarting Whether the connection is being restarted. + */ + public void onStartInputViewInternal(EditorInfo attribute, boolean restarting) { + if (shouldObscureInput(attribute)) { + final CharSequence text = mContext.getText(R.string.spoken_use_headphones); + speak(text); + } + } } diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java index e1b778126..4c109c708 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java @@ -21,7 +21,6 @@ import android.content.SharedPreferences; import android.graphics.Color; import android.graphics.Paint; import android.inputmethodservice.InputMethodService; -import android.media.AudioManager; import android.util.Log; import android.view.MotionEvent; import android.view.ViewConfiguration; @@ -29,8 +28,6 @@ import android.view.accessibility.AccessibilityEvent; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.compat.AccessibilityEventCompatUtils; -import com.android.inputmethod.compat.AudioManagerCompatWrapper; -import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.compat.MotionEventCompatUtils; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.KeyDetector; @@ -48,7 +45,6 @@ public class AccessibleKeyboardViewProxy { private FlickGestureDetector mGestureDetector; private LatinKeyboardView mView; private AccessibleKeyboardActionListener mListener; - private AudioManagerCompatWrapper mAudioManager; private int mScaledEdgeSlop; private int mLastHoverKeyIndex = KeyDetector.NOT_A_KEY; @@ -82,26 +78,6 @@ public class AccessibleKeyboardViewProxy { mInputMethod = inputMethod; mGestureDetector = new KeyboardFlickGestureDetector(inputMethod); mScaledEdgeSlop = ViewConfiguration.get(inputMethod).getScaledEdgeSlop(); - - final AudioManager audioManager = (AudioManager) inputMethod - .getSystemService(Context.AUDIO_SERVICE); - mAudioManager = new AudioManagerCompatWrapper(audioManager); - } - - /** - * @return {@code true} if the device should not speak text (eg. non-control) characters - */ - private boolean shouldObscureInput() { - // Always speak if the user is listening through headphones. - if (mAudioManager.isWiredHeadsetOn() || mAudioManager.isBluetoothA2dpOn()) - return false; - - final EditorInfo info = mInputMethod.getCurrentInputEditorInfo(); - if (info == null) - return false; - - // Don't speak if the IME is connected to a password field. - return InputTypeCompatUtils.isPasswordInputType(info.inputType); } public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event, @@ -118,7 +94,8 @@ public class AccessibleKeyboardViewProxy { if (key == null) break; - final boolean shouldObscure = shouldObscureInput(); + final EditorInfo info = mInputMethod.getCurrentInputEditorInfo(); + final boolean shouldObscure = AccessibilityUtils.getInstance().shouldObscureInput(info); final CharSequence description = KeyCodeDescriptionMapper.getInstance() .getDescriptionForKey(mView.getContext(), mView.getKeyboard(), key, shouldObscure); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 36e97af11..1278c5ec8 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -693,6 +693,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return; } + // Forward this event to the accessibility utilities, if enabled. + final AccessibilityUtils accessUtils = AccessibilityUtils.getInstance(); + if (accessUtils.isTouchExplorationEnabled()) { + accessUtils.onStartInputViewInternal(attribute, restarting); + } + mSubtypeSwitcher.updateParametersOnStartInputView(); TextEntryState.reset(); -- cgit v1.2.3-83-g751a From e7eac906c0a14b644d457beeb73a407fa1b63673 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 21 Nov 2011 14:58:32 -0800 Subject: Pending onStartInputView only if the EditorInfo is identical Bug: 5604372 Change-Id: I2a88cf15b07eebd29e43e460f6ec758432181b01 --- .../accessibility/AccessibilityUtils.java | 12 ++-- .../android/inputmethod/deprecated/VoiceProxy.java | 10 +-- .../inputmethod/deprecated/voice/FieldContext.java | 4 +- .../android/inputmethod/keyboard/KeyboardId.java | 12 ++-- .../com/android/inputmethod/latin/LatinIME.java | 83 +++++++++++----------- .../com/android/inputmethod/latin/Settings.java | 4 +- 6 files changed, 64 insertions(+), 61 deletions(-) (limited to 'java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java') diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index 4a2542dec..dcebb1c04 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -116,8 +116,8 @@ public class AccessibilityUtils { * @return {@code true} if the device should not speak text (eg. * non-control) characters */ - public boolean shouldObscureInput(EditorInfo attribute) { - if (attribute == null) + public boolean shouldObscureInput(EditorInfo editorInfo) { + if (editorInfo == null) return false; // Always speak if the user is listening through headphones. @@ -125,7 +125,7 @@ public class AccessibilityUtils { return false; // Don't speak if the IME is connected to a password field. - return InputTypeCompatUtils.isPasswordInputType(attribute.inputType); + return InputTypeCompatUtils.isPasswordInputType(editorInfo.inputType); } /** @@ -159,11 +159,11 @@ public class AccessibilityUtils { * Handles speaking the "connect a headset to hear passwords" notification * when connecting to a password field. * - * @param attribute The input connection's editor info attribute. + * @param editorInfo The input connection's editor info attribute. * @param restarting Whether the connection is being restarted. */ - public void onStartInputViewInternal(EditorInfo attribute, boolean restarting) { - if (shouldObscureInput(attribute)) { + public void onStartInputViewInternal(EditorInfo editorInfo, boolean restarting) { + if (shouldObscureInput(editorInfo)) { final CharSequence text = mContext.getText(R.string.spoken_use_headphones); speak(text); } diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java index 3f8c2ef8f..a013ebca9 100644 --- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java +++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java @@ -695,12 +695,12 @@ public class VoiceProxy implements VoiceInput.UiListener { && !mVoiceInput.isBlacklistedField(fieldContext); } - private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo attribute) { + private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo editorInfo) { @SuppressWarnings("deprecation") final boolean noMic = Utils.inPrivateImeOptions(null, - LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, attribute) + LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo) || Utils.inPrivateImeOptions(mService.getPackageName(), - LatinIME.IME_OPTION_NO_MICROPHONE, attribute); + LatinIME.IME_OPTION_NO_MICROPHONE, editorInfo); return ENABLE_VOICE_BUTTON && fieldCanDoVoice(fieldContext) && !noMic && SpeechRecognizer.isRecognitionAvailable(mService); } @@ -709,7 +709,7 @@ public class VoiceProxy implements VoiceInput.UiListener { return SpeechRecognizer.isRecognitionAvailable(context); } - public void loadSettings(EditorInfo attribute, SharedPreferences sp) { + public void loadSettings(EditorInfo editorInfo, SharedPreferences sp) { if (!VOICE_INSTALLED) { return; } @@ -723,7 +723,7 @@ public class VoiceProxy implements VoiceInput.UiListener { final String voiceMode = sp.getString(PREF_VOICE_MODE, mService.getString(R.string.voice_mode_main)); mVoiceButtonEnabled = !voiceMode.equals(mService.getString(R.string.voice_mode_off)) - && shouldShowVoiceButton(makeFieldContext(), attribute); + && shouldShowVoiceButton(makeFieldContext(), editorInfo); mVoiceButtonOnPrimary = voiceMode.equals(mService.getString(R.string.voice_mode_main)); } diff --git a/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java index 3c79cc218..fd2cf3d25 100644 --- a/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java +++ b/java/src/com/android/inputmethod/deprecated/voice/FieldContext.java @@ -43,10 +43,10 @@ public class FieldContext { Bundle mFieldInfo; - public FieldContext(InputConnection conn, EditorInfo info, + public FieldContext(InputConnection conn, EditorInfo editorInfo, String selectedLanguage, String[] enabledLanguages) { mFieldInfo = new Bundle(); - addEditorInfoToBundle(info, mFieldInfo); + addEditorInfoToBundle(editorInfo, mFieldInfo); addInputConnectionToBundle(conn, mFieldInfo); addLanguageInfoToBundle(selectedLanguage, enabledLanguages, mFieldInfo); if (DBG) Log.i("FieldContext", "Bundle = " + mFieldInfo.toString()); diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java index cf0637124..840857778 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -58,15 +58,15 @@ public class KeyboardId { public final int mImeAction; public final String mXmlName; - public final EditorInfo mAttribute; + public final EditorInfo mEditorInfo; private final int mHashCode; public KeyboardId(String xmlName, int xmlId, Locale locale, int orientation, int width, - int mode, EditorInfo attribute, boolean hasSettingsKey, int f2KeyMode, + int mode, EditorInfo editorInfo, boolean hasSettingsKey, int f2KeyMode, boolean clobberSettingsKey, boolean shortcutKeyEnabled, boolean hasShortcutKey) { - final int inputType = (attribute != null) ? attribute.inputType : 0; - final int imeOptions = (attribute != null) ? attribute.imeOptions : 0; + final int inputType = (editorInfo != null) ? editorInfo.inputType : 0; + final int imeOptions = (editorInfo != null) ? editorInfo.imeOptions : 0; this.mLocale = locale; this.mOrientation = orientation; this.mWidth = width; @@ -89,7 +89,7 @@ public class KeyboardId { EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION); this.mXmlName = xmlName; - this.mAttribute = attribute; + this.mEditorInfo = editorInfo; this.mHashCode = Arrays.hashCode(new Object[] { locale, @@ -109,7 +109,7 @@ public class KeyboardId { } public KeyboardId cloneWithNewXml(String xmlName, int xmlId) { - return new KeyboardId(xmlName, xmlId, mLocale, mOrientation, mWidth, mMode, mAttribute, + return new KeyboardId(xmlName, xmlId, mLocale, mOrientation, mWidth, mMode, mEditorInfo, false, F2KEY_MODE_NONE, false, false, false); } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 049b316b1..dc5ec2d86 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -409,6 +409,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private boolean mHasPendingStartInput; private boolean mHasPendingFinishInputView; private boolean mHasPendingFinishInput; + private EditorInfo mAppliedEditorInfo; public void startOrientationChanging() { removeMessages(MSG_PENDING_IMS_CALLBACK); @@ -424,18 +425,18 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mHasPendingStartInput = false; } - private void executePendingImsCallback(LatinIME latinIme, EditorInfo attribute, + private void executePendingImsCallback(LatinIME latinIme, EditorInfo editorInfo, boolean restarting) { if (mHasPendingFinishInputView) latinIme.onFinishInputViewInternal(mHasPendingFinishInput); if (mHasPendingFinishInput) latinIme.onFinishInputInternal(); if (mHasPendingStartInput) - latinIme.onStartInputInternal(attribute, restarting); + latinIme.onStartInputInternal(editorInfo, restarting); resetPendingImsCallback(); } - public void onStartInput(EditorInfo attribute, boolean restarting) { + public void onStartInput(EditorInfo editorInfo, boolean restarting) { if (hasMessages(MSG_PENDING_IMS_CALLBACK)) { // Typically this is the second onStartInput after orientation changed. mHasPendingStartInput = true; @@ -446,27 +447,28 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mPendingSuccesiveImsCallback = true; } final LatinIME latinIme = getOuterInstance(); - executePendingImsCallback(latinIme, attribute, restarting); - latinIme.onStartInputInternal(attribute, restarting); + executePendingImsCallback(latinIme, editorInfo, restarting); + latinIme.onStartInputInternal(editorInfo, restarting); } } - public void onStartInputView(EditorInfo attribute, boolean restarting) { - if (hasMessages(MSG_PENDING_IMS_CALLBACK)) { - // Typically this is the second onStartInputView after orientation changed. - resetPendingImsCallback(); - } else { - if (mPendingSuccesiveImsCallback) { - // This is the first onStartInputView after orientation changed. - mPendingSuccesiveImsCallback = false; - resetPendingImsCallback(); - sendMessageDelayed(obtainMessage(MSG_PENDING_IMS_CALLBACK), - PENDING_IMS_CALLBACK_DURATION); - } - final LatinIME latinIme = getOuterInstance(); - executePendingImsCallback(latinIme, attribute, restarting); - latinIme.onStartInputViewInternal(attribute, restarting); - } + public void onStartInputView(EditorInfo editorInfo, boolean restarting) { + if (hasMessages(MSG_PENDING_IMS_CALLBACK) && editorInfo == mAppliedEditorInfo) { + // Typically this is the second onStartInputView after orientation changed. + resetPendingImsCallback(); + } else { + if (mPendingSuccesiveImsCallback) { + // This is the first onStartInputView after orientation changed. + mPendingSuccesiveImsCallback = false; + resetPendingImsCallback(); + sendMessageDelayed(obtainMessage(MSG_PENDING_IMS_CALLBACK), + PENDING_IMS_CALLBACK_DURATION); + } + final LatinIME latinIme = getOuterInstance(); + executePendingImsCallback(latinIme, editorInfo, restarting); + latinIme.onStartInputViewInternal(editorInfo, restarting); + mAppliedEditorInfo = editorInfo; + } } public void onFinishInputView(boolean finishingInput) { @@ -476,6 +478,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } else { final LatinIME latinIme = getOuterInstance(); latinIme.onFinishInputViewInternal(finishingInput); + mAppliedEditorInfo = null; } } @@ -703,13 +706,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } @Override - public void onStartInput(EditorInfo attribute, boolean restarting) { - mHandler.onStartInput(attribute, restarting); + public void onStartInput(EditorInfo editorInfo, boolean restarting) { + mHandler.onStartInput(editorInfo, restarting); } @Override - public void onStartInputView(EditorInfo attribute, boolean restarting) { - mHandler.onStartInputView(attribute, restarting); + public void onStartInputView(EditorInfo editorInfo, boolean restarting) { + mHandler.onStartInputView(editorInfo, restarting); } @Override @@ -722,19 +725,19 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mHandler.onFinishInput(); } - private void onStartInputInternal(EditorInfo attribute, boolean restarting) { - super.onStartInput(attribute, restarting); + private void onStartInputInternal(EditorInfo editorInfo, boolean restarting) { + super.onStartInput(editorInfo, restarting); } - private void onStartInputViewInternal(EditorInfo attribute, boolean restarting) { - super.onStartInputView(attribute, restarting); + private void onStartInputViewInternal(EditorInfo editorInfo, boolean restarting) { + super.onStartInputView(editorInfo, restarting); final KeyboardSwitcher switcher = mKeyboardSwitcher; LatinKeyboardView inputView = switcher.getKeyboardView(); if (DEBUG) { - Log.d(TAG, "onStartInputView: attribute:" + ((attribute == null) ? "none" + Log.d(TAG, "onStartInputView: editorInfo:" + ((editorInfo == null) ? "none" : String.format("inputType=0x%08x imeOptions=0x%08x", - attribute.inputType, attribute.imeOptions))); + editorInfo.inputType, editorInfo.imeOptions))); } // In landscape mode, this method gets called without the input view being created. if (inputView == null) { @@ -744,7 +747,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // Forward this event to the accessibility utilities, if enabled. final AccessibilityUtils accessUtils = AccessibilityUtils.getInstance(); if (accessUtils.isTouchExplorationEnabled()) { - accessUtils.onStartInputViewInternal(attribute, restarting); + accessUtils.onStartInputViewInternal(editorInfo, restarting); } mSubtypeSwitcher.updateParametersOnStartInputView(); @@ -755,14 +758,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // know now whether this is a password text field, because we need to know now whether we // want to enable the voice button. final VoiceProxy voiceIme = mVoiceProxy; - final int inputType = (attribute != null) ? attribute.inputType : 0; + final int inputType = (editorInfo != null) ? editorInfo.inputType : 0; voiceIme.resetVoiceStates(InputTypeCompatUtils.isPasswordInputType(inputType) || InputTypeCompatUtils.isVisiblePasswordInputType(inputType)); // The EditorInfo might have a flag that affects fullscreen mode. // Note: This call should be done by InputMethodService? updateFullscreenMode(); - initializeInputAttributes(attribute); + initializeInputAttributes(editorInfo); inputView.closing(); mEnteredText = null; @@ -778,12 +781,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (mSuggest != null && mSettingsValues.mAutoCorrectEnabled) { mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold); } - mVoiceProxy.loadSettings(attribute, mPrefs); + mVoiceProxy.loadSettings(editorInfo, mPrefs); // This will work only when the subtype is not supported. LanguageSwitcherProxy.loadSettings(); if (mSubtypeSwitcher.isKeyboardMode()) { - switcher.loadKeyboard(attribute, mSettingsValues); + switcher.loadKeyboard(editorInfo, mSettingsValues); } if (mSuggestionsView != null) @@ -803,10 +806,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); } - private void initializeInputAttributes(EditorInfo attribute) { - if (attribute == null) + private void initializeInputAttributes(EditorInfo editorInfo) { + if (editorInfo == null) return; - final int inputType = attribute.inputType; + final int inputType = editorInfo.inputType; if (inputType == InputType.TYPE_NULL) { // TODO: We should honor TYPE_NULL specification. Log.i(TAG, "InputType.TYPE_NULL is specified"); @@ -815,7 +818,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final int variation = inputType & InputType.TYPE_MASK_VARIATION; if (inputClass == 0) { Log.w(TAG, String.format("Unexpected input class: inputType=0x%08x imeOptions=0x%08x", - inputType, attribute.imeOptions)); + inputType, editorInfo.imeOptions)); } mInsertSpaceOnPickSuggestionManually = false; diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index e5a041f11..7d6efa584 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -301,9 +301,9 @@ public class Settings extends InputMethodSettingsActivity return mShowSettingsKey; } - public boolean isVoiceKeyEnabled(EditorInfo attribute) { + public boolean isVoiceKeyEnabled(EditorInfo editorInfo) { final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled(); - final int inputType = (attribute != null) ? attribute.inputType : 0; + final int inputType = (editorInfo != null) ? editorInfo.inputType : 0; return shortcutImeEnabled && mVoiceKeyEnabled && !InputTypeCompatUtils.isPasswordInputType(inputType); } -- cgit v1.2.3-83-g751a From c960695f38ae0564dff3a6897fd1843c8e74c604 Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Tue, 6 Dec 2011 14:06:57 -0800 Subject: Updated keyboard to use SPEAK_PASSWORD preference. Bug: 5678383 Change-Id: Ie9bdc92f4b2c9014159d672b71e4438f8fa34f55 --- .../accessibility/AccessibilityUtils.java | 16 ++++++++-- .../compat/SettingsSecureCompatUtils.java | 34 ++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 java/src/com/android/inputmethod/compat/SettingsSecureCompatUtils.java (limited to 'java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java') diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index 4a2542dec..46663327d 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 attribute) { if (attribute == 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); +} -- cgit v1.2.3-83-g751a From 2ac5988f84b5c38d313951a3d7faddebf5f25e04 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Thu, 15 Dec 2011 19:32:11 +0900 Subject: Cleanup unused variables and parameters Change-Id: Iad756a7a775c93f3344c6962e7b3456ef8339490 --- .../accessibility/AccessibilityUtils.java | 13 ++++++------- .../AccessibleInputMethodServiceProxy.java | 9 +++------ .../accessibility/AccessibleKeyboardViewProxy.java | 16 +++++++--------- .../accessibility/FlickGestureDetector.java | 1 - .../accessibility/KeyCodeDescriptionMapper.java | 7 +++---- .../inputmethod/keyboard/LatinKeyboardView.java | 8 +++----- .../src/com/android/inputmethod/latin/LatinIME.java | 6 +++--- .../android/inputmethod/latin/SettingsValues.java | 21 ++++++++++++--------- .../android/inputmethod/latin/SuggestionsView.java | 7 ------- .../inputmethod/latin/UserUnigramDictionary.java | 6 +++--- 10 files changed, 40 insertions(+), 54 deletions(-) (limited to 'java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java') diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index 1836f27b3..9caed00c9 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -17,7 +17,6 @@ package com.android.inputmethod.accessibility; import android.content.Context; -import android.content.SharedPreferences; import android.inputmethodservice.InputMethodService; import android.media.AudioManager; import android.os.SystemClock; @@ -55,15 +54,15 @@ public class AccessibilityUtils { */ private static final boolean ENABLE_ACCESSIBILITY = true; - public static void init(InputMethodService inputMethod, SharedPreferences prefs) { + public static void init(InputMethodService inputMethod) { if (!ENABLE_ACCESSIBILITY) return; // These only need to be initialized if the kill switch is off. - sInstance.initInternal(inputMethod, prefs); - KeyCodeDescriptionMapper.init(inputMethod, prefs); - AccessibleInputMethodServiceProxy.init(inputMethod, prefs); - AccessibleKeyboardViewProxy.init(inputMethod, prefs); + sInstance.initInternal(inputMethod); + KeyCodeDescriptionMapper.init(); + AccessibleInputMethodServiceProxy.init(inputMethod); + AccessibleKeyboardViewProxy.init(inputMethod); } public static AccessibilityUtils getInstance() { @@ -74,7 +73,7 @@ public class AccessibilityUtils { // This class is not publicly instantiable. } - private void initInternal(Context context, SharedPreferences prefs) { + private void initInternal(Context context) { mContext = context; mAccessibilityManager = (AccessibilityManager) context .getSystemService(Context.ACCESSIBILITY_SERVICE); diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java index 4ab9cb898..d834dd10b 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java @@ -17,7 +17,6 @@ package com.android.inputmethod.accessibility; import android.content.Context; -import android.content.SharedPreferences; import android.inputmethodservice.InputMethodService; import android.media.AudioManager; import android.os.Looper; @@ -82,8 +81,8 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi } } - public static void init(InputMethodService inputMethod, SharedPreferences prefs) { - sInstance.initInternal(inputMethod, prefs); + public static void init(InputMethodService inputMethod) { + sInstance.initInternal(inputMethod); } public static AccessibleInputMethodServiceProxy getInstance() { @@ -94,7 +93,7 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi // Not publicly instantiable. } - private void initInternal(InputMethodService inputMethod, SharedPreferences prefs) { + private void initInternal(InputMethodService inputMethod) { mInputMethod = inputMethod; mVibrator = (Vibrator) inputMethod.getSystemService(Context.VIBRATOR_SERVICE); mAudioManager = (AudioManager) inputMethod.getSystemService(Context.AUDIO_SERVICE); @@ -125,8 +124,6 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi */ @Override public void onFlickGesture(int direction) { - final int keyEventCode; - switch (direction) { case FlickGestureDetector.FLICK_LEFT: sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT); diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java index 4cb2f20b9..9141daaee 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java @@ -17,7 +17,6 @@ package com.android.inputmethod.accessibility; import android.content.Context; -import android.content.SharedPreferences; import android.graphics.Color; import android.graphics.Paint; import android.inputmethodservice.InputMethodService; @@ -43,8 +42,8 @@ public class AccessibleKeyboardViewProxy { private Key mLastHoverKey = null; - public static void init(InputMethodService inputMethod, SharedPreferences prefs) { - sInstance.initInternal(inputMethod, prefs); + public static void init(InputMethodService inputMethod) { + sInstance.initInternal(inputMethod); sInstance.mListener = AccessibleInputMethodServiceProxy.getInstance(); } @@ -60,7 +59,7 @@ public class AccessibleKeyboardViewProxy { // Not publicly instantiable. } - private void initInternal(InputMethodService inputMethod, SharedPreferences prefs) { + private void initInternal(InputMethodService inputMethod) { final Paint paint = new Paint(); paint.setTextAlign(Paint.Align.LEFT); paint.setTextSize(14.0f); @@ -71,8 +70,7 @@ public class AccessibleKeyboardViewProxy { mGestureDetector = new KeyboardFlickGestureDetector(inputMethod); } - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event, - PointerTracker tracker) { + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { if (mView == null) { Log.e(TAG, "No keyboard view set!"); return false; @@ -132,9 +130,9 @@ public class AccessibleKeyboardViewProxy { final Key key = tracker.getKeyOn(x, y); if (key != mLastHoverKey) { - fireKeyHoverEvent(tracker, mLastHoverKey, false); + fireKeyHoverEvent(mLastHoverKey, false); mLastHoverKey = key; - fireKeyHoverEvent(tracker, mLastHoverKey, true); + fireKeyHoverEvent(mLastHoverKey, true); } return true; @@ -143,7 +141,7 @@ public class AccessibleKeyboardViewProxy { return false; } - private void fireKeyHoverEvent(PointerTracker tracker, Key key, boolean entering) { + private void fireKeyHoverEvent(Key key, boolean entering) { if (mListener == null) { Log.e(TAG, "No accessible keyboard action listener set!"); return; diff --git a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java index 9d99e3131..db12f76ad 100644 --- a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java +++ b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java @@ -126,7 +126,6 @@ public abstract class FlickGestureDetector { } final float distanceSquare = calculateDistanceSquare(mCachedHoverEnter, event); - final long timeout = event.getEventTime() - mCachedHoverEnter.getEventTime(); switch (event.getAction()) { case MotionEventCompatUtils.ACTION_HOVER_MOVE: diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java index e01262c20..3d5ab05c3 100644 --- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java +++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java @@ -17,7 +17,6 @@ package com.android.inputmethod.accessibility; import android.content.Context; -import android.content.SharedPreferences; import android.text.TextUtils; import com.android.inputmethod.keyboard.Key; @@ -45,8 +44,8 @@ public class KeyCodeDescriptionMapper { // Map of shift-locked key codes to spoken description resource IDs private final HashMap mShiftLockedKeyCodeMap; - public static void init(Context context, SharedPreferences prefs) { - sInstance.initInternal(context, prefs); + public static void init() { + sInstance.initInternal(); } public static KeyCodeDescriptionMapper getInstance() { @@ -60,7 +59,7 @@ public class KeyCodeDescriptionMapper { mShiftLockedKeyCodeMap = new HashMap(); } - private void initInternal(Context context, SharedPreferences prefs) { + private void initInternal() { // Manual label substitutions for key labels with no string resource mKeyLabelMap.put(":-)", R.string.spoken_description_smiley); diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index e56f2ea84..7f2c6c501 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -206,7 +206,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke // Detected a double tap on shift key. If we are in the ignoring double tap // mode, it means we have already turned off caps lock in // {@link KeyboardSwitcher#onReleaseShift} . - onDoubleTapShiftKey(tracker, mKeyTimerHandler.isIgnoringDoubleTap()); + onDoubleTapShiftKey(mKeyTimerHandler.isIgnoringDoubleTap()); return true; } // Otherwise these events should not be handled as double tap. @@ -342,8 +342,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke return onLongPress(parentKey, tracker); } - private void onDoubleTapShiftKey(@SuppressWarnings("unused") PointerTracker tracker, - final boolean ignore) { + private void onDoubleTapShiftKey(final boolean ignore) { // When shift key is double tapped, the first tap is correctly processed as usual tap. And // the second tap is treated as this double tap event, so that we need not mark tracker // calling setAlreadyProcessed() nor remove the tracker from mPointerQueue. @@ -633,9 +632,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke @Override public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { - final PointerTracker tracker = getPointerTracker(0); return AccessibleKeyboardViewProxy.getInstance().dispatchPopulateAccessibilityEvent( - event, tracker) || super.dispatchPopulateAccessibilityEvent(event); + event) || super.dispatchPopulateAccessibilityEvent(event); } return super.dispatchPopulateAccessibilityEvent(event); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 98fea1b5b..943361c73 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -489,7 +489,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar InputMethodManagerCompatWrapper.init(this); SubtypeSwitcher.init(this); KeyboardSwitcher.init(this, prefs); - AccessibilityUtils.init(this, prefs); + AccessibilityUtils.init(this); super.onCreate(); @@ -758,7 +758,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar loadSettings(); updateCorrectionMode(); - updateSuggestionVisibility(mPrefs, mResources); + updateSuggestionVisibility(mResources); if (mSuggest != null && mSettingsValues.mAutoCorrectEnabled) { mSuggest.setAutoCorrectionThreshold(mSettingsValues.mAutoCorrectionThreshold); @@ -2415,7 +2415,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar ? Suggest.CORRECTION_FULL_BIGRAM : mCorrectionMode; } - private void updateSuggestionVisibility(final SharedPreferences prefs, final Resources res) { + private void updateSuggestionVisibility(final Resources res) { final String suggestionVisiblityStr = mSettingsValues.mShowSuggestionsSetting; for (int visibility : SUGGESTION_VISIBILITY_VALUE_ARRAY) { if (suggestionVisiblityStr.equals(res.getString(visibility))) { diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index 0ad1c1529..651d90ca4 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -52,7 +52,9 @@ public class SettingsValues { private final String mVoiceMode; private final String mAutoCorrectionThresholdRawValue; public final String mShowSuggestionsSetting; + @SuppressWarnings("unused") // TODO: Use this private final boolean mUsabilityStudyMode; + @SuppressWarnings("unused") // TODO: Use this private final String mKeyPreviewPopupDismissDelayRawValue; public final boolean mUseContactsDict; // Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary @@ -60,7 +62,9 @@ public class SettingsValues { // Prediction: use bigrams to predict the next word when there is no input for it yet public final boolean mBigramPredictionEnabled; public final boolean mEnableSuggestionSpanInsertion; + @SuppressWarnings("unused") // TODO: Use this private final int mVibrationDurationSettingsRawValue; + @SuppressWarnings("unused") // TODO: Use this private final float mKeypressSoundVolumeRawValue; // Deduced settings @@ -111,12 +115,12 @@ public class SettingsValues { res.getString(R.string.auto_correction_threshold_mode_index_modest)); mShowSuggestionsSetting = prefs.getString(Settings.PREF_SHOW_SUGGESTIONS_SETTING, res.getString(R.string.prefs_suggestion_visibility_default_value)); - mUsabilityStudyMode = getUsabilityStudyMode(prefs, res); + mUsabilityStudyMode = getUsabilityStudyMode(prefs); mKeyPreviewPopupDismissDelayRawValue = prefs.getString( Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, Integer.toString(res.getInteger(R.integer.config_delay_after_preview))); mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true); - mAutoCorrectEnabled = isAutoCorrectEnabled(prefs, res, mAutoCorrectionThresholdRawValue); + mAutoCorrectEnabled = isAutoCorrectEnabled(res, mAutoCorrectionThresholdRawValue); mBigramSuggestionEnabled = mAutoCorrectEnabled && isBigramSuggestionEnabled(prefs, res, mAutoCorrectEnabled); mBigramPredictionEnabled = mBigramSuggestionEnabled @@ -131,7 +135,7 @@ public class SettingsValues { mKeypressVibrationDuration = getCurrentVibrationDuration(prefs, res); mFxVolume = getCurrentKeypressSoundVolume(prefs, res); mKeyPreviewPopupDismissDelay = getKeyPreviewPopupDismissDelay(prefs, res); - mAutoCorrectionThreshold = getAutoCorrectionThreshold(prefs, res, + mAutoCorrectionThreshold = getAutoCorrectionThreshold(res, mAutoCorrectionThresholdRawValue); mVoiceKeyEnabled = mVoiceMode != null && !mVoiceMode.equals(voiceModeOff); mVoiceKeyOnMain = mVoiceMode != null && mVoiceMode.equals(voiceModeMain); @@ -202,8 +206,8 @@ public class SettingsValues { return mMagicSpaceSwappers.contains(String.valueOf((char)code)); } - private static boolean isAutoCorrectEnabled(final SharedPreferences sp, - final Resources resources, final String currentAutoCorrectionSetting) { + private static boolean isAutoCorrectEnabled(final Resources resources, + final String currentAutoCorrectionSetting) { final String autoCorrectionOff = resources.getString( R.string.auto_correction_threshold_mode_index_off); return !currentAutoCorrectionSetting.equals(autoCorrectionOff); @@ -244,8 +248,8 @@ public class SettingsValues { R.bool.config_default_bigram_prediction)); } - private static double getAutoCorrectionThreshold(final SharedPreferences sp, - final Resources resources, final String currentAutoCorrectionSetting) { + private static double getAutoCorrectionThreshold(final Resources resources, + final String currentAutoCorrectionSetting) { final String[] autoCorrectionThresholdValues = resources.getStringArray( R.array.auto_correction_threshold_values); // When autoCorrectionThreshold is greater than 1.0, it's like auto correction is off. @@ -321,8 +325,7 @@ public class SettingsValues { } // Likewise - public static boolean getUsabilityStudyMode(final SharedPreferences prefs, - final Resources res) { + public static boolean getUsabilityStudyMode(final SharedPreferences prefs) { // TODO: use mUsabilityStudyMode instead of reading it again here return prefs.getBoolean(Settings.PREF_USABILITY_STUDY_MODE, true); } diff --git a/java/src/com/android/inputmethod/latin/SuggestionsView.java b/java/src/com/android/inputmethod/latin/SuggestionsView.java index 10f5ec9db..883bb57f0 100644 --- a/java/src/com/android/inputmethod/latin/SuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/SuggestionsView.java @@ -100,8 +100,6 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, private static class UiHandler extends StaticInnerHandlerWrapper { private static final int MSG_HIDE_PREVIEW = 0; - private static final long DELAY_HIDE_PREVIEW = 1300; - public UiHandler(SuggestionsView outerInstance) { super(outerInstance); } @@ -116,11 +114,6 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, } } - public void postHidePreview() { - cancelHidePreview(); - sendMessageDelayed(obtainMessage(MSG_HIDE_PREVIEW), DELAY_HIDE_PREVIEW); - } - public void cancelHidePreview() { removeMessages(MSG_HIDE_PREVIEW); } diff --git a/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java b/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java index 6af20c754..a7f57ae46 100644 --- a/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java @@ -172,7 +172,7 @@ public class UserUnigramDictionary extends ExpandableDictionary { // Nothing pending? Return if (mPendingWrites.isEmpty()) return; // Create a background thread to write the pending entries - new UpdateDbTask(getContext(), sOpenHelper, mPendingWrites, mLocale).execute(); + new UpdateDbTask(sOpenHelper, mPendingWrites, mLocale).execute(); // Create a new map for writing new entries into while the old one is written to db mPendingWrites = new HashMap(); } @@ -227,8 +227,8 @@ public class UserUnigramDictionary extends ExpandableDictionary { private final DatabaseHelper mDbHelper; private final String mLocale; - public UpdateDbTask(@SuppressWarnings("unused") Context context, DatabaseHelper openHelper, - HashMap pendingWrites, String locale) { + public UpdateDbTask(DatabaseHelper openHelper, HashMap pendingWrites, + String locale) { mMap = pendingWrites; mLocale = locale; mDbHelper = openHelper; -- cgit v1.2.3-83-g751a From 9a81ce92c381007affe6bb2310bf94c9856eaae1 Mon Sep 17 00:00:00 2001 From: alanv Date: Tue, 28 Feb 2012 10:01:40 -0800 Subject: Added virtual view hierarchy for keyboard accessibility. Bug: 5829051 Change-Id: Ied1b6267eec616bd3b9337f6e761b0c740aa0eb2 --- java/Android.mk | 1 + .../accessibility/AccessibilityEntityProvider.java | 377 +++++++++++++++++++++ .../accessibility/AccessibilityUtils.java | 11 +- .../accessibility/AccessibleKeyboardViewProxy.java | 164 ++++++--- .../accessibility/FlickGestureDetector.java | 5 +- .../accessibility/KeyCodeDescriptionMapper.java | 18 +- .../compat/AccessibilityEventCompatUtils.java | 22 -- .../compat/AccessibilityManagerCompatUtils.java | 34 ++ .../compat/AccessibilityManagerCompatWrapper.java | 36 -- .../inputmethod/compat/MotionEventCompatUtils.java | 2 +- .../inputmethod/compat/ViewParentCompatUtils.java | 51 +++ .../inputmethod/keyboard/KeyboardSwitcher.java | 2 +- .../inputmethod/keyboard/LatinKeyboardView.java | 11 - 13 files changed, 590 insertions(+), 144 deletions(-) create mode 100644 java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java delete mode 100644 java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java create mode 100644 java/src/com/android/inputmethod/compat/AccessibilityManagerCompatUtils.java delete mode 100644 java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java create mode 100644 java/src/com/android/inputmethod/compat/ViewParentCompatUtils.java (limited to 'java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java') diff --git a/java/Android.mk b/java/Android.mk index fd71d82e0..52cc18b26 100644 --- a/java/Android.mk +++ b/java/Android.mk @@ -30,6 +30,7 @@ LOCAL_REQUIRED_MODULES := libjni_latinime LOCAL_STATIC_JAVA_LIBRARIES := android-common LOCAL_STATIC_JAVA_LIBRARIES += inputmethod-common +LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4 # Do not compress dictionary files to mmap dict data runtime LOCAL_AAPT_FLAGS := -0 .dict diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java new file mode 100644 index 000000000..dc7c12ba6 --- /dev/null +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java @@ -0,0 +1,377 @@ +/* + * Copyright (C) 2012 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.accessibility; + +import android.graphics.Rect; +import android.inputmethodservice.InputMethodService; +import android.support.v4.view.ViewCompat; +import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; +import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat; +import android.support.v4.view.accessibility.AccessibilityRecordCompat; +import android.util.Log; +import android.util.SparseArray; +import android.view.View; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.view.accessibility.AccessibilityEvent; +import android.view.inputmethod.EditorInfo; + +import com.android.inputmethod.keyboard.Key; +import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.keyboard.KeyboardView; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +/** + * Exposes a virtual view sub-tree for {@link KeyboardView} and generates + * {@link AccessibilityEvent}s for individual {@link Key}s. + *

+ * A virtual sub-tree is composed of imaginary {@link View}s that are reported + * as a part of the view hierarchy for accessibility purposes. This enables + * custom views that draw complex content to report them selves as a tree of + * virtual views, thus conveying their logical structure. + *

+ */ +public class AccessibilityEntityProvider extends AccessibilityNodeProviderCompat { + private static final String TAG = AccessibilityEntityProvider.class.getSimpleName(); + + private final KeyboardView mKeyboardView; + private final InputMethodService mInputMethodService; + private final KeyCodeDescriptionMapper mKeyCodeDescriptionMapper; + private final AccessibilityUtils mAccessibilityUtils; + + /** A map of integer IDs to {@link Key}s. */ + private final SparseArray mVirtualViewIdToKey = new SparseArray(); + + /** Temporary rect used to calculate in-screen bounds. */ + private final Rect mTempBoundsInScreen = new Rect(); + + /** The parent view's cached on-screen location. */ + private final int[] mParentLocation = new int[2]; + + public AccessibilityEntityProvider(KeyboardView keyboardView, InputMethodService inputMethod) { + mKeyboardView = keyboardView; + mInputMethodService = inputMethod; + + mKeyCodeDescriptionMapper = KeyCodeDescriptionMapper.getInstance(); + mAccessibilityUtils = AccessibilityUtils.getInstance(); + + assignVirtualViewIds(); + updateParentLocation(); + + // Ensure that the on-screen bounds are cleared when the layout changes. + mKeyboardView.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener); + } + + /** + * Creates and populates an {@link AccessibilityEvent} for the specified key + * and event type. + * + * @param key A key on the host keyboard view. + * @param eventType The event type to create. + * @return A populated {@link AccessibilityEvent} for the key. + * @see AccessibilityEvent + */ + public AccessibilityEvent createAccessibilityEvent(Key key, int eventType) { + final int virtualViewId = generateVirtualViewIdForKey(key); + final String keyDescription = getKeyDescription(key); + + final AccessibilityEvent event = AccessibilityEvent.obtain(eventType); + event.setPackageName(mKeyboardView.getContext().getPackageName()); + event.setClassName(key.getClass().getName()); + event.getText().add(keyDescription); + + final AccessibilityRecordCompat record = new AccessibilityRecordCompat(event); + record.setSource(mKeyboardView, virtualViewId); + + return event; + } + + /** + * Returns an {@link AccessibilityNodeInfoCompat} representing a virtual + * view, i.e. a descendant of the host View, with the given virtualViewId or + * the host View itself if virtualViewId equals to {@link View#NO_ID}. + *

+ * A virtual descendant is an imaginary View that is reported as a part of + * the view hierarchy for accessibility purposes. This enables custom views + * that draw complex content to report them selves as a tree of virtual + * views, thus conveying their logical structure. + *

+ *

+ * The implementer is responsible for obtaining an accessibility node info + * from the pool of reusable instances and setting the desired properties of + * the node info before returning it. + *

+ * + * @param virtualViewId A client defined virtual view id. + * @return A populated {@link AccessibilityNodeInfoCompat} for a virtual + * descendant or the host View. + * @see AccessibilityNodeInfoCompat + */ + @Override + public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) { + AccessibilityNodeInfoCompat info = null; + + if (virtualViewId == View.NO_ID) { + // We are requested to create an AccessibilityNodeInfo describing + // this View, i.e. the root of the virtual sub-tree. + info = AccessibilityNodeInfoCompat.obtain(mKeyboardView); + ViewCompat.onInitializeAccessibilityNodeInfo(mKeyboardView, info); + + // Add the virtual children of the root View. + // TODO(alanv): Need to assign a unique ID to each key. + final Keyboard keyboard = mKeyboardView.getKeyboard(); + final Set keys = keyboard.mKeys; + for (Key key : keys) { + final int childVirtualViewId = generateVirtualViewIdForKey(key); + info.addChild(mKeyboardView, childVirtualViewId); + } + } else { + // Find the view that corresponds to the given id. + final Key key = mVirtualViewIdToKey.get(virtualViewId); + if (key == null) { + Log.e(TAG, "Invalid virtual view ID: " + virtualViewId); + return null; + } + + final String keyDescription = getKeyDescription(key); + final Rect boundsInParent = key.mHitBox; + + // Calculate the key's in-screen bounds. + mTempBoundsInScreen.set(boundsInParent); + mTempBoundsInScreen.offset(mParentLocation[0], mParentLocation[1]); + + final Rect boundsInScreen = mTempBoundsInScreen; + + // Obtain and initialize an AccessibilityNodeInfo with + // information about the virtual view. + info = AccessibilityNodeInfoCompat.obtain(); + info.addAction(AccessibilityNodeInfoCompat.ACTION_SELECT); + info.addAction(AccessibilityNodeInfoCompat.ACTION_CLEAR_SELECTION); + info.setPackageName(mKeyboardView.getContext().getPackageName()); + info.setClassName(key.getClass().getName()); + info.setBoundsInParent(boundsInParent); + info.setBoundsInScreen(boundsInScreen); + info.setParent(mKeyboardView); + info.setSource(mKeyboardView, virtualViewId); + info.setBoundsInScreen(boundsInScreen); + info.setText(keyDescription); + } + + return info; + } + + /** + * Performs an accessibility action on a virtual view, i.e. a descendant of + * the host View, with the given virtualViewId or the host View itself if + * virtualViewId equals to {@link View#NO_ID}. + * + * @param action The action to perform. + * @param virtualViewId A client defined virtual view id. + * @return True if the action was performed. + * @see #createAccessibilityNodeInfo(int) + * @see AccessibilityNodeInfoCompat + */ + @Override + public boolean performAccessibilityAction(int action, int virtualViewId) { + if (virtualViewId == View.NO_ID) { + // Perform the action on the host View. + switch (action) { + case AccessibilityNodeInfoCompat.ACTION_SELECT: + if (!mKeyboardView.isSelected()) { + mKeyboardView.setSelected(true); + return mKeyboardView.isSelected(); + } + break; + case AccessibilityNodeInfoCompat.ACTION_CLEAR_SELECTION: + if (mKeyboardView.isSelected()) { + mKeyboardView.setSelected(false); + return !mKeyboardView.isSelected(); + } + break; + } + } else { + // Find the view that corresponds to the given id. + final Key child = mVirtualViewIdToKey.get(virtualViewId); + if (child == null) + return false; + + // Perform the action on a virtual view. + switch (action) { + case AccessibilityNodeInfoCompat.ACTION_SELECT: + // TODO: Provide some focus indicator. + return true; + case AccessibilityNodeInfoCompat.ACTION_CLEAR_SELECTION: + // TODO: Provide some clear focus indicator. + return true; + } + } + + return false; + } + + /** + * Finds {@link AccessibilityNodeInfoCompat}s by text. The match is case + * insensitive containment. The search is relative to the virtual view, i.e. + * a descendant of the host View, with the given virtualViewId or the host + * View itself virtualViewId equals to {@link View#NO_ID}. + * + * @param virtualViewId A client defined virtual view id which defined the + * root of the tree in which to perform the search. + * @param text The searched text. + * @return A list of node info. + * @see #createAccessibilityNodeInfo(int) + * @see AccessibilityNodeInfoCompat + */ + @Override + public List findAccessibilityNodeInfosByText( + String text, int virtualViewId) { + final String searchedLowerCase = text.toLowerCase(); + final Keyboard keyboard = mKeyboardView.getKeyboard(); + + List results = null; + + if (virtualViewId == View.NO_ID) { + for (Key key : keyboard.mKeys) { + results = findByTextAndPopulate(searchedLowerCase, key, results); + } + } else { + final Key key = mVirtualViewIdToKey.get(virtualViewId); + + results = findByTextAndPopulate(searchedLowerCase, key, results); + } + + if (results == null) { + return Collections.emptyList(); + } + + return results; + } + + /** + * Helper method for {@link #findAccessibilityNodeInfosByText(String, int)}. + * Takes a current set of results and matches a specified key against a + * lower-case search string. Returns an updated list of results. + * + * @param searchedLowerCase The lower-case search string. + * @param key The key to compare against. + * @param results The current list of results, or {@code null} if no results + * found. + * @return An updated list of results, or {@code null} if no results found. + */ + private List findByTextAndPopulate(String searchedLowerCase, + Key key, List results) { + if (!keyContainsText(key, searchedLowerCase)) { + return results; + } + + final int childVirtualViewId = generateVirtualViewIdForKey(key); + final AccessibilityNodeInfoCompat nodeInfo = createAccessibilityNodeInfo( + childVirtualViewId); + + if (results == null) { + results = new LinkedList(); + } + + results.add(nodeInfo); + + return results; + } + + /** + * Returns whether a key's current description contains the lower-case + * search text. + * + * @param key The key to compare against. + * @param textLowerCase The lower-case search string. + * @return {@code true} if the key contains the search text. + */ + private boolean keyContainsText(Key key, String textLowerCase) { + if (key == null) { + return false; + } + + final String description = getKeyDescription(key); + + if (description == null) { + return false; + } + + return description.toLowerCase().contains(textLowerCase); + } + + /** + * Returns the context-specific description for a {@link Key}. + * + * @param key The key to describe. + * @return The context-specific description of the key. + */ + private String getKeyDescription(Key key) { + final EditorInfo editorInfo = mInputMethodService.getCurrentInputEditorInfo(); + final boolean shouldObscure = mAccessibilityUtils.shouldObscureInput(editorInfo); + final String keyDescription = mKeyCodeDescriptionMapper.getDescriptionForKey( + mKeyboardView.getContext(), mKeyboardView.getKeyboard(), key, shouldObscure); + + return keyDescription; + } + + /** + * Assigns virtual view IDs to keyboard keys and populates the related maps. + */ + private void assignVirtualViewIds() { + final Keyboard keyboard = mKeyboardView.getKeyboard(); + if (keyboard == null) { + return; + } + + mVirtualViewIdToKey.clear(); + + final Set keySet = keyboard.mKeys; + for (Key key : keySet) { + final int virtualViewId = generateVirtualViewIdForKey(key); + mVirtualViewIdToKey.put(virtualViewId, key); + } + } + + /** + * Updates the parent's on-screen location. + */ + private void updateParentLocation() { + mKeyboardView.getLocationOnScreen(mParentLocation); + } + + /** + * Generates a virtual view identifier for the specified key. + * + * @param key The key to identify. + * @return A virtual view identifier. + */ + private static int generateVirtualViewIdForKey(Key key) { + // The key code is unique within an instance of a Keyboard. + return key.mCode; + } + + private final OnGlobalLayoutListener mGlobalLayoutListener = new OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + assignVirtualViewIds(); + updateParentLocation(); + } + }; +} diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index 9caed00c9..41da2aa4c 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -21,13 +21,14 @@ import android.inputmethodservice.InputMethodService; import android.media.AudioManager; import android.os.SystemClock; import android.provider.Settings; +import android.support.v4.view.MotionEventCompat; import android.util.Log; import android.view.MotionEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.compat.AccessibilityManagerCompatWrapper; +import com.android.inputmethod.compat.AccessibilityManagerCompatUtils; import com.android.inputmethod.compat.AudioManagerCompatWrapper; import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.compat.MotionEventCompatUtils; @@ -44,7 +45,6 @@ public class AccessibilityUtils { private Context mContext; private AccessibilityManager mAccessibilityManager; - private AccessibilityManagerCompatWrapper mCompatManager; private AudioManagerCompatWrapper mAudioManager; /* @@ -77,7 +77,6 @@ public class AccessibilityUtils { mContext = context; mAccessibilityManager = (AccessibilityManager) context .getSystemService(Context.ACCESSIBILITY_SERVICE); - mCompatManager = new AccessibilityManagerCompatWrapper(mAccessibilityManager); final AudioManager audioManager = (AudioManager) context .getSystemService(Context.AUDIO_SERVICE); @@ -94,7 +93,7 @@ public class AccessibilityUtils { public boolean isTouchExplorationEnabled() { return ENABLE_ACCESSIBILITY && mAccessibilityManager.isEnabled() - && mCompatManager.isTouchExplorationEnabled(); + && AccessibilityManagerCompatUtils.isTouchExplorationEnabled(mAccessibilityManager); } /** @@ -110,13 +109,13 @@ public class AccessibilityUtils { return action == MotionEventCompatUtils.ACTION_HOVER_ENTER || action == MotionEventCompatUtils.ACTION_HOVER_EXIT - || action == MotionEventCompatUtils.ACTION_HOVER_MOVE; + || action == MotionEventCompat.ACTION_HOVER_MOVE; } /** * 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) { diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java index 2294a18a0..2401d93c6 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java @@ -20,13 +20,16 @@ import android.content.Context; import android.graphics.Color; import android.graphics.Paint; import android.inputmethodservice.InputMethodService; -import android.util.Log; +import android.support.v4.view.AccessibilityDelegateCompat; +import android.support.v4.view.MotionEventCompat; +import android.support.v4.view.ViewCompat; +import android.support.v4.view.accessibility.AccessibilityEventCompat; import android.view.MotionEvent; +import android.view.View; import android.view.accessibility.AccessibilityEvent; -import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.compat.AccessibilityEventCompatUtils; import com.android.inputmethod.compat.MotionEventCompatUtils; +import com.android.inputmethod.compat.ViewParentCompatUtils; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardId; @@ -34,14 +37,14 @@ import com.android.inputmethod.keyboard.LatinKeyboardView; import com.android.inputmethod.keyboard.PointerTracker; import com.android.inputmethod.latin.R; -public class AccessibleKeyboardViewProxy { - private static final String TAG = AccessibleKeyboardViewProxy.class.getSimpleName(); +public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat { private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy(); private InputMethodService mInputMethod; private FlickGestureDetector mGestureDetector; private LatinKeyboardView mView; private AccessibleKeyboardActionListener mListener; + private AccessibilityEntityProvider mAccessibilityNodeProvider; private Key mLastHoverKey = null; @@ -54,10 +57,6 @@ public class AccessibleKeyboardViewProxy { return sInstance; } - public static void setView(LatinKeyboardView view) { - sInstance.mView = view; - } - private AccessibleKeyboardViewProxy() { // Not publicly instantiable. } @@ -73,34 +72,39 @@ public class AccessibleKeyboardViewProxy { mGestureDetector = new KeyboardFlickGestureDetector(inputMethod); } - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - if (mView == null) { - Log.e(TAG, "No keyboard view set!"); - return false; + /** + * Sets the view wrapped by this proxy. + * + * @param view The view to wrap. + */ + public void setView(LatinKeyboardView view) { + if (view == null) { + // Ignore null views. + return; } - switch (event.getEventType()) { - case AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_ENTER: - final Key key = mLastHoverKey; + mView = view; - if (key == null) - break; - - final EditorInfo info = mInputMethod.getCurrentInputEditorInfo(); - final boolean shouldObscure = AccessibilityUtils.getInstance().shouldObscureInput(info); - final CharSequence description = KeyCodeDescriptionMapper.getInstance() - .getDescriptionForKey(mView.getContext(), mView.getKeyboard(), key, - shouldObscure); - - if (description == null) - return false; - - event.getText().add(description); + // Ensure that the view has an accessibility delegate. + ViewCompat.setAccessibilityDelegate(view, this); + } - break; + /** + * Proxy method for View.getAccessibilityNodeProvider(). This method is + * called in SDK version 15 and higher to obtain the virtual node hierarchy + * provider. + * + * @return The accessibility node provider for the current keyboard. + */ + @Override + public AccessibilityEntityProvider getAccessibilityNodeProvider(View host) { + // Instantiate the provide only when requested. Since the system + // will call this method multiple times it is a good practice to + // cache the provider instance. + if (mAccessibilityNodeProvider == null) { + mAccessibilityNodeProvider = new AccessibilityEntityProvider(mView, mInputMethod); } - - return true; + return mAccessibilityNodeProvider; } /** @@ -123,46 +127,94 @@ public class AccessibleKeyboardViewProxy { * @param event The touch exploration hover event. * @return {@code true} if the event was handled */ - /*package*/ boolean onHoverEventInternal(MotionEvent event, PointerTracker tracker) { + /* package */boolean onHoverEventInternal(MotionEvent event, PointerTracker tracker) { final int x = (int) event.getX(); final int y = (int) event.getY(); + final Key key = tracker.getKeyOn(x, y); + final Key previousKey = mLastHoverKey; + + mLastHoverKey = key; switch (event.getAction()) { case MotionEventCompatUtils.ACTION_HOVER_ENTER: - case MotionEventCompatUtils.ACTION_HOVER_MOVE: - final Key key = tracker.getKeyOn(x, y); - - if (key != mLastHoverKey) { - fireKeyHoverEvent(mLastHoverKey, false); - mLastHoverKey = key; - fireKeyHoverEvent(mLastHoverKey, true); + case MotionEventCompatUtils.ACTION_HOVER_EXIT: + return onHoverKey(key, event); + case MotionEventCompat.ACTION_HOVER_MOVE: + if (key != previousKey) { + return onTransitionKey(key, previousKey, event); + } else { + return onHoverKey(key, event); } - - return true; } return false; } - private void fireKeyHoverEvent(Key key, boolean entering) { - if (mListener == null) { - Log.e(TAG, "No accessible keyboard action listener set!"); - return; + /** + * Simulates a transition between two {@link Key}s by sending a HOVER_EXIT + * on the previous key, a HOVER_ENTER on the current key, and a HOVER_MOVE + * on the current key. + * + * @param currentKey The currently hovered key. + * @param previousKey The previously hovered key. + * @param event The event that triggered the transition. + * @return {@code true} if the event was handled. + */ + private boolean onTransitionKey(Key currentKey, Key previousKey, MotionEvent event) { + final int savedAction = event.getAction(); + + event.setAction(MotionEventCompatUtils.ACTION_HOVER_EXIT); + onHoverKey(previousKey, event); + + event.setAction(MotionEventCompatUtils.ACTION_HOVER_ENTER); + onHoverKey(currentKey, event); + + event.setAction(MotionEventCompat.ACTION_HOVER_MOVE); + final boolean handled = onHoverKey(currentKey, event); + + event.setAction(savedAction); + + return handled; + } + + /** + * Handles a hover event on a key. If {@link Key} extended View, this would + * be analogous to calling View.onHoverEvent(MotionEvent). + * + * @param key The currently hovered key. + * @param event The hover event. + * @return {@code true} if the event was handled. + */ + private boolean onHoverKey(Key key, MotionEvent event) { + // Null keys can't receive events. + if (key == null) { + return false; } - if (mView == null) { - Log.e(TAG, "No keyboard view set!"); - return; + switch (event.getAction()) { + case MotionEventCompatUtils.ACTION_HOVER_ENTER: + sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER); + break; + case MotionEventCompatUtils.ACTION_HOVER_EXIT: + sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT); + break; } - if (key == null) - return; + return true; + } - if (entering) { - mView.sendAccessibilityEvent(AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_ENTER); - } else { - mView.sendAccessibilityEvent(AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_EXIT); - } + /** + * Populates and sends an {@link AccessibilityEvent} for the specified key. + * + * @param key The key to send an event for. + * @param eventType The type of event to send. + */ + private void sendAccessibilityEventForKey(Key key, int eventType) { + final AccessibilityEntityProvider nodeProvider = getAccessibilityNodeProvider(null); + final AccessibilityEvent event = nodeProvider.createAccessibilityEvent(key, eventType); + + // Propagates the event up the view hierarchy. + ViewParentCompatUtils.requestSendAccessibilityEvent(mView.getParent(), mView, event); } private class KeyboardFlickGestureDetector extends FlickGestureDetector { diff --git a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java index db12f76ad..eaa4ddff6 100644 --- a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java +++ b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java @@ -18,6 +18,7 @@ package com.android.inputmethod.accessibility; import android.content.Context; import android.os.Message; +import android.support.v4.view.MotionEventCompat; import android.view.MotionEvent; import android.view.ViewConfiguration; @@ -32,7 +33,7 @@ import com.android.inputmethod.latin.StaticInnerHandlerWrapper; * properties: *
    *
  • Begins with a {@link MotionEventCompatUtils#ACTION_HOVER_ENTER} event - *
  • Contains any number of {@link MotionEventCompatUtils#ACTION_HOVER_MOVE} + *
  • Contains any number of {@link MotionEventCompat#ACTION_HOVER_MOVE} * events *
  • Ends with a {@link MotionEventCompatUtils#ACTION_HOVER_EXIT} event *
  • Maximum duration of 250 milliseconds @@ -128,7 +129,7 @@ public abstract class FlickGestureDetector { final float distanceSquare = calculateDistanceSquare(mCachedHoverEnter, event); switch (event.getAction()) { - case MotionEventCompatUtils.ACTION_HOVER_MOVE: + case MotionEventCompat.ACTION_HOVER_MOVE: // Consume all valid move events before timeout. return true; case MotionEventCompatUtils.ACTION_HOVER_EXIT: diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java index f0dba4a02..3d861c231 100644 --- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java +++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java @@ -18,6 +18,7 @@ package com.android.inputmethod.accessibility; import android.content.Context; import android.text.TextUtils; +import android.util.Log; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; @@ -27,6 +28,8 @@ import com.android.inputmethod.latin.R; import java.util.HashMap; public class KeyCodeDescriptionMapper { + private static final String TAG = KeyCodeDescriptionMapper.class.getSimpleName(); + // The resource ID of the string spoken for obscured keys private static final int OBSCURED_KEY_RES_ID = R.string.spoken_description_dot; @@ -87,12 +90,12 @@ public class KeyCodeDescriptionMapper { * @return a character sequence describing the action performed by pressing * the key */ - public CharSequence getDescriptionForKey(Context context, Keyboard keyboard, Key key, + public String getDescriptionForKey(Context context, Keyboard keyboard, Key key, boolean shouldObscure) { final int code = key.mCode; if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { - final CharSequence description = getDescriptionForSwitchAlphaSymbol(context, keyboard); + final String description = getDescriptionForSwitchAlphaSymbol(context, keyboard); if (description != null) return description; } @@ -128,7 +131,7 @@ public class KeyCodeDescriptionMapper { * @return a character sequence describing the action performed by pressing * the key */ - private CharSequence getDescriptionForSwitchAlphaSymbol(Context context, Keyboard keyboard) { + private String getDescriptionForSwitchAlphaSymbol(Context context, Keyboard keyboard) { final KeyboardId keyboardId = keyboard.mId; final int elementId = keyboardId.mElementId; final int resId; @@ -152,10 +155,7 @@ public class KeyCodeDescriptionMapper { resId = R.string.spoken_description_to_numeric; break; default: - resId = -1; - } - - if (resId < 0) { + Log.e(TAG, "Missing description for keyboard element ID:" + elementId); return null; } @@ -169,7 +169,7 @@ public class KeyCodeDescriptionMapper { * @param keyboard The keyboard on which the key resides. * @return A context-sensitive description of the "Shift" key. */ - private CharSequence getDescriptionForShiftKey(Context context, Keyboard keyboard) { + private String getDescriptionForShiftKey(Context context, Keyboard keyboard) { final KeyboardId keyboardId = keyboard.mId; final int elementId = keyboardId.mElementId; final int resId; @@ -212,7 +212,7 @@ public class KeyCodeDescriptionMapper { * @return a character sequence describing the action performed by pressing * the key */ - private CharSequence getDescriptionForKeyCode(Context context, Keyboard keyboard, Key key, + private String getDescriptionForKeyCode(Context context, Keyboard keyboard, Key key, boolean shouldObscure) { final int code = key.mCode; diff --git a/java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java b/java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java deleted file mode 100644 index 2fa9d87d8..000000000 --- a/java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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; - -public class AccessibilityEventCompatUtils { - public static final int TYPE_VIEW_HOVER_ENTER = 0x80; - public static final int TYPE_VIEW_HOVER_EXIT = 0x100; -} diff --git a/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatUtils.java b/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatUtils.java new file mode 100644 index 000000000..41b6a074d --- /dev/null +++ b/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatUtils.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 android.view.accessibility.AccessibilityManager; + +import java.lang.reflect.Method; + +public class AccessibilityManagerCompatUtils { + private static final Method METHOD_isTouchExplorationEnabled = CompatUtils.getMethod( + AccessibilityManager.class, "isTouchExplorationEnabled"); + + private AccessibilityManagerCompatUtils() { + // This class is non-instantiable. + } + + public static boolean isTouchExplorationEnabled(AccessibilityManager receiver) { + return (Boolean) CompatUtils.invoke(receiver, false, METHOD_isTouchExplorationEnabled); + } +} diff --git a/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java deleted file mode 100644 index a30af0faf..000000000 --- a/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 android.view.accessibility.AccessibilityManager; - -import java.lang.reflect.Method; - -public class AccessibilityManagerCompatWrapper { - private static final Method METHOD_isTouchExplorationEnabled = CompatUtils.getMethod( - AccessibilityManager.class, "isTouchExplorationEnabled"); - - private final AccessibilityManager mManager; - - public AccessibilityManagerCompatWrapper(AccessibilityManager manager) { - mManager = manager; - } - - public boolean isTouchExplorationEnabled() { - return (Boolean) CompatUtils.invoke(mManager, false, METHOD_isTouchExplorationEnabled); - } -} diff --git a/java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java b/java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java index 8518a4a78..eca922e68 100644 --- a/java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java @@ -17,7 +17,7 @@ package com.android.inputmethod.compat; public class MotionEventCompatUtils { - public static final int ACTION_HOVER_MOVE = 0x7; + // TODO(alanv): Remove after these are added to MotionEventCompat. public static final int ACTION_HOVER_ENTER = 0x9; public static final int ACTION_HOVER_EXIT = 0xA; } diff --git a/java/src/com/android/inputmethod/compat/ViewParentCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewParentCompatUtils.java new file mode 100644 index 000000000..d19bc3af1 --- /dev/null +++ b/java/src/com/android/inputmethod/compat/ViewParentCompatUtils.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2012 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 android.view.View; +import android.view.ViewParent; +import android.view.accessibility.AccessibilityEvent; + +import java.lang.reflect.Method; + +public class ViewParentCompatUtils { + private static final Method METHOD_requestSendAccessibilityEvent = CompatUtils.getMethod( + ViewParent.class, "requestSendAccessibilityEvent", View.class, + AccessibilityEvent.class); + + /** + * Called by a child to request from its parent to send an {@link AccessibilityEvent}. + * The child has already populated a record for itself in the event and is delegating + * to its parent to send the event. The parent can optionally add a record for itself. + *

    + * Note: An accessibility event is fired by an individual view which populates the + * event with a record for its state and requests from its parent to perform + * the sending. The parent can optionally add a record for itself before + * dispatching the request to its parent. A parent can also choose not to + * respect the request for sending the event. The accessibility event is sent + * by the topmost view in the view tree.

    + * + * @param child The child which requests sending the event. + * @param event The event to be sent. + * @return True if the event was sent. + */ + public static boolean requestSendAccessibilityEvent( + ViewParent receiver, View child, AccessibilityEvent event) { + return (Boolean) CompatUtils.invoke( + receiver, false, METHOD_requestSendAccessibilityEvent, child, event); + } +} diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 622e5831f..e1c6f2604 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -379,7 +379,7 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, // This always needs to be set since the accessibility state can // potentially change without the input view being re-created. - AccessibleKeyboardViewProxy.setView(mKeyboardView); + AccessibleKeyboardViewProxy.getInstance().setView(mKeyboardView); return mCurrentInputView; } diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 9a0fe1efa..00570fb0b 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -34,7 +34,6 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; -import android.view.accessibility.AccessibilityEvent; import android.widget.PopupWindow; import com.android.inputmethod.accessibility.AccessibilityUtils; @@ -735,16 +734,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke VoiceProxy.getInstance().onAttachedToWindow(); } - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { - return AccessibleKeyboardViewProxy.getInstance().dispatchPopulateAccessibilityEvent( - event) || super.dispatchPopulateAccessibilityEvent(event); - } - - return super.dispatchPopulateAccessibilityEvent(event); - } - /** * Receives hover events from the input framework. This method overrides * View.dispatchHoverEvent(MotionEvent) on SDK version ICS or higher. On -- cgit v1.2.3-83-g751a From c6435f92a80c6664870f9d1a4bb2a1c5153ef2c3 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 2 Apr 2012 23:13:09 +0900 Subject: Remove AccessibilityManagerCompatUtils and MorionEventCompatUtils Bug: 6129704 Change-Id: Icb7e80588536066c4fe5b4a1afc100a724b43e7b --- .../accessibility/AccessibilityUtils.java | 11 +++---- .../accessibility/AccessibleKeyboardViewProxy.java | 18 +++++------- .../accessibility/FlickGestureDetector.java | 20 +++++-------- .../compat/AccessibilityManagerCompatUtils.java | 34 ---------------------- .../inputmethod/compat/MotionEventCompatUtils.java | 23 --------------- .../inputmethod/keyboard/LatinKeyboardView.java | 6 ++-- 6 files changed, 22 insertions(+), 90 deletions(-) delete mode 100644 java/src/com/android/inputmethod/compat/AccessibilityManagerCompatUtils.java delete mode 100644 java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java (limited to 'java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java') diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index 41da2aa4c..af10e75bf 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -21,17 +21,14 @@ import android.inputmethodservice.InputMethodService; import android.media.AudioManager; import android.os.SystemClock; import android.provider.Settings; -import android.support.v4.view.MotionEventCompat; import android.util.Log; import android.view.MotionEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.compat.AccessibilityManagerCompatUtils; 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; @@ -93,7 +90,7 @@ public class AccessibilityUtils { public boolean isTouchExplorationEnabled() { return ENABLE_ACCESSIBILITY && mAccessibilityManager.isEnabled() - && AccessibilityManagerCompatUtils.isTouchExplorationEnabled(mAccessibilityManager); + && mAccessibilityManager.isTouchExplorationEnabled(); } /** @@ -107,9 +104,9 @@ public class AccessibilityUtils { public boolean isTouchExplorationEvent(MotionEvent event) { final int action = event.getAction(); - return action == MotionEventCompatUtils.ACTION_HOVER_ENTER - || action == MotionEventCompatUtils.ACTION_HOVER_EXIT - || action == MotionEventCompat.ACTION_HOVER_MOVE; + return action == MotionEvent.ACTION_HOVER_ENTER + || action == MotionEvent.ACTION_HOVER_EXIT + || action == MotionEvent.ACTION_HOVER_MOVE; } /** diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java index 2401d93c6..083cb2203 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java @@ -21,14 +21,12 @@ import android.graphics.Color; import android.graphics.Paint; import android.inputmethodservice.InputMethodService; import android.support.v4.view.AccessibilityDelegateCompat; -import android.support.v4.view.MotionEventCompat; import android.support.v4.view.ViewCompat; import android.support.v4.view.accessibility.AccessibilityEventCompat; import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityEvent; -import com.android.inputmethod.compat.MotionEventCompatUtils; import com.android.inputmethod.compat.ViewParentCompatUtils; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; @@ -136,10 +134,10 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat { mLastHoverKey = key; switch (event.getAction()) { - case MotionEventCompatUtils.ACTION_HOVER_ENTER: - case MotionEventCompatUtils.ACTION_HOVER_EXIT: + case MotionEvent.ACTION_HOVER_ENTER: + case MotionEvent.ACTION_HOVER_EXIT: return onHoverKey(key, event); - case MotionEventCompat.ACTION_HOVER_MOVE: + case MotionEvent.ACTION_HOVER_MOVE: if (key != previousKey) { return onTransitionKey(key, previousKey, event); } else { @@ -163,13 +161,13 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat { private boolean onTransitionKey(Key currentKey, Key previousKey, MotionEvent event) { final int savedAction = event.getAction(); - event.setAction(MotionEventCompatUtils.ACTION_HOVER_EXIT); + event.setAction(MotionEvent.ACTION_HOVER_EXIT); onHoverKey(previousKey, event); - event.setAction(MotionEventCompatUtils.ACTION_HOVER_ENTER); + event.setAction(MotionEvent.ACTION_HOVER_ENTER); onHoverKey(currentKey, event); - event.setAction(MotionEventCompat.ACTION_HOVER_MOVE); + event.setAction(MotionEvent.ACTION_HOVER_MOVE); final boolean handled = onHoverKey(currentKey, event); event.setAction(savedAction); @@ -192,10 +190,10 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat { } switch (event.getAction()) { - case MotionEventCompatUtils.ACTION_HOVER_ENTER: + case MotionEvent.ACTION_HOVER_ENTER: sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER); break; - case MotionEventCompatUtils.ACTION_HOVER_EXIT: + case MotionEvent.ACTION_HOVER_EXIT: sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT); break; } diff --git a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java index eaa4ddff6..e8ec37600 100644 --- a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java +++ b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java @@ -18,11 +18,9 @@ package com.android.inputmethod.accessibility; import android.content.Context; import android.os.Message; -import android.support.v4.view.MotionEventCompat; import android.view.MotionEvent; import android.view.ViewConfiguration; -import com.android.inputmethod.compat.MotionEventCompatUtils; import com.android.inputmethod.keyboard.PointerTracker; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; @@ -32,10 +30,10 @@ import com.android.inputmethod.latin.StaticInnerHandlerWrapper; * A flick gesture is defined as a stream of hover events with the following * properties: *
      - *
    • Begins with a {@link MotionEventCompatUtils#ACTION_HOVER_ENTER} event - *
    • Contains any number of {@link MotionEventCompat#ACTION_HOVER_MOVE} + *
    • Begins with a {@link MotionEvent#ACTION_HOVER_ENTER} event + *
    • Contains any number of {@link MotionEvent#ACTION_HOVER_MOVE} * events - *
    • Ends with a {@link MotionEventCompatUtils#ACTION_HOVER_EXIT} event + *
    • Ends with a {@link MotionEvent#ACTION_HOVER_EXIT} event *
    • Maximum duration of 250 milliseconds *
    • Minimum distance between enter and exit points must be at least equal to * scaled double tap slop (see @@ -113,7 +111,7 @@ public abstract class FlickGestureDetector { public boolean onHoverEvent(MotionEvent event, AccessibleKeyboardViewProxy view, PointerTracker tracker) { // Always cache and consume the first hover event. - if (event.getAction() == MotionEventCompatUtils.ACTION_HOVER_ENTER) { + if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER) { mCachedView = view; mCachedTracker = tracker; mCachedHoverEnter = MotionEvent.obtain(event); @@ -129,10 +127,10 @@ public abstract class FlickGestureDetector { final float distanceSquare = calculateDistanceSquare(mCachedHoverEnter, event); switch (event.getAction()) { - case MotionEventCompat.ACTION_HOVER_MOVE: + case MotionEvent.ACTION_HOVER_MOVE: // Consume all valid move events before timeout. return true; - case MotionEventCompatUtils.ACTION_HOVER_EXIT: + case MotionEvent.ACTION_HOVER_EXIT: // Ignore exit events outside the flick radius. if (distanceSquare < mFlickRadiusSquare) { clearFlick(true); @@ -171,10 +169,8 @@ public abstract class FlickGestureDetector { * Computes the direction of a flick gesture and forwards it to * {@link #onFlick(MotionEvent, MotionEvent, int)} for handling. * - * @param e1 The {@link MotionEventCompatUtils#ACTION_HOVER_ENTER} event - * where the flick started. - * @param e2 The {@link MotionEventCompatUtils#ACTION_HOVER_EXIT} event - * where the flick ended. + * @param e1 The {@link MotionEvent#ACTION_HOVER_ENTER} event where the flick started. + * @param e2 The {@link MotionEvent#ACTION_HOVER_EXIT} event where the flick ended. * @return {@code true} if the flick event was handled. */ private boolean dispatchFlick(MotionEvent e1, MotionEvent e2) { diff --git a/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatUtils.java b/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatUtils.java deleted file mode 100644 index 41b6a074d..000000000 --- a/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 android.view.accessibility.AccessibilityManager; - -import java.lang.reflect.Method; - -public class AccessibilityManagerCompatUtils { - private static final Method METHOD_isTouchExplorationEnabled = CompatUtils.getMethod( - AccessibilityManager.class, "isTouchExplorationEnabled"); - - private AccessibilityManagerCompatUtils() { - // This class is non-instantiable. - } - - public static boolean isTouchExplorationEnabled(AccessibilityManager receiver) { - return (Boolean) CompatUtils.invoke(receiver, false, METHOD_isTouchExplorationEnabled); - } -} diff --git a/java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java b/java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java deleted file mode 100644 index 9a523011a..000000000 --- a/java/src/com/android/inputmethod/compat/MotionEventCompatUtils.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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; - -public class MotionEventCompatUtils { - // TODO: Remove after these are added to MotionEventCompat. - public static final int ACTION_HOVER_ENTER = 0x9; - public static final int ACTION_HOVER_EXIT = 0xA; -} diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 62bcf6ca8..e2af97185 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -828,15 +828,13 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke } /** - * Receives hover events from the input framework. This method overrides - * View.dispatchHoverEvent(MotionEvent) on SDK version ICS or higher. On - * lower SDK versions, this method is never called. + * Receives hover events from the input framework. * * @param event The motion event to be dispatched. * @return {@code true} if the event was handled by the view, {@code false} * otherwise */ - //Should not annotate @override + @Override public boolean dispatchHoverEvent(MotionEvent event) { if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { final PointerTracker tracker = PointerTracker.getPointerTracker(0, this); -- cgit v1.2.3-83-g751a From be55086fd9218bc03ee0ccac1052d96b40d8a979 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 2 Apr 2012 22:43:38 +0900 Subject: Cleanup InputTypeCompatUtils to InputTypeUtils Bug: 6129704 Change-Id: I45e19e456ef7c6e61fe877ea544fef1b9f896e95 --- .../accessibility/AccessibilityUtils.java | 4 +- .../inputmethod/compat/InputTypeCompatUtils.java | 118 --------------------- .../android/inputmethod/keyboard/KeyboardId.java | 6 +- .../android/inputmethod/keyboard/KeyboardSet.java | 4 +- .../android/inputmethod/latin/InputAttributes.java | 8 +- .../android/inputmethod/latin/InputTypeUtils.java | 90 ++++++++++++++++ .../android/inputmethod/latin/SettingsValues.java | 4 +- 7 files changed, 101 insertions(+), 133 deletions(-) delete mode 100644 java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java create mode 100644 java/src/com/android/inputmethod/latin/InputTypeUtils.java (limited to 'java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java') diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index af10e75bf..667b109cb 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -28,8 +28,8 @@ import android.view.accessibility.AccessibilityManager; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.compat.AudioManagerCompatWrapper; -import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.compat.SettingsSecureCompatUtils; +import com.android.inputmethod.latin.InputTypeUtils; import com.android.inputmethod.latin.R; public class AccessibilityUtils { @@ -132,7 +132,7 @@ public class AccessibilityUtils { return false; // Don't speak if the IME is connected to a password field. - return InputTypeCompatUtils.isPasswordInputType(editorInfo.inputType); + return InputTypeUtils.isPasswordInputType(editorInfo.inputType); } /** diff --git a/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java b/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java deleted file mode 100644 index 6c2f0f799..000000000 --- a/java/src/com/android/inputmethod/compat/InputTypeCompatUtils.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 android.text.InputType; - -import java.lang.reflect.Field; - -public class InputTypeCompatUtils { - private static final Field FIELD_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS = - CompatUtils.getField(InputType.class, "TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS"); - private static final Field FIELD_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD = CompatUtils - .getField(InputType.class, "TYPE_TEXT_VARIATION_WEB_PASSWORD"); - private static final Field FIELD_InputType_TYPE_NUMBER_VARIATION_PASSWORD = CompatUtils - .getField(InputType.class, "TYPE_NUMBER_VARIATION_PASSWORD"); - private static final Integer OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS = - (Integer) CompatUtils.getFieldValue(null, null, - FIELD_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS); - private static final Integer OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD = - (Integer) CompatUtils.getFieldValue(null, null, - FIELD_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD); - private static final Integer OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD = - (Integer) CompatUtils.getFieldValue(null, null, - FIELD_InputType_TYPE_NUMBER_VARIATION_PASSWORD); - private static final int WEB_TEXT_PASSWORD_INPUT_TYPE; - private static final int WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE; - private static final int NUMBER_PASSWORD_INPUT_TYPE; - private static final int TEXT_PASSWORD_INPUT_TYPE = - InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD; - private static final int TEXT_VISIBLE_PASSWORD_INPUT_TYPE = - InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD; - - static { - WEB_TEXT_PASSWORD_INPUT_TYPE = - OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD != null - ? InputType.TYPE_CLASS_TEXT | OBJ_InputType_TYPE_TEXT_VARIATION_WEB_PASSWORD - : 0; - WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE = - OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS != null - ? InputType.TYPE_CLASS_TEXT - | OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS - : 0; - NUMBER_PASSWORD_INPUT_TYPE = - OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD != null - ? InputType.TYPE_CLASS_NUMBER | OBJ_InputType_TYPE_NUMBER_VARIATION_PASSWORD - : 0; - } - - private static boolean isWebEditTextInputType(int inputType) { - return inputType == (InputType.TYPE_CLASS_TEXT - | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT); - } - - private static boolean isWebPasswordInputType(int inputType) { - return WEB_TEXT_PASSWORD_INPUT_TYPE != 0 - && inputType == WEB_TEXT_PASSWORD_INPUT_TYPE; - } - - private static boolean isWebEmailAddressInputType(int inputType) { - return WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE != 0 - && inputType == WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE; - } - - private static boolean isNumberPasswordInputType(int inputType) { - return NUMBER_PASSWORD_INPUT_TYPE != 0 - && inputType == NUMBER_PASSWORD_INPUT_TYPE; - } - - private static boolean isTextPasswordInputType(int inputType) { - return inputType == TEXT_PASSWORD_INPUT_TYPE; - } - - private static boolean isWebEmailAddressVariation(int variation) { - return OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS != null - && variation == OBJ_InputType_TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS; - } - - public static boolean isEmailVariation(int variation) { - return variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS - || isWebEmailAddressVariation(variation); - } - - public static boolean isWebInputType(int inputType) { - final int maskedInputType = - inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION); - return isWebEditTextInputType(maskedInputType) || isWebPasswordInputType(maskedInputType) - || isWebEmailAddressInputType(maskedInputType); - } - - // Please refer to TextView.isPasswordInputType - public static boolean isPasswordInputType(int inputType) { - final int maskedInputType = - inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION); - return isTextPasswordInputType(maskedInputType) || isWebPasswordInputType(maskedInputType) - || isNumberPasswordInputType(maskedInputType); - } - - // Please refer to TextView.isVisiblePasswordInputType - public static boolean isVisiblePasswordInputType(int inputType) { - final int maskedInputType = - inputType & (InputType.TYPE_MASK_CLASS | InputType.TYPE_MASK_VARIATION); - return maskedInputType == TEXT_VISIBLE_PASSWORD_INPUT_TYPE; - } -} diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java index eef065f52..e35081867 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -21,7 +21,7 @@ import android.text.TextUtils; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.compat.EditorInfoCompatUtils; -import com.android.inputmethod.compat.InputTypeCompatUtils; +import com.android.inputmethod.latin.InputTypeUtils; import java.util.Arrays; import java.util.Locale; @@ -140,8 +140,8 @@ public class KeyboardId { public boolean passwordInput() { final int inputType = mEditorInfo.inputType; - return InputTypeCompatUtils.isPasswordInputType(inputType) - || InputTypeCompatUtils.isVisiblePasswordInputType(inputType); + return InputTypeUtils.isPasswordInputType(inputType) + || InputTypeUtils.isVisiblePasswordInputType(inputType); } public boolean isMultiLine() { diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java index 4d0f00380..62cb41b9e 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java @@ -27,8 +27,8 @@ import android.util.Xml; import android.view.inputmethod.EditorInfo; import com.android.inputmethod.compat.EditorInfoCompatUtils; -import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.keyboard.KeyboardSet.Params.ElementParams; +import com.android.inputmethod.latin.InputTypeUtils; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LocaleUtils; @@ -379,7 +379,7 @@ public class KeyboardSet { case InputType.TYPE_CLASS_PHONE: return KeyboardId.MODE_PHONE; case InputType.TYPE_CLASS_TEXT: - if (InputTypeCompatUtils.isEmailVariation(variation)) { + if (InputTypeUtils.isEmailVariation(variation)) { return KeyboardId.MODE_EMAIL; } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { return KeyboardId.MODE_URL; diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java index 06c70c42c..a6ce04069 100644 --- a/java/src/com/android/inputmethod/latin/InputAttributes.java +++ b/java/src/com/android/inputmethod/latin/InputAttributes.java @@ -20,8 +20,6 @@ import android.text.InputType; import android.util.Log; import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.compat.InputTypeCompatUtils; - /** * Class to hold attributes of the input field. */ @@ -66,9 +64,9 @@ public class InputAttributes { 0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE); // Make sure that passwords are not displayed in {@link SuggestionsView}. - if (InputTypeCompatUtils.isPasswordInputType(inputType) - || InputTypeCompatUtils.isVisiblePasswordInputType(inputType) - || InputTypeCompatUtils.isEmailVariation(variation) + if (InputTypeUtils.isPasswordInputType(inputType) + || InputTypeUtils.isVisiblePasswordInputType(inputType) + || InputTypeUtils.isEmailVariation(variation) || InputType.TYPE_TEXT_VARIATION_URI == variation || InputType.TYPE_TEXT_VARIATION_FILTER == variation || flagNoSuggestions diff --git a/java/src/com/android/inputmethod/latin/InputTypeUtils.java b/java/src/com/android/inputmethod/latin/InputTypeUtils.java new file mode 100644 index 000000000..40c3b765e --- /dev/null +++ b/java/src/com/android/inputmethod/latin/InputTypeUtils.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012 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.text.InputType; + +public class InputTypeUtils implements InputType { + private static final int WEB_TEXT_PASSWORD_INPUT_TYPE = + TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_WEB_PASSWORD; + private static final int WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE = + TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS; + private static final int NUMBER_PASSWORD_INPUT_TYPE = + TYPE_CLASS_NUMBER | TYPE_NUMBER_VARIATION_PASSWORD; + private static final int TEXT_PASSWORD_INPUT_TYPE = + TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD; + private static final int TEXT_VISIBLE_PASSWORD_INPUT_TYPE = + TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_VISIBLE_PASSWORD; + + private InputTypeUtils() { + // This utility class is not publicly instantiable. + } + + private static boolean isWebEditTextInputType(int inputType) { + return inputType == (TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_WEB_EDIT_TEXT); + } + + private static boolean isWebPasswordInputType(int inputType) { + return WEB_TEXT_PASSWORD_INPUT_TYPE != 0 + && inputType == WEB_TEXT_PASSWORD_INPUT_TYPE; + } + + private static boolean isWebEmailAddressInputType(int inputType) { + return WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE != 0 + && inputType == WEB_TEXT_EMAIL_ADDRESS_INPUT_TYPE; + } + + private static boolean isNumberPasswordInputType(int inputType) { + return NUMBER_PASSWORD_INPUT_TYPE != 0 + && inputType == NUMBER_PASSWORD_INPUT_TYPE; + } + + private static boolean isTextPasswordInputType(int inputType) { + return inputType == TEXT_PASSWORD_INPUT_TYPE; + } + + private static boolean isWebEmailAddressVariation(int variation) { + return variation == TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS; + } + + public static boolean isEmailVariation(int variation) { + return variation == TYPE_TEXT_VARIATION_EMAIL_ADDRESS + || isWebEmailAddressVariation(variation); + } + + public static boolean isWebInputType(int inputType) { + final int maskedInputType = + inputType & (TYPE_MASK_CLASS | TYPE_MASK_VARIATION); + return isWebEditTextInputType(maskedInputType) || isWebPasswordInputType(maskedInputType) + || isWebEmailAddressInputType(maskedInputType); + } + + // Please refer to TextView.isPasswordInputType + public static boolean isPasswordInputType(int inputType) { + final int maskedInputType = + inputType & (TYPE_MASK_CLASS | TYPE_MASK_VARIATION); + return isTextPasswordInputType(maskedInputType) || isWebPasswordInputType(maskedInputType) + || isNumberPasswordInputType(maskedInputType); + } + + // Please refer to TextView.isVisiblePasswordInputType + public static boolean isVisiblePasswordInputType(int inputType) { + final int maskedInputType = + inputType & (TYPE_MASK_CLASS | TYPE_MASK_VARIATION); + return maskedInputType == TEXT_VISIBLE_PASSWORD_INPUT_TYPE; + } +} diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index f76cc7e44..d46160f0d 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -22,10 +22,8 @@ import android.content.res.Resources; import android.util.Log; import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.keyboard.internal.KeySpecParser; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import com.android.inputmethod.latin.VibratorUtils; import java.util.ArrayList; import java.util.Arrays; @@ -286,7 +284,7 @@ public class SettingsValues { final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled(); final int inputType = (editorInfo != null) ? editorInfo.inputType : 0; return shortcutImeEnabled && mVoiceKeyEnabled - && !InputTypeCompatUtils.isPasswordInputType(inputType); + && !InputTypeUtils.isPasswordInputType(inputType); } public boolean isVoiceKeyOnMain() { -- cgit v1.2.3-83-g751a From 34b2b5e694758390126ffa3b1c7d752cdde7a05c Mon Sep 17 00:00:00 2001 From: alanv Date: Tue, 8 May 2012 17:23:58 -0700 Subject: Remove accessibility gesture handlers from LatinIME. Bug: 6457558 Change-Id: If33ca6f026d4846ba79a701ef42c0112f5b0b488 --- .../accessibility/AccessibilityUtils.java | 1 - .../AccessibleInputMethodServiceProxy.java | 84 -------- .../AccessibleKeyboardActionListener.java | 30 --- .../accessibility/AccessibleKeyboardViewProxy.java | 39 ---- .../accessibility/FlickGestureDetector.java | 223 --------------------- 5 files changed, 377 deletions(-) delete mode 100644 java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java delete mode 100644 java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java delete mode 100644 java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java (limited to 'java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java') diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index 667b109cb..2ea7d83e4 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -58,7 +58,6 @@ public class AccessibilityUtils { // These only need to be initialized if the kill switch is off. sInstance.initInternal(inputMethod); KeyCodeDescriptionMapper.init(); - AccessibleInputMethodServiceProxy.init(inputMethod); AccessibleKeyboardViewProxy.init(inputMethod); } diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java deleted file mode 100644 index 961176bb8..000000000 --- a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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.accessibility; - -import android.content.Context; -import android.inputmethodservice.InputMethodService; -import android.media.AudioManager; -import android.os.Vibrator; -import android.view.KeyEvent; - -public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActionListener { - private static final AccessibleInputMethodServiceProxy sInstance = - new AccessibleInputMethodServiceProxy(); - - /** - * Duration of the key click vibration in milliseconds. - */ - private static final long VIBRATE_KEY_CLICK = 50; - - private static final float FX_VOLUME = -1.0f; - - private InputMethodService mInputMethod; - private Vibrator mVibrator; - private AudioManager mAudioManager; - - public static void init(InputMethodService inputMethod) { - sInstance.initInternal(inputMethod); - } - - public static AccessibleInputMethodServiceProxy getInstance() { - return sInstance; - } - - private AccessibleInputMethodServiceProxy() { - // Not publicly instantiable. - } - - private void initInternal(InputMethodService inputMethod) { - mInputMethod = inputMethod; - mVibrator = (Vibrator) inputMethod.getSystemService(Context.VIBRATOR_SERVICE); - mAudioManager = (AudioManager) inputMethod.getSystemService(Context.AUDIO_SERVICE); - } - - /** - * Handle flick gestures by mapping them to directional pad keys. - */ - @Override - public void onFlickGesture(int direction) { - switch (direction) { - case FlickGestureDetector.FLICK_LEFT: - sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT); - break; - case FlickGestureDetector.FLICK_RIGHT: - sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT); - break; - } - } - - /** - * Provide haptic feedback and send the specified keyCode to the input - * connection as a pair of down/up events. - * - * @param keyCode - */ - private void sendDownUpKeyEvents(int keyCode) { - mVibrator.vibrate(VIBRATE_KEY_CLICK); - mAudioManager.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD, FX_VOLUME); - mInputMethod.sendDownUpKeyEvents(keyCode); - } -} diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java deleted file mode 100644 index 31d17d09f..000000000 --- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardActionListener.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.accessibility; - -public interface AccessibleKeyboardActionListener { - /** - * @param direction the direction of the flick gesture, one of - *
        - *
      • {@link FlickGestureDetector#FLICK_UP} - *
      • {@link FlickGestureDetector#FLICK_DOWN} - *
      • {@link FlickGestureDetector#FLICK_LEFT} - *
      • {@link FlickGestureDetector#FLICK_RIGHT} - *
      - */ - public void onFlickGesture(int direction); -} diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java index c85a5514e..ba814e390 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java @@ -17,8 +17,6 @@ package com.android.inputmethod.accessibility; import android.content.Context; -import android.graphics.Color; -import android.graphics.Paint; import android.inputmethodservice.InputMethodService; import android.support.v4.view.AccessibilityDelegateCompat; import android.support.v4.view.ViewCompat; @@ -38,16 +36,13 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat { private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy(); private InputMethodService mInputMethod; - private FlickGestureDetector mGestureDetector; private LatinKeyboardView mView; - private AccessibleKeyboardActionListener mListener; private AccessibilityEntityProvider mAccessibilityNodeProvider; private Key mLastHoverKey = null; public static void init(InputMethodService inputMethod) { sInstance.initInternal(inputMethod); - sInstance.mListener = AccessibleInputMethodServiceProxy.getInstance(); } public static AccessibleKeyboardViewProxy getInstance() { @@ -59,14 +54,7 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat { } private void initInternal(InputMethodService inputMethod) { - final Paint paint = new Paint(); - paint.setTextAlign(Paint.Align.LEFT); - paint.setTextSize(14.0f); - paint.setAntiAlias(true); - paint.setColor(Color.YELLOW); - mInputMethod = inputMethod; - mGestureDetector = new KeyboardFlickGestureDetector(inputMethod); } /** @@ -112,19 +100,6 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat { * @return {@code true} if the event is handled */ public boolean dispatchHoverEvent(MotionEvent event, PointerTracker tracker) { - if (mGestureDetector.onHoverEvent(event, this, tracker)) - return true; - - return onHoverEventInternal(event, tracker); - } - - /** - * Handles touch exploration events when Accessibility is turned on. - * - * @param event The touch exploration hover event. - * @return {@code true} if the event was handled - */ - /* package */boolean onHoverEventInternal(MotionEvent event, PointerTracker tracker) { final int x = (int) event.getX(); final int y = (int) event.getY(); final Key key = tracker.getKeyOn(x, y); @@ -214,20 +189,6 @@ public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat { mView.getParent().requestSendAccessibilityEvent(mView, event); } - private class KeyboardFlickGestureDetector extends FlickGestureDetector { - public KeyboardFlickGestureDetector(Context context) { - super(context); - } - - @Override - public boolean onFlick(MotionEvent e1, MotionEvent e2, int direction) { - if (mListener != null) { - mListener.onFlickGesture(direction); - } - return true; - } - } - /** * Notifies the user of changes in the keyboard shift state. */ diff --git a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java b/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java deleted file mode 100644 index e8ec37600..000000000 --- a/java/src/com/android/inputmethod/accessibility/FlickGestureDetector.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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.accessibility; - -import android.content.Context; -import android.os.Message; -import android.view.MotionEvent; -import android.view.ViewConfiguration; - -import com.android.inputmethod.keyboard.PointerTracker; -import com.android.inputmethod.latin.StaticInnerHandlerWrapper; - -/** - * Detects flick gestures within a stream of hover events. - *

      - * A flick gesture is defined as a stream of hover events with the following - * properties: - *

        - *
      • Begins with a {@link MotionEvent#ACTION_HOVER_ENTER} event - *
      • Contains any number of {@link MotionEvent#ACTION_HOVER_MOVE} - * events - *
      • Ends with a {@link MotionEvent#ACTION_HOVER_EXIT} event - *
      • Maximum duration of 250 milliseconds - *
      • Minimum distance between enter and exit points must be at least equal to - * scaled double tap slop (see - * {@link ViewConfiguration#getScaledDoubleTapSlop()}) - *
      - *

      - * Initial enter events are intercepted and cached until the stream fails to - * satisfy the constraints defined above, at which point the cached enter event - * is sent to its source {@link AccessibleKeyboardViewProxy} and subsequent move - * and exit events are ignored. - */ -public abstract class FlickGestureDetector { - public static final int FLICK_UP = 0; - public static final int FLICK_RIGHT = 1; - public static final int FLICK_LEFT = 2; - public static final int FLICK_DOWN = 3; - - private final FlickHandler mFlickHandler; - private final int mFlickRadiusSquare; - - private AccessibleKeyboardViewProxy mCachedView; - private PointerTracker mCachedTracker; - private MotionEvent mCachedHoverEnter; - - private static class FlickHandler extends StaticInnerHandlerWrapper { - private static final int MSG_FLICK_TIMEOUT = 1; - - /** The maximum duration of a flick gesture in milliseconds. */ - private static final int DELAY_FLICK_TIMEOUT = 250; - - public FlickHandler(FlickGestureDetector outerInstance) { - super(outerInstance); - } - - @Override - public void handleMessage(Message msg) { - final FlickGestureDetector gestureDetector = getOuterInstance(); - - switch (msg.what) { - case MSG_FLICK_TIMEOUT: - gestureDetector.clearFlick(true); - } - } - - public void startFlickTimeout() { - cancelFlickTimeout(); - sendEmptyMessageDelayed(MSG_FLICK_TIMEOUT, DELAY_FLICK_TIMEOUT); - } - - public void cancelFlickTimeout() { - removeMessages(MSG_FLICK_TIMEOUT); - } - } - - /** - * Creates a new flick gesture detector. - * - * @param context The parent context. - */ - public FlickGestureDetector(Context context) { - final int doubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop(); - - mFlickHandler = new FlickHandler(this); - mFlickRadiusSquare = doubleTapSlop * doubleTapSlop; - } - - /** - * Processes motion events to detect flick gestures. - * - * @param event The current event. - * @param view The source of the event. - * @param tracker A pointer tracker for the event. - * @return {@code true} if the event was handled. - */ - public boolean onHoverEvent(MotionEvent event, AccessibleKeyboardViewProxy view, - PointerTracker tracker) { - // Always cache and consume the first hover event. - if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER) { - mCachedView = view; - mCachedTracker = tracker; - mCachedHoverEnter = MotionEvent.obtain(event); - mFlickHandler.startFlickTimeout(); - return true; - } - - // Stop if the event has already been canceled. - if (mCachedHoverEnter == null) { - return false; - } - - final float distanceSquare = calculateDistanceSquare(mCachedHoverEnter, event); - - switch (event.getAction()) { - case MotionEvent.ACTION_HOVER_MOVE: - // Consume all valid move events before timeout. - return true; - case MotionEvent.ACTION_HOVER_EXIT: - // Ignore exit events outside the flick radius. - if (distanceSquare < mFlickRadiusSquare) { - clearFlick(true); - return false; - } else { - return dispatchFlick(mCachedHoverEnter, event); - } - default: - return false; - } - } - - /** - * Clears the cached flick information and optionally forwards the event to - * the source view's internal hover event handler. - * - * @param sendCachedEvent Set to {@code true} to forward the hover event to - * the source view. - */ - private void clearFlick(boolean sendCachedEvent) { - mFlickHandler.cancelFlickTimeout(); - - if (mCachedHoverEnter != null) { - if (sendCachedEvent) { - mCachedView.onHoverEventInternal(mCachedHoverEnter, mCachedTracker); - } - mCachedHoverEnter.recycle(); - mCachedHoverEnter = null; - } - - mCachedTracker = null; - mCachedView = null; - } - - /** - * Computes the direction of a flick gesture and forwards it to - * {@link #onFlick(MotionEvent, MotionEvent, int)} for handling. - * - * @param e1 The {@link MotionEvent#ACTION_HOVER_ENTER} event where the flick started. - * @param e2 The {@link MotionEvent#ACTION_HOVER_EXIT} event where the flick ended. - * @return {@code true} if the flick event was handled. - */ - private boolean dispatchFlick(MotionEvent e1, MotionEvent e2) { - clearFlick(false); - - final float dX = e2.getX() - e1.getX(); - final float dY = e2.getY() - e1.getY(); - final int direction; - - if (dY > dX) { - if (dY > -dX) { - direction = FLICK_DOWN; - } else { - direction = FLICK_LEFT; - } - } else { - if (dY > -dX) { - direction = FLICK_RIGHT; - } else { - direction = FLICK_UP; - } - } - - return onFlick(e1, e2, direction); - } - - private float calculateDistanceSquare(MotionEvent e1, MotionEvent e2) { - final float dX = e2.getX() - e1.getX(); - final float dY = e2.getY() - e1.getY(); - return (dX * dX) + (dY * dY); - } - - /** - * Handles a detected flick gesture. - * - * @param e1 The {@link MotionEventCompatUtils#ACTION_HOVER_ENTER} event - * where the flick started. - * @param e2 The {@link MotionEventCompatUtils#ACTION_HOVER_EXIT} event - * where the flick ended. - * @param direction The direction of the flick event, one of: - *

        - *
      • {@link #FLICK_UP} - *
      • {@link #FLICK_DOWN} - *
      • {@link #FLICK_LEFT} - *
      • {@link #FLICK_RIGHT} - *
      - * @return {@code true} if the flick event was handled. - */ - public abstract boolean onFlick(MotionEvent e1, MotionEvent e2, int direction); -} -- cgit v1.2.3-83-g751a From 282adf733093b41a31514746825ea05fc90fb3ee Mon Sep 17 00:00:00 2001 From: alanv Date: Sat, 19 May 2012 00:05:13 -0700 Subject: Pass IME accessibility events directly to the AccessibilityManager. Bug: 6523554 Change-Id: I44bceb7b068ff1ac0c799f4a93d5dcd8026f1e4b --- .../accessibility/AccessibilityEntityProvider.java | 7 ++++++- .../inputmethod/accessibility/AccessibilityUtils.java | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java') diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java index 67e21b10c..3cfef972a 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java @@ -282,7 +282,12 @@ public class AccessibilityEntityProvider extends AccessibilityNodeProviderCompat return; } - parent.requestSendAccessibilityEvent(mKeyboardView, event); + if (!parent.requestSendAccessibilityEvent(mKeyboardView, event)) { + // TODO: Remove this line after the top-level view for the IME + // window is fixed to be non-null and requestSendAccessibilityEvent + // can return true. + mAccessibilityUtils.requestSendAccessibilityEvent(event); + } } /** diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index 2ea7d83e4..616b1c6d7 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -174,4 +174,16 @@ public class AccessibilityUtils { speak(text); } } + + /** + * Sends the specified {@link AccessibilityEvent} if accessibility is + * enabled. No operation if accessibility is disabled. + * + * @param event The event to send. + */ + public void requestSendAccessibilityEvent(AccessibilityEvent event) { + if (mAccessibilityManager.isEnabled()) { + mAccessibilityManager.sendAccessibilityEvent(event); + } + } } -- cgit v1.2.3-83-g751a