aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2011-06-22 11:50:28 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-06-22 11:50:28 -0700
commit8521781fd72784d23cf7ae11459c6cccf958aa83 (patch)
tree39e13685283b24475d64a580a7fd55efdeaacb51 /java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
parentae706548d67644005cac87c62bb80d33c1601b9f (diff)
parent5ac4638f999db4fea8a9e24171dbceb640a10858 (diff)
downloadlatinime-8521781fd72784d23cf7ae11459c6cccf958aa83.tar.gz
latinime-8521781fd72784d23cf7ae11459c6cccf958aa83.tar.xz
latinime-8521781fd72784d23cf7ae11459c6cccf958aa83.zip
Merge "Added support for touch exploration to Latin IME."
Diffstat (limited to 'java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java')
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java226
1 files changed, 226 insertions, 0 deletions
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
new file mode 100644
index 000000000..154f4af91
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -0,0 +1,226 @@
+/*
+ * 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.content.SharedPreferences;
+import android.text.TextUtils;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.latin.R;
+
+import java.util.HashMap;
+
+public class KeyCodeDescriptionMapper {
+ private static KeyCodeDescriptionMapper sInstance = new KeyCodeDescriptionMapper();
+
+ // Map of key labels to spoken description resource IDs
+ private final HashMap<CharSequence, Integer> mKeyLabelMap;
+
+ // Map of key codes to spoken description resource IDs
+ private final HashMap<Integer, Integer> mKeyCodeMap;
+
+ // Map of shifted key codes to spoken description resource IDs
+ private final HashMap<Integer, Integer> mShiftedKeyCodeMap;
+
+ // Map of shift-locked key codes to spoken description resource IDs
+ private final HashMap<Integer, Integer> mShiftLockedKeyCodeMap;
+
+ public static void init(Context context, SharedPreferences prefs) {
+ sInstance.initInternal(context, prefs);
+ }
+
+ public static KeyCodeDescriptionMapper getInstance() {
+ return sInstance;
+ }
+
+ private KeyCodeDescriptionMapper() {
+ mKeyLabelMap = new HashMap<CharSequence, Integer>();
+ mKeyCodeMap = new HashMap<Integer, Integer>();
+ mShiftedKeyCodeMap = new HashMap<Integer, Integer>();
+ mShiftLockedKeyCodeMap = new HashMap<Integer, Integer>();
+ }
+
+ private void initInternal(Context context, SharedPreferences prefs) {
+ // Manual label substitutions for key labels with no string resource
+ mKeyLabelMap.put(":-)", R.string.spoken_description_smiley);
+
+ // Symbols that most TTS engines can't speak
+ mKeyCodeMap.put((int) '.', R.string.spoken_description_period);
+ mKeyCodeMap.put((int) ',', R.string.spoken_description_comma);
+ mKeyCodeMap.put((int) '(', R.string.spoken_description_left_parenthesis);
+ mKeyCodeMap.put((int) ')', R.string.spoken_description_right_parenthesis);
+ mKeyCodeMap.put((int) ':', R.string.spoken_description_colon);
+ mKeyCodeMap.put((int) ';', R.string.spoken_description_semicolon);
+ mKeyCodeMap.put((int) '!', R.string.spoken_description_exclamation_mark);
+ mKeyCodeMap.put((int) '?', R.string.spoken_description_question_mark);
+ mKeyCodeMap.put((int) '\"', R.string.spoken_description_double_quote);
+ mKeyCodeMap.put((int) '\'', R.string.spoken_description_single_quote);
+ mKeyCodeMap.put((int) '*', R.string.spoken_description_star);
+ mKeyCodeMap.put((int) '#', R.string.spoken_description_pound);
+ mKeyCodeMap.put((int) ' ', R.string.spoken_description_space);
+
+ // Non-ASCII symbols (must use escape codes!)
+ mKeyCodeMap.put((int) '\u2022', R.string.spoken_description_dot);
+ mKeyCodeMap.put((int) '\u221A', R.string.spoken_description_square_root);
+ mKeyCodeMap.put((int) '\u03C0', R.string.spoken_description_pi);
+ mKeyCodeMap.put((int) '\u0394', R.string.spoken_description_delta);
+ mKeyCodeMap.put((int) '\u2122', R.string.spoken_description_trademark);
+ mKeyCodeMap.put((int) '\u2105', R.string.spoken_description_care_of);
+ mKeyCodeMap.put((int) '\u2026', R.string.spoken_description_ellipsis);
+ mKeyCodeMap.put((int) '\u201E', R.string.spoken_description_low_double_quote);
+
+ // Special non-character codes defined in Keyboard
+ mKeyCodeMap.put(Keyboard.CODE_DELETE, R.string.spoken_description_delete);
+ mKeyCodeMap.put(Keyboard.CODE_ENTER, R.string.spoken_description_return);
+ mKeyCodeMap.put(Keyboard.CODE_SETTINGS, R.string.spoken_description_settings);
+ mKeyCodeMap.put(Keyboard.CODE_SHIFT, R.string.spoken_description_shift);
+ mKeyCodeMap.put(Keyboard.CODE_SHORTCUT, R.string.spoken_description_mic);
+ mKeyCodeMap.put(Keyboard.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol);
+ mKeyCodeMap.put(Keyboard.CODE_TAB, R.string.spoken_description_tab);
+
+ // Shifted versions of non-character codes defined in Keyboard
+ mShiftedKeyCodeMap.put(Keyboard.CODE_SHIFT, R.string.spoken_description_shift_shifted);
+
+ // Shift-locked versions of non-character codes defined in Keyboard
+ mShiftLockedKeyCodeMap.put(Keyboard.CODE_SHIFT, R.string.spoken_description_caps_lock);
+ }
+
+ /**
+ * Returns the localized description of the action performed by a specified
+ * key based on the current keyboard state.
+ * <p>
+ * The order of precedence for key descriptions is:
+ * <ol>
+ * <li>Manually-defined based on the key label</li>
+ * <li>Automatic or manually-defined based on the key code</li>
+ * <li>Automatically based on the key label</li>
+ * <li>{code null} for keys with no label or key code defined</li>
+ * </p>
+ *
+ * @param context The package's context.
+ * @param keyboard The keyboard on which the key resides.
+ * @param key The key from which to obtain a description.
+ * @return a character sequence describing the action performed by pressing
+ * the key
+ */
+ public CharSequence getDescriptionForKey(Context context, Keyboard keyboard, Key key) {
+ if (key.mCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ final CharSequence description = getDescriptionForSwitchAlphaSymbol(context, keyboard);
+ if (description != null)
+ return description;
+ }
+
+ if (!TextUtils.isEmpty(key.mLabel)) {
+ final String label = key.mLabel.toString().trim();
+
+ if (mKeyLabelMap.containsKey(label)) {
+ return context.getString(mKeyLabelMap.get(label));
+ } else if (label.length() == 1
+ || (keyboard.isManualTemporaryUpperCase() && !TextUtils
+ .isEmpty(key.mHintLetter))) {
+ return getDescriptionForKeyCode(context, keyboard, key);
+ } else {
+ return label;
+ }
+ } else if (key.mCode != Keyboard.CODE_DUMMY) {
+ return getDescriptionForKeyCode(context, keyboard, key);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns a context-specific description for the CODE_SWITCH_ALPHA_SYMBOL
+ * key or {@code null} if there is not a description provided for the
+ * current keyboard context.
+ *
+ * @param context The package's context.
+ * @param keyboard The keyboard on which the key resides.
+ * @return a character sequence describing the action performed by pressing
+ * the key
+ */
+ private CharSequence getDescriptionForSwitchAlphaSymbol(Context context, Keyboard keyboard) {
+ final KeyboardId id = keyboard.mId;
+
+ if (id.isAlphabetKeyboard()) {
+ return context.getString(R.string.spoken_description_to_symbol);
+ } else if (id.isSymbolsKeyboard()) {
+ return context.getString(R.string.spoken_description_to_alpha);
+ } else if (id.isPhoneSymbolsKeyboard()) {
+ return context.getString(R.string.spoken_description_to_numeric);
+ } else if (id.isPhoneKeyboard()) {
+ return context.getString(R.string.spoken_description_to_symbol);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the keycode for the specified key given the current keyboard
+ * state.
+ *
+ * @param keyboard The keyboard on which the key resides.
+ * @param key The key from which to obtain a key code.
+ * @return the key code for the specified key
+ */
+ private int getCorrectKeyCode(Keyboard keyboard, Key key) {
+ if (keyboard.isManualTemporaryUpperCase() && !TextUtils.isEmpty(key.mHintLetter)) {
+ return key.mHintLetter.charAt(0);
+ } else {
+ return key.mCode;
+ }
+ }
+
+ /**
+ * Returns a localized character sequence describing what will happen when
+ * the specified key is pressed based on its key code.
+ * <p>
+ * The order of precedence for key code descriptions is:
+ * <ol>
+ * <li>Manually-defined shift-locked description</li>
+ * <li>Manually-defined shifted description</li>
+ * <li>Manually-defined normal description</li>
+ * <li>Automatic based on the character represented by the key code</li>
+ * <li>Fall-back for undefined or control characters</li>
+ * </ol>
+ * </p>
+ *
+ * @param context The package's context.
+ * @param keyboard The keyboard on which the key resides.
+ * @param key The key from which to obtain a description.
+ * @return a character sequence describing the action performed by pressing
+ * the key
+ */
+ private CharSequence getDescriptionForKeyCode(Context context, Keyboard keyboard, Key key) {
+ final int code = getCorrectKeyCode(keyboard, key);
+
+ if (keyboard.isShiftLocked() && mShiftLockedKeyCodeMap.containsKey(code)) {
+ return context.getString(mShiftLockedKeyCodeMap.get(code));
+ } else if (keyboard.isShiftedOrShiftLocked() && mShiftedKeyCodeMap.containsKey(code)) {
+ return context.getString(mShiftedKeyCodeMap.get(code));
+ } else if (mKeyCodeMap.containsKey(code)) {
+ return context.getString(mKeyCodeMap.get(code));
+ } else if (Character.isDefined(code) && !Character.isISOControl(code)) {
+ return Character.toString((char) code);
+ } else {
+ return context.getString(R.string.spoken_description_unknown, code);
+ }
+ }
+}