Announce keyboard mode changes as a WINDOW_STATE_CHANGED event.
Bug: 8165295 Change-Id: Ie416f6cdb68377f3e06f30e9b6363c38ba2a602dmain
parent
042020b05f
commit
c2ee72a214
|
@ -223,6 +223,29 @@
|
||||||
<!-- Spoken feedback after changing to the shifted phone dialer (symbols) keyboard. -->
|
<!-- Spoken feedback after changing to the shifted phone dialer (symbols) keyboard. -->
|
||||||
<string name="spoken_description_mode_phone_shift">Phone symbols mode</string>
|
<string name="spoken_description_mode_phone_shift">Phone symbols mode</string>
|
||||||
|
|
||||||
|
<!-- Spoken feedback when the keyboard is hidden. -->
|
||||||
|
<string name="announce_keyboard_hidden">Keyboard hidden</string>
|
||||||
|
<!-- Spoken feedback when the keyboard mode changes. -->
|
||||||
|
<string name="announce_keyboard_mode">Showing <xliff:g id="mode" example="email">%s</xliff:g> keyboard</string>
|
||||||
|
<!-- Description of the keyboard mode for entering dates. -->
|
||||||
|
<string name="keyboard_mode_date">date</string>
|
||||||
|
<!-- Description of the keyboard mode for entering dates and times. -->
|
||||||
|
<string name="keyboard_mode_date_time">date and time</string>
|
||||||
|
<!-- Description of the keyboard mode for entering email addresses. -->
|
||||||
|
<string name="keyboard_mode_email">email</string>
|
||||||
|
<!-- Description of the keyboard mode for entering text messages. -->
|
||||||
|
<string name="keyboard_mode_im">messaging</string>
|
||||||
|
<!-- Description of the keyboard mode for entering numbers. -->
|
||||||
|
<string name="keyboard_mode_number">number</string>
|
||||||
|
<!-- Description of the keyboard mode for entering phone numbers. -->
|
||||||
|
<string name="keyboard_mode_phone">phone</string>
|
||||||
|
<!-- Description of the keyboard mode for entering generic text. -->
|
||||||
|
<string name="keyboard_mode_text">text</string>
|
||||||
|
<!-- Description of the keyboard mode for entering times. -->
|
||||||
|
<string name="keyboard_mode_time">time</string>
|
||||||
|
<!-- Description of the keyboard mode for entering URLs. -->
|
||||||
|
<string name="keyboard_mode_url">URL</string>
|
||||||
|
|
||||||
<!-- Preferences item for enabling speech input -->
|
<!-- Preferences item for enabling speech input -->
|
||||||
<string name="voice_input">Voice input key</string>
|
<string name="voice_input">Voice input key</string>
|
||||||
|
|
||||||
|
|
|
@ -79,17 +79,25 @@ public final class AccessibilityUtils {
|
||||||
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if accessibility is enabled. Currently, this means
|
||||||
|
* that the kill switch is off and system accessibility is turned on.
|
||||||
|
*
|
||||||
|
* @return {@code true} if accessibility is enabled.
|
||||||
|
*/
|
||||||
|
public boolean isAccessibilityEnabled() {
|
||||||
|
return ENABLE_ACCESSIBILITY && mAccessibilityManager.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if touch exploration is enabled. Currently, this
|
* Returns {@code true} if touch exploration is enabled. Currently, this
|
||||||
* means that the kill switch is off, the device supports touch exploration,
|
* means that the kill switch is off, the device supports touch exploration,
|
||||||
* and a spoken feedback service is turned on.
|
* and system accessibility is turned on.
|
||||||
*
|
*
|
||||||
* @return {@code true} if touch exploration is enabled.
|
* @return {@code true} if touch exploration is enabled.
|
||||||
*/
|
*/
|
||||||
public boolean isTouchExplorationEnabled() {
|
public boolean isTouchExplorationEnabled() {
|
||||||
return ENABLE_ACCESSIBILITY
|
return isAccessibilityEnabled() && mAccessibilityManager.isTouchExplorationEnabled();
|
||||||
&& mAccessibilityManager.isEnabled()
|
|
||||||
&& mAccessibilityManager.isTouchExplorationEnabled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,6 +121,7 @@ public final class AccessibilityUtils {
|
||||||
*
|
*
|
||||||
* @return {@code true} if the device should obscure password characters.
|
* @return {@code true} if the device should obscure password characters.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public boolean shouldObscureInput(final EditorInfo editorInfo) {
|
public boolean shouldObscureInput(final EditorInfo editorInfo) {
|
||||||
if (editorInfo == null) return false;
|
if (editorInfo == null) return false;
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,11 @@ import android.support.v4.view.AccessibilityDelegateCompat;
|
||||||
import android.support.v4.view.ViewCompat;
|
import android.support.v4.view.ViewCompat;
|
||||||
import android.support.v4.view.accessibility.AccessibilityEventCompat;
|
import android.support.v4.view.accessibility.AccessibilityEventCompat;
|
||||||
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
|
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
|
||||||
|
import android.util.SparseIntArray;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewParent;
|
||||||
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.Key;
|
import com.android.inputmethod.keyboard.Key;
|
||||||
import com.android.inputmethod.keyboard.Keyboard;
|
import com.android.inputmethod.keyboard.Keyboard;
|
||||||
|
@ -35,6 +38,21 @@ import com.android.inputmethod.latin.R;
|
||||||
public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat {
|
public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat {
|
||||||
private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy();
|
private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy();
|
||||||
|
|
||||||
|
/** Map of keyboard modes to resource IDs. */
|
||||||
|
private static final SparseIntArray KEYBOARD_MODE_RES_IDS = new SparseIntArray();
|
||||||
|
|
||||||
|
static {
|
||||||
|
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_DATE, R.string.keyboard_mode_date);
|
||||||
|
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_DATETIME, R.string.keyboard_mode_date_time);
|
||||||
|
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_EMAIL, R.string.keyboard_mode_email);
|
||||||
|
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_IM, R.string.keyboard_mode_im);
|
||||||
|
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_NUMBER, R.string.keyboard_mode_number);
|
||||||
|
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_PHONE, R.string.keyboard_mode_phone);
|
||||||
|
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_TEXT, R.string.keyboard_mode_text);
|
||||||
|
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_TIME, R.string.keyboard_mode_time);
|
||||||
|
KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_URL, R.string.keyboard_mode_url);
|
||||||
|
}
|
||||||
|
|
||||||
private InputMethodService mInputMethod;
|
private InputMethodService mInputMethod;
|
||||||
private MainKeyboardView mView;
|
private MainKeyboardView mView;
|
||||||
private AccessibilityEntityProvider mAccessibilityNodeProvider;
|
private AccessibilityEntityProvider mAccessibilityNodeProvider;
|
||||||
|
@ -85,11 +103,75 @@ public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateComp
|
||||||
mAccessibilityNodeProvider.setView(view);
|
mAccessibilityNodeProvider.setView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the keyboard layout changes.
|
||||||
|
* <p>
|
||||||
|
* <b>Note:</b> This method will be called even if accessibility is not
|
||||||
|
* enabled.
|
||||||
|
*/
|
||||||
public void setKeyboard() {
|
public void setKeyboard() {
|
||||||
if (mAccessibilityNodeProvider == null) {
|
if (mAccessibilityNodeProvider != null) {
|
||||||
|
mAccessibilityNodeProvider.setKeyboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since this method is called even when accessibility is off, make sure
|
||||||
|
// to check the state before announcing anything.
|
||||||
|
if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
|
||||||
|
announceKeyboardMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the keyboard is hidden and accessibility is enabled.
|
||||||
|
*/
|
||||||
|
public void onHideWindow() {
|
||||||
|
announceKeyboardHidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Announces which type of keyboard is being displayed. If the keyboard type
|
||||||
|
* is unknown, no announcement is made.
|
||||||
|
*/
|
||||||
|
private void announceKeyboardMode() {
|
||||||
|
final Keyboard keyboard = mView.getKeyboard();
|
||||||
|
final int resId = KEYBOARD_MODE_RES_IDS.get(keyboard.mId.mMode);
|
||||||
|
if (resId == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mAccessibilityNodeProvider.setKeyboard();
|
|
||||||
|
final Context context = mView.getContext();
|
||||||
|
final String keyboardMode = context.getString(resId);
|
||||||
|
final String text = context.getString(R.string.announce_keyboard_mode, keyboardMode);
|
||||||
|
|
||||||
|
sendWindowStateChanged(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Announces that the keyboard has been hidden.
|
||||||
|
*/
|
||||||
|
private void announceKeyboardHidden() {
|
||||||
|
final Context context = mView.getContext();
|
||||||
|
final String text = context.getString(R.string.announce_keyboard_hidden);
|
||||||
|
|
||||||
|
sendWindowStateChanged(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a window state change event with the specified text.
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
*/
|
||||||
|
private void sendWindowStateChanged(final String text) {
|
||||||
|
final AccessibilityEvent stateChange = AccessibilityEvent.obtain(
|
||||||
|
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
|
||||||
|
mView.onInitializeAccessibilityEvent(stateChange);
|
||||||
|
stateChange.getText().add(text);
|
||||||
|
stateChange.setContentDescription(null);
|
||||||
|
|
||||||
|
final ViewParent parent = mView.getParent();
|
||||||
|
if (parent != null) {
|
||||||
|
parent.requestSendAccessibilityEvent(mView, stateChange);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -955,6 +955,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
|
||||||
LatinImeLogger.commit();
|
LatinImeLogger.commit();
|
||||||
mKeyboardSwitcher.onHideWindow();
|
mKeyboardSwitcher.onHideWindow();
|
||||||
|
|
||||||
|
if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
|
||||||
|
AccessibleKeyboardViewProxy.getInstance().onHideWindow();
|
||||||
|
}
|
||||||
|
|
||||||
if (TRACE) Debug.stopMethodTracing();
|
if (TRACE) Debug.stopMethodTracing();
|
||||||
if (mOptionsDialog != null && mOptionsDialog.isShowing()) {
|
if (mOptionsDialog != null && mOptionsDialog.isShowing()) {
|
||||||
mOptionsDialog.dismiss();
|
mOptionsDialog.dismiss();
|
||||||
|
|
Loading…
Reference in New Issue