diff options
author | 2024-12-16 21:45:41 -0500 | |
---|---|---|
committer | 2025-01-11 14:17:35 -0500 | |
commit | e9a0e66716dab4dd3184d009d8920de1961efdfa (patch) | |
tree | 02dcc096643d74645bf28459c2834c3d4a2ad7f2 /java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java | |
parent | fb3b9360d70596d7e921de8bf7d3ca99564a077e (diff) | |
download | latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.tar.gz latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.tar.xz latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.zip |
Rename to Kelar Keyboard (org.kelar.inputmethod.latin)
Diffstat (limited to 'java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java')
-rw-r--r-- | java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java | 365 |
1 files changed, 0 insertions, 365 deletions
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java deleted file mode 100644 index bbda9f8e2..000000000 --- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java +++ /dev/null @@ -1,365 +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.content.res.Resources; -import android.text.TextUtils; -import android.util.Log; -import android.util.SparseIntArray; -import android.view.inputmethod.EditorInfo; - -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 com.android.inputmethod.latin.common.Constants; -import com.android.inputmethod.latin.common.StringUtils; - -import java.util.Locale; - -final class KeyCodeDescriptionMapper { - private static final String TAG = KeyCodeDescriptionMapper.class.getSimpleName(); - private static final String SPOKEN_LETTER_RESOURCE_NAME_FORMAT = "spoken_accented_letter_%04X"; - private static final String SPOKEN_SYMBOL_RESOURCE_NAME_FORMAT = "spoken_symbol_%04X"; - private static final String SPOKEN_EMOJI_RESOURCE_NAME_FORMAT = "spoken_emoji_%04X"; - private static final String SPOKEN_EMOTICON_RESOURCE_NAME_PREFIX = "spoken_emoticon"; - private static final String SPOKEN_EMOTICON_CODE_POINT_FORMAT = "_%02X"; - - // 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 KeyCodeDescriptionMapper sInstance = new KeyCodeDescriptionMapper(); - - public static KeyCodeDescriptionMapper getInstance() { - return sInstance; - } - - // Sparse array of spoken description resource IDs indexed by key codes - private final SparseIntArray mKeyCodeMap = new SparseIntArray(); - - private KeyCodeDescriptionMapper() { - // Special non-character codes defined in Keyboard - mKeyCodeMap.put(Constants.CODE_SPACE, R.string.spoken_description_space); - mKeyCodeMap.put(Constants.CODE_DELETE, R.string.spoken_description_delete); - mKeyCodeMap.put(Constants.CODE_ENTER, R.string.spoken_description_return); - mKeyCodeMap.put(Constants.CODE_SETTINGS, R.string.spoken_description_settings); - mKeyCodeMap.put(Constants.CODE_SHIFT, R.string.spoken_description_shift); - mKeyCodeMap.put(Constants.CODE_SHORTCUT, R.string.spoken_description_mic); - mKeyCodeMap.put(Constants.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol); - mKeyCodeMap.put(Constants.CODE_TAB, R.string.spoken_description_tab); - mKeyCodeMap.put(Constants.CODE_LANGUAGE_SWITCH, - R.string.spoken_description_language_switch); - mKeyCodeMap.put(Constants.CODE_ACTION_NEXT, R.string.spoken_description_action_next); - mKeyCodeMap.put(Constants.CODE_ACTION_PREVIOUS, - R.string.spoken_description_action_previous); - mKeyCodeMap.put(Constants.CODE_EMOJI, R.string.spoken_description_emoji); - // Because the upper-case and lower-case mappings of the following letters is depending on - // the locale, the upper case descriptions should be defined here. The lower case - // descriptions are handled in {@link #getSpokenLetterDescriptionId(Context,int)}. - // U+0049: "I" LATIN CAPITAL LETTER I - // U+0069: "i" LATIN SMALL LETTER I - // U+0130: "İ" LATIN CAPITAL LETTER I WITH DOT ABOVE - // U+0131: "ı" LATIN SMALL LETTER DOTLESS I - mKeyCodeMap.put(0x0049, R.string.spoken_letter_0049); - mKeyCodeMap.put(0x0130, R.string.spoken_letter_0130); - } - - /** - * Returns the localized description of the action performed by a specified - * key based on the current keyboard state. - * - * @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. - * @param shouldObscure {@true} if text (e.g. non-control) characters should be obscured. - * @return a character sequence describing the action performed by pressing the key - */ - public String getDescriptionForKey(final Context context, final Keyboard keyboard, - final Key key, final boolean shouldObscure) { - final int code = key.getCode(); - - if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) { - final String description = getDescriptionForSwitchAlphaSymbol(context, keyboard); - if (description != null) { - return description; - } - } - - if (code == Constants.CODE_SHIFT) { - return getDescriptionForShiftKey(context, keyboard); - } - - if (code == Constants.CODE_ENTER) { - // The following function returns the correct description in all action and - // regular enter cases, taking care of all modes. - return getDescriptionForActionKey(context, keyboard, key); - } - - if (code == Constants.CODE_OUTPUT_TEXT) { - final String outputText = key.getOutputText(); - final String description = getSpokenEmoticonDescription(context, outputText); - return TextUtils.isEmpty(description) ? outputText : description; - } - - // Just attempt to speak the description. - if (code != Constants.CODE_UNSPECIFIED) { - // If the key description should be obscured, now is the time to do it. - final boolean isDefinedNonCtrl = Character.isDefined(code) - && !Character.isISOControl(code); - if (shouldObscure && isDefinedNonCtrl) { - return context.getString(OBSCURED_KEY_RES_ID); - } - final String description = getDescriptionForCodePoint(context, code); - if (description != null) { - return description; - } - if (!TextUtils.isEmpty(key.getLabel())) { - return key.getLabel(); - } - return context.getString(R.string.spoken_description_unknown); - } - 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 static String getDescriptionForSwitchAlphaSymbol(final Context context, - final Keyboard keyboard) { - final KeyboardId keyboardId = keyboard.mId; - final int elementId = keyboardId.mElementId; - final int resId; - - switch (elementId) { - case KeyboardId.ELEMENT_ALPHABET: - case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED: - case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED: - case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED: - case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED: - resId = R.string.spoken_description_to_symbol; - break; - case KeyboardId.ELEMENT_SYMBOLS: - case KeyboardId.ELEMENT_SYMBOLS_SHIFTED: - resId = R.string.spoken_description_to_alpha; - break; - case KeyboardId.ELEMENT_PHONE: - resId = R.string.spoken_description_to_symbol; - break; - case KeyboardId.ELEMENT_PHONE_SYMBOLS: - resId = R.string.spoken_description_to_numeric; - break; - default: - Log.e(TAG, "Missing description for keyboard element ID:" + elementId); - return null; - } - return context.getString(resId); - } - - /** - * Returns a context-sensitive description of the "Shift" key. - * - * @param context The package's context. - * @param keyboard The keyboard on which the key resides. - * @return A context-sensitive description of the "Shift" key. - */ - private static String getDescriptionForShiftKey(final Context context, - final Keyboard keyboard) { - final KeyboardId keyboardId = keyboard.mId; - final int elementId = keyboardId.mElementId; - final int resId; - - switch (elementId) { - case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED: - case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED: - resId = R.string.spoken_description_caps_lock; - break; - case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED: - case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED: - resId = R.string.spoken_description_shift_shifted; - break; - case KeyboardId.ELEMENT_SYMBOLS: - resId = R.string.spoken_description_symbols_shift; - break; - case KeyboardId.ELEMENT_SYMBOLS_SHIFTED: - resId = R.string.spoken_description_symbols_shift_shifted; - break; - default: - resId = R.string.spoken_description_shift; - } - return context.getString(resId); - } - - /** - * Returns a context-sensitive description of the "Enter" action key. - * - * @param context The package's context. - * @param keyboard The keyboard on which the key resides. - * @param key The key to describe. - * @return Returns a context-sensitive description of the "Enter" action key. - */ - private static String getDescriptionForActionKey(final Context context, final Keyboard keyboard, - final Key key) { - final KeyboardId keyboardId = keyboard.mId; - final int actionId = keyboardId.imeAction(); - final int resId; - - // Always use the label, if available. - if (!TextUtils.isEmpty(key.getLabel())) { - return key.getLabel().trim(); - } - - // Otherwise, use the action ID. - switch (actionId) { - case EditorInfo.IME_ACTION_SEARCH: - resId = R.string.spoken_description_search; - break; - case EditorInfo.IME_ACTION_GO: - resId = R.string.label_go_key; - break; - case EditorInfo.IME_ACTION_SEND: - resId = R.string.label_send_key; - break; - case EditorInfo.IME_ACTION_NEXT: - resId = R.string.label_next_key; - break; - case EditorInfo.IME_ACTION_DONE: - resId = R.string.label_done_key; - break; - case EditorInfo.IME_ACTION_PREVIOUS: - resId = R.string.label_previous_key; - break; - default: - resId = R.string.spoken_description_return; - } - return context.getString(resId); - } - - /** - * Returns a localized character sequence describing what will happen when - * the specified key is pressed based on its key code point. - * - * @param context The package's context. - * @param codePoint The code point from which to obtain a description. - * @return a character sequence describing the code point. - */ - public String getDescriptionForCodePoint(final Context context, final int codePoint) { - // If the key description should be obscured, now is the time to do it. - final int index = mKeyCodeMap.indexOfKey(codePoint); - if (index >= 0) { - return context.getString(mKeyCodeMap.valueAt(index)); - } - final String accentedLetter = getSpokenAccentedLetterDescription(context, codePoint); - if (accentedLetter != null) { - return accentedLetter; - } - // Here, <code>code</code> may be a base (non-accented) letter. - final String unsupportedSymbol = getSpokenSymbolDescription(context, codePoint); - if (unsupportedSymbol != null) { - return unsupportedSymbol; - } - final String emojiDescription = getSpokenEmojiDescription(context, codePoint); - if (emojiDescription != null) { - return emojiDescription; - } - if (Character.isDefined(codePoint) && !Character.isISOControl(codePoint)) { - return StringUtils.newSingleCodePointString(codePoint); - } - return null; - } - - // TODO: Remove this method once TTS supports those accented letters' verbalization. - private String getSpokenAccentedLetterDescription(final Context context, final int code) { - final boolean isUpperCase = Character.isUpperCase(code); - final int baseCode = isUpperCase ? Character.toLowerCase(code) : code; - final int baseIndex = mKeyCodeMap.indexOfKey(baseCode); - final int resId = (baseIndex >= 0) ? mKeyCodeMap.valueAt(baseIndex) - : getSpokenDescriptionId(context, baseCode, SPOKEN_LETTER_RESOURCE_NAME_FORMAT); - if (resId == 0) { - return null; - } - final String spokenText = context.getString(resId); - return isUpperCase ? context.getString(R.string.spoken_description_upper_case, spokenText) - : spokenText; - } - - // TODO: Remove this method once TTS supports those symbols' verbalization. - private String getSpokenSymbolDescription(final Context context, final int code) { - final int resId = getSpokenDescriptionId(context, code, SPOKEN_SYMBOL_RESOURCE_NAME_FORMAT); - if (resId == 0) { - return null; - } - final String spokenText = context.getString(resId); - if (!TextUtils.isEmpty(spokenText)) { - return spokenText; - } - // If a translated description is empty, fall back to unknown symbol description. - return context.getString(R.string.spoken_symbol_unknown); - } - - // TODO: Remove this method once TTS supports emoji verbalization. - private String getSpokenEmojiDescription(final Context context, final int code) { - final int resId = getSpokenDescriptionId(context, code, SPOKEN_EMOJI_RESOURCE_NAME_FORMAT); - if (resId == 0) { - return null; - } - final String spokenText = context.getString(resId); - if (!TextUtils.isEmpty(spokenText)) { - return spokenText; - } - // If a translated description is empty, fall back to unknown emoji description. - return context.getString(R.string.spoken_emoji_unknown); - } - - private 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(); - // Note that the resource package name may differ from the context package name. - final String resourcePackageName = resources.getResourcePackageName( - R.string.spoken_description_unknown); - final int resId = resources.getIdentifier(resourceName, "string", resourcePackageName); - if (resId != 0) { - mKeyCodeMap.append(code, resId); - } - return resId; - } - - // TODO: Remove this method once TTS supports emoticon verbalization. - private static String getSpokenEmoticonDescription(final Context context, - final String outputText) { - final StringBuilder sb = new StringBuilder(SPOKEN_EMOTICON_RESOURCE_NAME_PREFIX); - final int textLength = outputText.length(); - for (int index = 0; index < textLength; index = outputText.offsetByCodePoints(index, 1)) { - final int codePoint = outputText.codePointAt(index); - sb.append(String.format(Locale.ROOT, SPOKEN_EMOTICON_CODE_POINT_FORMAT, codePoint)); - } - final String resourceName = sb.toString(); - final Resources resources = context.getResources(); - // Note that the resource package name may differ from the context package name. - final String resourcePackageName = resources.getResourcePackageName( - R.string.spoken_description_unknown); - final int resId = resources.getIdentifier(resourceName, "string", resourcePackageName); - return (resId == 0) ? null : resources.getString(resId); - } -} |