Merge "Introduce KeyboardSet to hold related KeyboardIds"
This commit is contained in:
commit
cfe264bfee
2 changed files with 144 additions and 80 deletions
134
java/src/com/android/inputmethod/keyboard/KeyboardSet.java
Normal file
134
java/src/com/android/inputmethod/keyboard/KeyboardSet.java
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* 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.util.DisplayMetrics;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.LatinIME;
|
||||||
|
import com.android.inputmethod.latin.R;
|
||||||
|
import com.android.inputmethod.latin.SettingsValues;
|
||||||
|
import com.android.inputmethod.latin.SubtypeSwitcher;
|
||||||
|
import com.android.inputmethod.latin.Utils;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class has a set of {@link KeyboardId}s. 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 {
|
||||||
|
// TODO: Make these KeyboardId private.
|
||||||
|
public final KeyboardId mAlphabetId;
|
||||||
|
public final KeyboardId mSymbolsId;
|
||||||
|
public final KeyboardId mSymbolsShiftedId;
|
||||||
|
|
||||||
|
KeyboardSet(Builder builder) {
|
||||||
|
mAlphabetId = builder.getKeyboardId(false, false);
|
||||||
|
mSymbolsId = builder.getKeyboardId(true, false);
|
||||||
|
mSymbolsShiftedId = builder.getKeyboardId(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private final Resources mResources;
|
||||||
|
private final EditorInfo mEditorInfo;
|
||||||
|
|
||||||
|
private final int mMode;
|
||||||
|
private final boolean mVoiceKeyEnabled;
|
||||||
|
private final boolean mNoSettingsKey;
|
||||||
|
private final boolean mHasSettingsKey;
|
||||||
|
private final int mF2KeyMode;
|
||||||
|
private final boolean mVoiceKeyOnMain;
|
||||||
|
private final Locale mLocale;
|
||||||
|
private final Configuration mConf;
|
||||||
|
private final DisplayMetrics mMetrics;
|
||||||
|
|
||||||
|
public Builder(Context context, EditorInfo editorInfo, SettingsValues settingsValues) {
|
||||||
|
mResources = context.getResources();
|
||||||
|
mEditorInfo = editorInfo;
|
||||||
|
final SubtypeSwitcher subtypeSwitcher = SubtypeSwitcher.getInstance();
|
||||||
|
final String packageName = context.getPackageName();
|
||||||
|
|
||||||
|
mMode = Utils.getKeyboardMode(mEditorInfo);
|
||||||
|
final boolean settingsKeyEnabled = settingsValues.isSettingsKeyEnabled();
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
final boolean noMicrophone = Utils.inPrivateImeOptions(
|
||||||
|
packageName, LatinIME.IME_OPTION_NO_MICROPHONE, editorInfo)
|
||||||
|
|| Utils.inPrivateImeOptions(
|
||||||
|
null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo);
|
||||||
|
mVoiceKeyEnabled = settingsValues.isVoiceKeyEnabled(editorInfo) && !noMicrophone;
|
||||||
|
mVoiceKeyOnMain = settingsValues.isVoiceKeyOnMain();
|
||||||
|
mNoSettingsKey = Utils.inPrivateImeOptions(
|
||||||
|
packageName, LatinIME.IME_OPTION_NO_SETTINGS_KEY, editorInfo);
|
||||||
|
mHasSettingsKey = settingsKeyEnabled && !mNoSettingsKey;
|
||||||
|
mF2KeyMode = getF2KeyMode(settingsKeyEnabled, mNoSettingsKey);
|
||||||
|
final boolean forceAscii = Utils.inPrivateImeOptions(
|
||||||
|
packageName, LatinIME.IME_OPTION_FORCE_ASCII, editorInfo);
|
||||||
|
final boolean asciiCapable = subtypeSwitcher.currentSubtypeContainsExtraValueKey(
|
||||||
|
LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE);
|
||||||
|
mLocale = (forceAscii && !asciiCapable) ? Locale.US : subtypeSwitcher.getInputLocale();
|
||||||
|
mConf = mResources.getConfiguration();
|
||||||
|
mMetrics = mResources.getDisplayMetrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardSet build() {
|
||||||
|
return new KeyboardSet(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardId getKeyboardId(boolean isSymbols, boolean isShift) {
|
||||||
|
final int xmlId = getXmlId(mMode, isSymbols, isShift);
|
||||||
|
final boolean hasShortCutKey = mVoiceKeyEnabled && (isSymbols != mVoiceKeyOnMain);
|
||||||
|
return new KeyboardId(mResources.getResourceEntryName(xmlId), xmlId, mLocale,
|
||||||
|
mConf.orientation, mMetrics.widthPixels, mMode, mEditorInfo, mHasSettingsKey,
|
||||||
|
mF2KeyMode, mNoSettingsKey, mVoiceKeyEnabled, hasShortCutKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getXmlId(int mode, boolean isSymbols, boolean isShift) {
|
||||||
|
switch (mode) {
|
||||||
|
case KeyboardId.MODE_PHONE:
|
||||||
|
return (isSymbols && isShift) ? R.xml.kbd_phone_shift : R.xml.kbd_phone;
|
||||||
|
case KeyboardId.MODE_NUMBER:
|
||||||
|
return R.xml.kbd_number;
|
||||||
|
default:
|
||||||
|
if (isSymbols) {
|
||||||
|
return isShift ? R.xml.kbd_symbols_shift : R.xml.kbd_symbols;
|
||||||
|
}
|
||||||
|
return R.xml.kbd_qwerty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getF2KeyMode(boolean settingsKeyEnabled, boolean noSettingsKey) {
|
||||||
|
if (noSettingsKey) {
|
||||||
|
// Never shows the Settings key
|
||||||
|
return KeyboardId.F2KEY_MODE_SHORTCUT_IME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsKeyEnabled) {
|
||||||
|
return KeyboardId.F2KEY_MODE_SETTINGS;
|
||||||
|
} else {
|
||||||
|
// It should be alright to fall back to the Settings key on 7-inch layouts
|
||||||
|
// even when the Settings key is not explicitly enabled.
|
||||||
|
return KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,9 +18,7 @@ package com.android.inputmethod.keyboard;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextThemeWrapper;
|
import android.view.ContextThemeWrapper;
|
||||||
import android.view.InflateException;
|
import android.view.InflateException;
|
||||||
|
@ -65,14 +63,11 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
|
||||||
private InputView mCurrentInputView;
|
private InputView mCurrentInputView;
|
||||||
private LatinKeyboardView mKeyboardView;
|
private LatinKeyboardView mKeyboardView;
|
||||||
private LatinIME mInputMethodService;
|
private LatinIME mInputMethodService;
|
||||||
private String mPackageName;
|
|
||||||
private Resources mResources;
|
private Resources mResources;
|
||||||
|
|
||||||
private KeyboardState mState;
|
private KeyboardState mState;
|
||||||
|
|
||||||
private KeyboardId mMainKeyboardId;
|
private KeyboardSet mKeyboardSet;
|
||||||
private KeyboardId mSymbolsKeyboardId;
|
|
||||||
private KeyboardId mSymbolsShiftedKeyboardId;
|
|
||||||
|
|
||||||
private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboardCache =
|
private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboardCache =
|
||||||
new HashMap<KeyboardId, SoftReference<LatinKeyboard>>();
|
new HashMap<KeyboardId, SoftReference<LatinKeyboard>>();
|
||||||
|
@ -100,7 +95,6 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
|
||||||
|
|
||||||
private void initInternal(LatinIME ims, SharedPreferences prefs) {
|
private void initInternal(LatinIME ims, SharedPreferences prefs) {
|
||||||
mInputMethodService = ims;
|
mInputMethodService = ims;
|
||||||
mPackageName = ims.getPackageName();
|
|
||||||
mResources = ims.getResources();
|
mResources = ims.getResources();
|
||||||
mPrefs = prefs;
|
mPrefs = prefs;
|
||||||
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
|
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
|
||||||
|
@ -133,20 +127,19 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
|
||||||
|
|
||||||
public void loadKeyboard(EditorInfo editorInfo, SettingsValues settingsValues) {
|
public void loadKeyboard(EditorInfo editorInfo, SettingsValues settingsValues) {
|
||||||
try {
|
try {
|
||||||
mMainKeyboardId = getKeyboardId(editorInfo, false, false, settingsValues);
|
mKeyboardSet = new KeyboardSet.Builder(mInputMethodService, editorInfo, settingsValues)
|
||||||
mSymbolsKeyboardId = getKeyboardId(editorInfo, true, false, settingsValues);
|
.build();
|
||||||
mSymbolsShiftedKeyboardId = getKeyboardId(editorInfo, true, true, settingsValues);
|
|
||||||
mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols),
|
mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols),
|
||||||
hasDistinctMultitouch());
|
hasDistinctMultitouch());
|
||||||
// TODO: Should get rid of this special case handling for Phone Number layouts once we
|
// TODO: Should get rid of this special case handling for Phone Number layouts once we
|
||||||
// have separate layouts with unique KeyboardIds for alphabet and alphabet-shifted
|
// have separate layouts with unique KeyboardIds for alphabet and alphabet-shifted
|
||||||
// respectively.
|
// respectively.
|
||||||
if (mMainKeyboardId.isPhoneKeyboard()) {
|
if (mKeyboardSet.mAlphabetId.isPhoneKeyboard()) {
|
||||||
mState.onToggleAlphabetAndSymbols();
|
mState.onToggleAlphabetAndSymbols();
|
||||||
}
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
Log.w(TAG, "loading keyboard failed: " + mMainKeyboardId, e);
|
Log.w(TAG, "loading keyboard failed: " + mKeyboardSet.mAlphabetId, e);
|
||||||
LatinImeLogger.logOnException(mMainKeyboardId.toString(), e);
|
LatinImeLogger.logOnException(mKeyboardSet.mAlphabetId.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,6 +170,7 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
|
||||||
updateShiftState();
|
updateShiftState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move this method to KeyboardSet.
|
||||||
private LatinKeyboard getKeyboard(KeyboardId id) {
|
private LatinKeyboard getKeyboard(KeyboardId id) {
|
||||||
final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id);
|
final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id);
|
||||||
LatinKeyboard keyboard = (ref == null) ? null : ref.get();
|
LatinKeyboard keyboard = (ref == null) ? null : ref.get();
|
||||||
|
@ -215,55 +209,6 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
|
||||||
return keyboard;
|
return keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeyboardId getKeyboardId(EditorInfo editorInfo, final boolean isSymbols,
|
|
||||||
final boolean isShift, SettingsValues settingsValues) {
|
|
||||||
final int mode = Utils.getKeyboardMode(editorInfo);
|
|
||||||
final int xmlId;
|
|
||||||
switch (mode) {
|
|
||||||
case KeyboardId.MODE_PHONE:
|
|
||||||
xmlId = (isSymbols && isShift) ? R.xml.kbd_phone_shift : R.xml.kbd_phone;
|
|
||||||
break;
|
|
||||||
case KeyboardId.MODE_NUMBER:
|
|
||||||
xmlId = R.xml.kbd_number;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (isSymbols) {
|
|
||||||
xmlId = isShift ? R.xml.kbd_symbols_shift : R.xml.kbd_symbols;
|
|
||||||
} else {
|
|
||||||
xmlId = R.xml.kbd_qwerty;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
final boolean settingsKeyEnabled = settingsValues.isSettingsKeyEnabled();
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
final boolean noMicrophone = Utils.inPrivateImeOptions(
|
|
||||||
mPackageName, LatinIME.IME_OPTION_NO_MICROPHONE, editorInfo)
|
|
||||||
|| Utils.inPrivateImeOptions(
|
|
||||||
null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo);
|
|
||||||
final boolean voiceKeyEnabled = settingsValues.isVoiceKeyEnabled(editorInfo)
|
|
||||||
&& !noMicrophone;
|
|
||||||
final boolean voiceKeyOnMain = settingsValues.isVoiceKeyOnMain();
|
|
||||||
final boolean noSettingsKey = Utils.inPrivateImeOptions(
|
|
||||||
mPackageName, LatinIME.IME_OPTION_NO_SETTINGS_KEY, editorInfo);
|
|
||||||
final boolean hasSettingsKey = settingsKeyEnabled && !noSettingsKey;
|
|
||||||
final int f2KeyMode = getF2KeyMode(settingsKeyEnabled, noSettingsKey);
|
|
||||||
final boolean hasShortcutKey = voiceKeyEnabled && (isSymbols != voiceKeyOnMain);
|
|
||||||
final boolean forceAscii = Utils.inPrivateImeOptions(
|
|
||||||
mPackageName, LatinIME.IME_OPTION_FORCE_ASCII, editorInfo);
|
|
||||||
final boolean asciiCapable = mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(
|
|
||||||
LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE);
|
|
||||||
final Locale locale = (forceAscii && !asciiCapable)
|
|
||||||
? Locale.US : mSubtypeSwitcher.getInputLocale();
|
|
||||||
final Configuration conf = mResources.getConfiguration();
|
|
||||||
final DisplayMetrics dm = mResources.getDisplayMetrics();
|
|
||||||
|
|
||||||
return new KeyboardId(
|
|
||||||
mResources.getResourceEntryName(xmlId), xmlId, locale, conf.orientation,
|
|
||||||
dm.widthPixels, mode, editorInfo, hasSettingsKey, f2KeyMode, noSettingsKey,
|
|
||||||
voiceKeyEnabled, hasShortcutKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAlphabetMode() {
|
public boolean isAlphabetMode() {
|
||||||
final Keyboard keyboard = getLatinKeyboard();
|
final Keyboard keyboard = getLatinKeyboard();
|
||||||
return keyboard != null && keyboard.mId.isAlphabetKeyboard();
|
return keyboard != null && keyboard.mId.isAlphabetKeyboard();
|
||||||
|
@ -393,19 +338,19 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
@Override
|
@Override
|
||||||
public void setSymbolsKeyboard() {
|
public void setSymbolsKeyboard() {
|
||||||
setKeyboard(getKeyboard(mSymbolsKeyboardId));
|
setKeyboard(getKeyboard(mKeyboardSet.mSymbolsId));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
@Override
|
@Override
|
||||||
public void setAlphabetKeyboard() {
|
public void setAlphabetKeyboard() {
|
||||||
setKeyboard(getKeyboard(mMainKeyboardId));
|
setKeyboard(getKeyboard(mKeyboardSet.mAlphabetId));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
@Override
|
@Override
|
||||||
public void setSymbolsShiftedKeyboard() {
|
public void setSymbolsShiftedKeyboard() {
|
||||||
final Keyboard keyboard = getKeyboard(mSymbolsShiftedKeyboardId);
|
final Keyboard keyboard = getKeyboard(mKeyboardSet.mSymbolsShiftedId);
|
||||||
setKeyboard(keyboard);
|
setKeyboard(keyboard);
|
||||||
// TODO: Remove this logic once we introduce initial keyboard shift state attribute.
|
// TODO: Remove this logic once we introduce initial keyboard shift state attribute.
|
||||||
// Symbol shift keyboard may have a shift key that has a caps lock style indicator (a.k.a.
|
// Symbol shift keyboard may have a shift key that has a caps lock style indicator (a.k.a.
|
||||||
|
@ -518,19 +463,4 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getF2KeyMode(boolean settingsKeyEnabled, boolean noSettingsKey) {
|
|
||||||
if (noSettingsKey) {
|
|
||||||
// Never shows the Settings key
|
|
||||||
return KeyboardId.F2KEY_MODE_SHORTCUT_IME;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settingsKeyEnabled) {
|
|
||||||
return KeyboardId.F2KEY_MODE_SETTINGS;
|
|
||||||
} else {
|
|
||||||
// It should be alright to fall back to the Settings key on 7-inch layouts
|
|
||||||
// even when the Settings key is not explicitly enabled.
|
|
||||||
return KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue