am 305778b5: Support accessibility TalkBack in emoji palette
* commit '305778b53a5e7c865cae4010e657d00bb9bf5075': Support accessibility TalkBack in emoji palettemain
commit
b52665bb0b
|
@ -17,6 +17,7 @@
|
||||||
package com.android.inputmethod.accessibility;
|
package com.android.inputmethod.accessibility;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
|
@ -27,21 +28,18 @@ import com.android.inputmethod.keyboard.Keyboard;
|
||||||
import com.android.inputmethod.keyboard.KeyboardId;
|
import com.android.inputmethod.keyboard.KeyboardId;
|
||||||
import com.android.inputmethod.latin.Constants;
|
import com.android.inputmethod.latin.Constants;
|
||||||
import com.android.inputmethod.latin.R;
|
import com.android.inputmethod.latin.R;
|
||||||
import com.android.inputmethod.latin.utils.CollectionUtils;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.Locale;
|
||||||
|
|
||||||
public final class KeyCodeDescriptionMapper {
|
public final class KeyCodeDescriptionMapper {
|
||||||
private static final String TAG = KeyCodeDescriptionMapper.class.getSimpleName();
|
private static final String TAG = KeyCodeDescriptionMapper.class.getSimpleName();
|
||||||
|
private static final String SPOKEN_EMOJI_RESOURCE_NAME_FORMAT = "spoken_emoji_%04X";
|
||||||
|
|
||||||
// The resource ID of the string spoken for obscured keys
|
// The resource ID of the string spoken for obscured keys
|
||||||
private static final int OBSCURED_KEY_RES_ID = R.string.spoken_description_dot;
|
private static final int OBSCURED_KEY_RES_ID = R.string.spoken_description_dot;
|
||||||
|
|
||||||
private static KeyCodeDescriptionMapper sInstance = new KeyCodeDescriptionMapper();
|
private static KeyCodeDescriptionMapper sInstance = new KeyCodeDescriptionMapper();
|
||||||
|
|
||||||
// Map of key labels to spoken description resource IDs
|
|
||||||
private final HashMap<CharSequence, Integer> mKeyLabelMap = CollectionUtils.newHashMap();
|
|
||||||
|
|
||||||
// Sparse array of spoken description resource IDs indexed by key codes
|
// Sparse array of spoken description resource IDs indexed by key codes
|
||||||
private final SparseIntArray mKeyCodeMap;
|
private final SparseIntArray mKeyCodeMap;
|
||||||
|
|
||||||
|
@ -114,17 +112,12 @@ public final class KeyCodeDescriptionMapper {
|
||||||
return getDescriptionForActionKey(context, keyboard, key);
|
return getDescriptionForActionKey(context, keyboard, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(key.getLabel())) {
|
if (code == Constants.CODE_OUTPUT_TEXT) {
|
||||||
final String label = key.getLabel().trim();
|
return key.getOutputText();
|
||||||
|
|
||||||
// First, attempt to map the label to a pre-defined description.
|
|
||||||
if (mKeyLabelMap.containsKey(label)) {
|
|
||||||
return context.getString(mKeyLabelMap.get(label));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just attempt to speak the description.
|
// Just attempt to speak the description.
|
||||||
if (key.getCode() != Constants.CODE_UNSPECIFIED) {
|
if (code != Constants.CODE_UNSPECIFIED) {
|
||||||
return getDescriptionForKeyCode(context, keyboard, key, shouldObscure);
|
return getDescriptionForKeyCode(context, keyboard, key, shouldObscure);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -139,7 +132,7 @@ public final class KeyCodeDescriptionMapper {
|
||||||
* @param keyboard The keyboard on which the key resides.
|
* @param keyboard The keyboard on which the key resides.
|
||||||
* @return a character sequence describing the action performed by pressing the key
|
* @return a character sequence describing the action performed by pressing the key
|
||||||
*/
|
*/
|
||||||
private String getDescriptionForSwitchAlphaSymbol(final Context context,
|
private static String getDescriptionForSwitchAlphaSymbol(final Context context,
|
||||||
final Keyboard keyboard) {
|
final Keyboard keyboard) {
|
||||||
final KeyboardId keyboardId = keyboard.mId;
|
final KeyboardId keyboardId = keyboard.mId;
|
||||||
final int elementId = keyboardId.mElementId;
|
final int elementId = keyboardId.mElementId;
|
||||||
|
@ -177,7 +170,8 @@ public final class KeyCodeDescriptionMapper {
|
||||||
* @param keyboard The keyboard on which the key resides.
|
* @param keyboard The keyboard on which the key resides.
|
||||||
* @return A context-sensitive description of the "Shift" key.
|
* @return A context-sensitive description of the "Shift" key.
|
||||||
*/
|
*/
|
||||||
private String getDescriptionForShiftKey(final Context context, final Keyboard keyboard) {
|
private static String getDescriptionForShiftKey(final Context context,
|
||||||
|
final Keyboard keyboard) {
|
||||||
final KeyboardId keyboardId = keyboard.mId;
|
final KeyboardId keyboardId = keyboard.mId;
|
||||||
final int elementId = keyboardId.mElementId;
|
final int elementId = keyboardId.mElementId;
|
||||||
final int resId;
|
final int resId;
|
||||||
|
@ -211,7 +205,7 @@ public final class KeyCodeDescriptionMapper {
|
||||||
* @param key The key to describe.
|
* @param key The key to describe.
|
||||||
* @return Returns a context-sensitive description of the "Enter" action key.
|
* @return Returns a context-sensitive description of the "Enter" action key.
|
||||||
*/
|
*/
|
||||||
private String getDescriptionForActionKey(final Context context, final Keyboard keyboard,
|
private static String getDescriptionForActionKey(final Context context, final Keyboard keyboard,
|
||||||
final Key key) {
|
final Key key) {
|
||||||
final KeyboardId keyboardId = keyboard.mId;
|
final KeyboardId keyboardId = keyboard.mId;
|
||||||
final int actionId = keyboardId.imeAction();
|
final int actionId = keyboardId.imeAction();
|
||||||
|
@ -280,6 +274,13 @@ public final class KeyCodeDescriptionMapper {
|
||||||
if (mKeyCodeMap.indexOfKey(code) >= 0) {
|
if (mKeyCodeMap.indexOfKey(code) >= 0) {
|
||||||
return context.getString(mKeyCodeMap.get(code));
|
return context.getString(mKeyCodeMap.get(code));
|
||||||
}
|
}
|
||||||
|
final int spokenEmojiId = getSpokenDescriptionId(
|
||||||
|
context, code, SPOKEN_EMOJI_RESOURCE_NAME_FORMAT);
|
||||||
|
if (spokenEmojiId != 0) {
|
||||||
|
final String spokenEmoji = context.getString(spokenEmojiId);
|
||||||
|
mKeyCodeMap.append(code, spokenEmojiId);
|
||||||
|
return spokenEmoji;
|
||||||
|
}
|
||||||
if (isDefinedNonCtrl) {
|
if (isDefinedNonCtrl) {
|
||||||
return Character.toString((char) code);
|
return Character.toString((char) code);
|
||||||
}
|
}
|
||||||
|
@ -288,4 +289,13 @@ public final class KeyCodeDescriptionMapper {
|
||||||
}
|
}
|
||||||
return context.getString(R.string.spoken_description_unknown, code);
|
return context.getString(R.string.spoken_description_unknown, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int getSpokenDescriptionId(final Context context, final int code,
|
||||||
|
final String resourceNameFormat) {
|
||||||
|
final String resourceName = String.format(Locale.ROOT, resourceNameFormat, code);
|
||||||
|
final Resources resources = context.getResources();
|
||||||
|
final String packageName = resources.getResourcePackageName(
|
||||||
|
R.string.spoken_description_unknown);
|
||||||
|
return resources.getIdentifier(resourceName, "string", packageName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ import android.util.AttributeSet;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import com.android.inputmethod.accessibility.AccessibilityUtils;
|
||||||
|
import com.android.inputmethod.accessibility.KeyboardAccessibilityDelegate;
|
||||||
import com.android.inputmethod.keyboard.Key;
|
import com.android.inputmethod.keyboard.Key;
|
||||||
import com.android.inputmethod.keyboard.KeyDetector;
|
import com.android.inputmethod.keyboard.KeyDetector;
|
||||||
import com.android.inputmethod.keyboard.Keyboard;
|
import com.android.inputmethod.keyboard.Keyboard;
|
||||||
|
@ -53,6 +55,7 @@ final class EmojiPageKeyboardView extends KeyboardView implements
|
||||||
private OnKeyEventListener mListener = EMPTY_LISTENER;
|
private OnKeyEventListener mListener = EMPTY_LISTENER;
|
||||||
private final KeyDetector mKeyDetector = new KeyDetector();
|
private final KeyDetector mKeyDetector = new KeyDetector();
|
||||||
private final GestureDetector mGestureDetector;
|
private final GestureDetector mGestureDetector;
|
||||||
|
private final KeyboardAccessibilityDelegate<EmojiPageKeyboardView> mAccessibilityDelegate;
|
||||||
|
|
||||||
public EmojiPageKeyboardView(final Context context, final AttributeSet attrs) {
|
public EmojiPageKeyboardView(final Context context, final AttributeSet attrs) {
|
||||||
this(context, attrs, R.attr.keyboardViewStyle);
|
this(context, attrs, R.attr.keyboardViewStyle);
|
||||||
|
@ -64,6 +67,7 @@ final class EmojiPageKeyboardView extends KeyboardView implements
|
||||||
mGestureDetector = new GestureDetector(context, this);
|
mGestureDetector = new GestureDetector(context, this);
|
||||||
mGestureDetector.setIsLongpressEnabled(false /* isLongpressEnabled */);
|
mGestureDetector.setIsLongpressEnabled(false /* isLongpressEnabled */);
|
||||||
mHandler = new Handler();
|
mHandler = new Handler();
|
||||||
|
mAccessibilityDelegate = new KeyboardAccessibilityDelegate<>(this, mKeyDetector);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnKeyEventListener(final OnKeyEventListener listener) {
|
public void setOnKeyEventListener(final OnKeyEventListener listener) {
|
||||||
|
@ -79,6 +83,15 @@ final class EmojiPageKeyboardView extends KeyboardView implements
|
||||||
mKeyDetector.setKeyboard(keyboard, 0 /* correctionX */, 0 /* correctionY */);
|
mKeyDetector.setKeyboard(keyboard, 0 /* correctionX */, 0 /* correctionY */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchHoverEvent(final MotionEvent event) {
|
||||||
|
if (!AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
|
||||||
|
// Reflection doesn't support calling superclass methods.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return mAccessibilityDelegate.dispatchHoverEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue