summaryrefslogtreecommitdiff
path: root/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
diff options
context:
space:
mode:
authorTadashi G. Takaoka <takaoka@google.com>2012-04-04 14:30:42 +0900
committerTadashi G. Takaoka <takaoka@google.com>2012-04-05 17:25:15 +0900
commit11d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3 (patch)
treed508dde42b24796c16e809e62a6fda9434489271 /java/src/com/android/inputmethod/keyboard/KeyboardSet.java
parentcb389ef0d6e6eec737c249e1729c2a2cdc30f341 (diff)
Use keyboardSet extra value of subtype to specify layout type
Change-Id: Ice1f345a08a8d760e3b847c885c4072e3e142c97
Diffstat (limited to 'java/src/com/android/inputmethod/keyboard/KeyboardSet.java')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSet.java407
1 files changed, 0 insertions, 407 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
deleted file mode 100644
index f9b6b72c7..000000000
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
+++ /dev/null
@@ -1,407 +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.keyboard;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.text.InputType;
-import android.util.Log;
-import android.util.Xml;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodSubtype;
-
-import com.android.inputmethod.compat.EditorInfoCompatUtils;
-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.RunInLocale;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.StringUtils;
-import com.android.inputmethod.latin.SubtypeLocale;
-import com.android.inputmethod.latin.XmlParseUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.lang.ref.SoftReference;
-import java.util.HashMap;
-import java.util.Locale;
-
-/**
- * This class represents a set of keyboards. Each of them represents a different keyboard
- * specific to a keyboard state, such as alphabet, symbols, and so on. Layouts in the same
- * {@link KeyboardSet} are related to each other.
- * A {@link KeyboardSet} needs to be created for each {@link android.view.inputmethod.EditorInfo}.
- */
-public class KeyboardSet {
- private static final String TAG = KeyboardSet.class.getSimpleName();
- private static final boolean DEBUG_CACHE = LatinImeLogger.sDBG;
-
- private static final String TAG_KEYBOARD_SET = "KeyboardSet";
- private static final String TAG_ELEMENT = "Element";
-
- private final Context mContext;
- private final Params mParams;
-
- private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache =
- new HashMap<KeyboardId, SoftReference<Keyboard>>();
- private static final KeysCache sKeysCache = new KeysCache();
-
- public static class KeyboardSetException extends RuntimeException {
- public final KeyboardId mKeyboardId;
-
- public KeyboardSetException(Throwable cause, KeyboardId keyboardId) {
- super(cause);
- mKeyboardId = keyboardId;
- }
- }
-
- public static class KeysCache {
- private final HashMap<Key, Key> mMap;
-
- public KeysCache() {
- mMap = new HashMap<Key, Key>();
- }
-
- public void clear() {
- mMap.clear();
- }
-
- public Key get(Key key) {
- final Key existingKey = mMap.get(key);
- if (existingKey != null) {
- // Reuse the existing element that equals to "key" without adding "key" to the map.
- return existingKey;
- }
- mMap.put(key, key);
- return key;
- }
- }
-
- static class Params {
- int mMode;
- EditorInfo mEditorInfo;
- boolean mTouchPositionCorrectionEnabled;
- boolean mVoiceKeyEnabled;
- boolean mVoiceKeyOnMain;
- boolean mNoSettingsKey;
- boolean mLanguageSwitchKeyEnabled;
- Locale mLocale;
- int mOrientation;
- int mWidth;
- // KeyboardSet element id to element's parameters map.
- final HashMap<Integer, ElementParams> mKeyboardSetElementIdToParamsMap =
- new HashMap<Integer, ElementParams>();
-
- static class ElementParams {
- int mKeyboardXmlId;
- boolean mProximityCharsCorrectionEnabled;
- }
- }
-
- public static void clearKeyboardCache() {
- sKeyboardCache.clear();
- sKeysCache.clear();
- }
-
- private KeyboardSet(Context context, Params params) {
- mContext = context;
- mParams = params;
- }
-
- public Keyboard getKeyboard(int baseKeyboardSetElementId) {
- final int keyboardSetElementId;
- switch (mParams.mMode) {
- case KeyboardId.MODE_PHONE:
- if (baseKeyboardSetElementId == KeyboardId.ELEMENT_SYMBOLS) {
- keyboardSetElementId = KeyboardId.ELEMENT_PHONE_SYMBOLS;
- } else {
- keyboardSetElementId = KeyboardId.ELEMENT_PHONE;
- }
- break;
- case KeyboardId.MODE_NUMBER:
- case KeyboardId.MODE_DATE:
- case KeyboardId.MODE_TIME:
- case KeyboardId.MODE_DATETIME:
- keyboardSetElementId = KeyboardId.ELEMENT_NUMBER;
- break;
- default:
- keyboardSetElementId = baseKeyboardSetElementId;
- break;
- }
-
- ElementParams elementParams = mParams.mKeyboardSetElementIdToParamsMap.get(
- keyboardSetElementId);
- if (elementParams == null) {
- elementParams = mParams.mKeyboardSetElementIdToParamsMap.get(
- KeyboardId.ELEMENT_ALPHABET);
- }
- final KeyboardId id = getKeyboardId(keyboardSetElementId);
- try {
- return getKeyboard(mContext, elementParams, id);
- } catch (RuntimeException e) {
- throw new KeyboardSetException(e, id);
- }
- }
-
- private Keyboard getKeyboard(Context context, ElementParams elementParams,
- final KeyboardId id) {
- final SoftReference<Keyboard> ref = sKeyboardCache.get(id);
- Keyboard keyboard = (ref == null) ? null : ref.get();
- if (keyboard == null) {
- final Keyboard.Builder<Keyboard.Params> builder =
- new Keyboard.Builder<Keyboard.Params>(mContext, new Keyboard.Params());
- if (id.isAlphabetKeyboard()) {
- builder.setAutoGenerate(sKeysCache);
- }
- final int keyboardXmlId = elementParams.mKeyboardXmlId;
- final RunInLocale<Void> job = new RunInLocale<Void>() {
- @Override
- protected Void job(Resources res) {
- builder.load(keyboardXmlId, id);
- return null;
- }
- };
- job.runInLocale(context.getResources(), id.mLocale);
- builder.setTouchPositionCorrectionEnabled(mParams.mTouchPositionCorrectionEnabled);
- builder.setProximityCharsCorrectionEnabled(
- elementParams.mProximityCharsCorrectionEnabled);
- keyboard = builder.build();
- sKeyboardCache.put(id, new SoftReference<Keyboard>(keyboard));
-
- if (DEBUG_CACHE) {
- Log.d(TAG, "keyboard cache size=" + sKeyboardCache.size() + ": "
- + ((ref == null) ? "LOAD" : "GCed") + " id=" + id);
- }
- } else if (DEBUG_CACHE) {
- Log.d(TAG, "keyboard cache size=" + sKeyboardCache.size() + ": HIT id=" + id);
- }
-
- return keyboard;
- }
-
- // Note: The keyboard for each locale, shift state, and mode are represented as KeyboardSet
- // element id that is a key in keyboard_set.xml. Also that file specifies which XML layout
- // should be used for each keyboard. The KeyboardId is an internal key for Keyboard object.
- private KeyboardId getKeyboardId(int keyboardSetElementId) {
- final Params params = mParams;
- final boolean isSymbols = (keyboardSetElementId == KeyboardId.ELEMENT_SYMBOLS
- || keyboardSetElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED);
- final boolean noLanguage = params.mLocale.getLanguage().equals(SubtypeLocale.NO_LANGUAGE);
- final boolean voiceKeyEnabled = params.mVoiceKeyEnabled && !noLanguage;
- final boolean hasShortcutKey = voiceKeyEnabled && (isSymbols != params.mVoiceKeyOnMain);
- return new KeyboardId(keyboardSetElementId, params.mLocale, params.mOrientation,
- params.mWidth, params.mMode, params.mEditorInfo, params.mNoSettingsKey,
- voiceKeyEnabled, hasShortcutKey, params.mLanguageSwitchKeyEnabled);
- }
-
- public static class Builder {
- private final Context mContext;
- private final String mPackageName;
- private final Resources mResources;
- private final EditorInfo mEditorInfo;
-
- private final Params mParams = new Params();
-
- private static final EditorInfo EMPTY_EDITOR_INFO = new EditorInfo();
-
- public Builder(Context context, EditorInfo editorInfo) {
- mContext = context;
- mPackageName = context.getPackageName();
- mResources = context.getResources();
- mEditorInfo = editorInfo;
- final Params params = mParams;
-
- params.mMode = getKeyboardMode(editorInfo);
- params.mEditorInfo = (editorInfo != null) ? editorInfo : EMPTY_EDITOR_INFO;
- params.mNoSettingsKey = StringUtils.inPrivateImeOptions(
- mPackageName, LatinIME.IME_OPTION_NO_SETTINGS_KEY, mEditorInfo);
- }
-
- public Builder setScreenGeometry(int orientation, int widthPixels) {
- mParams.mOrientation = orientation;
- mParams.mWidth = widthPixels;
- return this;
- }
-
- public Builder setSubtype(InputMethodSubtype subtype) {
- final Locale inputLocale = SubtypeLocale.getSubtypeLocale(subtype);
- final boolean asciiCapable = subtype.containsExtraValueKey(
- LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE);
- final boolean deprecatedForceAscii = StringUtils.inPrivateImeOptions(
- mPackageName, LatinIME.IME_OPTION_FORCE_ASCII, mEditorInfo);
- final boolean forceAscii = EditorInfoCompatUtils.hasFlagForceAscii(
- mParams.mEditorInfo.imeOptions)
- || deprecatedForceAscii;
- mParams.mLocale = (forceAscii && !asciiCapable)
- ? SubtypeLocale.LOCALE_NO_LANGUAGE_QWERTY : inputLocale;
- return this;
- }
-
- public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain,
- boolean languageSwitchKeyEnabled) {
- @SuppressWarnings("deprecation")
- final boolean deprecatedNoMicrophone = StringUtils.inPrivateImeOptions(
- null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo);
- final boolean noMicrophone = StringUtils.inPrivateImeOptions(
- mPackageName, LatinIME.IME_OPTION_NO_MICROPHONE, mEditorInfo)
- || deprecatedNoMicrophone;
- mParams.mVoiceKeyEnabled = voiceKeyEnabled && !noMicrophone;
- mParams.mVoiceKeyOnMain = voiceKeyOnMain;
- mParams.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
- return this;
- }
-
- public void setTouchPositionCorrectionEnabled(boolean enabled) {
- mParams.mTouchPositionCorrectionEnabled = enabled;
- }
-
- public KeyboardSet build() {
- if (mParams.mOrientation == Configuration.ORIENTATION_UNDEFINED)
- throw new RuntimeException("Screen geometry is not specified");
- if (mParams.mLocale == null)
- throw new RuntimeException("KeyboardSet subtype is not specified");
-
- final RunInLocale<Void> job = new RunInLocale<Void>() {
- @Override
- protected Void job(Resources res) {
- try {
- parseKeyboardSet(res, R.xml.keyboard_set);
- } catch (Exception e) {
- throw new RuntimeException(e.getMessage() + " in "
- + res.getResourceName(R.xml.keyboard_set)
- + " of locale " + mParams.mLocale);
- }
- return null;
- }
- };
- job.runInLocale(mResources, mParams.mLocale);
- return new KeyboardSet(mContext, mParams);
- }
-
- private void parseKeyboardSet(Resources res, int resId) throws XmlPullParserException,
- IOException {
- final XmlResourceParser parser = res.getXml(resId);
- try {
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_KEYBOARD_SET.equals(tag)) {
- parseKeyboardSetContent(parser);
- } else {
- throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET);
- }
- }
- }
- } finally {
- parser.close();
- }
- }
-
- private void parseKeyboardSetContent(XmlPullParser parser) throws XmlPullParserException,
- IOException {
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_ELEMENT.equals(tag)) {
- parseKeyboardSetElement(parser);
- } else {
- throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET);
- }
- } else if (event == XmlPullParser.END_TAG) {
- final String tag = parser.getName();
- if (TAG_KEYBOARD_SET.equals(tag)) {
- break;
- } else {
- throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEYBOARD_SET);
- }
- }
- }
- }
-
- private void parseKeyboardSetElement(XmlPullParser parser) throws XmlPullParserException,
- IOException {
- final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.KeyboardSet_Element);
- try {
- XmlParseUtils.checkAttributeExists(a,
- R.styleable.KeyboardSet_Element_elementName, "elementName",
- TAG_ELEMENT, parser);
- XmlParseUtils.checkAttributeExists(a,
- R.styleable.KeyboardSet_Element_elementKeyboard, "elementKeyboard",
- TAG_ELEMENT, parser);
- XmlParseUtils.checkEndTag(TAG_ELEMENT, parser);
-
- final ElementParams elementParams = new ElementParams();
- final int elementName = a.getInt(
- R.styleable.KeyboardSet_Element_elementName, 0);
- elementParams.mKeyboardXmlId = a.getResourceId(
- R.styleable.KeyboardSet_Element_elementKeyboard, 0);
- elementParams.mProximityCharsCorrectionEnabled = a.getBoolean(
- R.styleable.KeyboardSet_Element_enableProximityCharsCorrection, false);
- mParams.mKeyboardSetElementIdToParamsMap.put(elementName, elementParams);
- } finally {
- a.recycle();
- }
- }
-
- private static int getKeyboardMode(EditorInfo editorInfo) {
- if (editorInfo == null)
- return KeyboardId.MODE_TEXT;
-
- final int inputType = editorInfo.inputType;
- final int variation = inputType & InputType.TYPE_MASK_VARIATION;
-
- switch (inputType & InputType.TYPE_MASK_CLASS) {
- case InputType.TYPE_CLASS_NUMBER:
- return KeyboardId.MODE_NUMBER;
- case InputType.TYPE_CLASS_DATETIME:
- switch (variation) {
- case InputType.TYPE_DATETIME_VARIATION_DATE:
- return KeyboardId.MODE_DATE;
- case InputType.TYPE_DATETIME_VARIATION_TIME:
- return KeyboardId.MODE_TIME;
- default: // InputType.TYPE_DATETIME_VARIATION_NORMAL
- return KeyboardId.MODE_DATETIME;
- }
- case InputType.TYPE_CLASS_PHONE:
- return KeyboardId.MODE_PHONE;
- case InputType.TYPE_CLASS_TEXT:
- if (InputTypeUtils.isEmailVariation(variation)) {
- return KeyboardId.MODE_EMAIL;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
- return KeyboardId.MODE_URL;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) {
- return KeyboardId.MODE_IM;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
- return KeyboardId.MODE_TEXT;
- } else {
- return KeyboardId.MODE_TEXT;
- }
- default:
- return KeyboardId.MODE_TEXT;
- }
- }
- }
-}