am 1fdb8f31: Define shortcuts for toggling IME layouts.

* commit '1fdb8f31562eeef78167585a878eb0450310036b':
  Define shortcuts for toggling IME layouts.
main
Dan Zivkovic 2015-10-16 21:56:08 +00:00 committed by Android Git Automerger
commit 1194ad63ee
4 changed files with 234 additions and 92 deletions

View File

@ -91,4 +91,22 @@
<fraction name="config_emoji_keyboard_row_height">33%p</fraction> <fraction name="config_emoji_keyboard_row_height">33%p</fraction>
<fraction name="config_emoji_keyboard_key_letter_size">68%p</fraction> <fraction name="config_emoji_keyboard_key_letter_size">68%p</fraction>
<integer name="config_emoji_keyboard_max_page_key_count">21</integer> <integer name="config_emoji_keyboard_max_page_key_count">21</integer>
<!-- Key codes of hardware keys that can be used to toggle the Emoji layout.
Each array defines a comma-separated tuple containing:
1. Key code constant from android.view.KeyEvent
2. Meta mask (if any) from android.view.KeyEvent
Used in EmojiAltPhysicalKeyDetector and KeyboardSwitcher. -->
<string-array name="keyboard_switcher_emoji" translatable="false">
<item>57,16</item> <!-- KeyEvent.KEYCODE_ALT_LEFT , KeyEvent.META_ALT_LEFT_ON -->
</string-array>
<!-- Key codes of hardware keys that can be used to toggle the Symbols (Shifted) layout.
Each array defines a comma-separated tuple containing:
1. Key code constant from android.view.KeyEvent
2. Meta mask (if any) from android.view.KeyEvent
Used in EmojiAltPhysicalKeyDetector and KeyboardSwitcher. -->
<string-array name="keyboard_switcher_symbols_shifted" translatable="false">
<item>58,32</item> <!-- KeyEvent.KEYCODE_ALT_RIGHT , KeyEvent.META_ALT_RIGHT_ON -->
</string-array>
</resources> </resources>

View File

@ -44,6 +44,8 @@ import com.android.inputmethod.latin.utils.RecapitalizeStatus;
import com.android.inputmethod.latin.utils.ResourceUtils; import com.android.inputmethod.latin.utils.ResourceUtils;
import com.android.inputmethod.latin.utils.ScriptUtils; import com.android.inputmethod.latin.utils.ScriptUtils;
import javax.annotation.Nonnull;
public final class KeyboardSwitcher implements KeyboardState.SwitchActions { public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private static final String TAG = KeyboardSwitcher.class.getSimpleName(); private static final String TAG = KeyboardSwitcher.class.getSimpleName();
@ -139,15 +141,18 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
} }
} }
private void setKeyboard(final Keyboard keyboard) { private void setKeyboard(
@Nonnull final int keyboardId,
@Nonnull final KeyboardSwitchState toggleState) {
// Make {@link MainKeyboardView} visible and hide {@link EmojiPalettesView}. // Make {@link MainKeyboardView} visible and hide {@link EmojiPalettesView}.
final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent(); final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent();
setMainKeyboardFrame(currentSettingsValues); setMainKeyboardFrame(currentSettingsValues, toggleState);
// TODO: pass this object to setKeyboard instead of getting the current values. // TODO: pass this object to setKeyboard instead of getting the current values.
final MainKeyboardView keyboardView = mKeyboardView; final MainKeyboardView keyboardView = mKeyboardView;
final Keyboard oldKeyboard = keyboardView.getKeyboard(); final Keyboard oldKeyboard = keyboardView.getKeyboard();
keyboardView.setKeyboard(keyboard); final Keyboard newKeyboard = mKeyboardLayoutSet.getKeyboard(keyboardId);
mCurrentInputView.setKeyboardTopPadding(keyboard.mTopPadding); keyboardView.setKeyboard(newKeyboard);
mCurrentInputView.setKeyboardTopPadding(newKeyboard.mTopPadding);
keyboardView.setKeyPreviewPopupEnabled( keyboardView.setKeyPreviewPopupEnabled(
currentSettingsValues.mKeyPreviewPopupOn, currentSettingsValues.mKeyPreviewPopupOn,
currentSettingsValues.mKeyPreviewPopupDismissDelay); currentSettingsValues.mKeyPreviewPopupDismissDelay);
@ -161,9 +166,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
currentSettingsValues.mKeyPreviewDismissDuration); currentSettingsValues.mKeyPreviewDismissDuration);
keyboardView.updateShortcutKey(mRichImm.isShortcutImeReady()); keyboardView.updateShortcutKey(mRichImm.isShortcutImeReady());
final boolean subtypeChanged = (oldKeyboard == null) final boolean subtypeChanged = (oldKeyboard == null)
|| !keyboard.mId.mSubtype.equals(oldKeyboard.mId.mSubtype); || !newKeyboard.mId.mSubtype.equals(oldKeyboard.mId.mSubtype);
final int languageOnSpacebarFormatType = LanguageOnSpacebarUtils final int languageOnSpacebarFormatType = LanguageOnSpacebarUtils
.getLanguageOnSpacebarFormatType(keyboard.mId.mSubtype); .getLanguageOnSpacebarFormatType(newKeyboard.mId.mSubtype);
final boolean hasMultipleEnabledIMEsOrSubtypes = mRichImm final boolean hasMultipleEnabledIMEsOrSubtypes = mRichImm
.hasMultipleEnabledIMEsOrSubtypes(true /* shouldIncludeAuxiliarySubtypes */); .hasMultipleEnabledIMEsOrSubtypes(true /* shouldIncludeAuxiliarySubtypes */);
keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, languageOnSpacebarFormatType, keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, languageOnSpacebarFormatType,
@ -205,7 +210,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
if (DEBUG_ACTION) { if (DEBUG_ACTION) {
Log.d(TAG, "setAlphabetKeyboard"); Log.d(TAG, "setAlphabetKeyboard");
} }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET)); setKeyboard(KeyboardId.ELEMENT_ALPHABET, KeyboardSwitchState.OTHER);
} }
// Implements {@link KeyboardState.SwitchActions}. // Implements {@link KeyboardState.SwitchActions}.
@ -214,7 +219,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
if (DEBUG_ACTION) { if (DEBUG_ACTION) {
Log.d(TAG, "setAlphabetManualShiftedKeyboard"); Log.d(TAG, "setAlphabetManualShiftedKeyboard");
} }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED)); setKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED, KeyboardSwitchState.OTHER);
} }
// Implements {@link KeyboardState.SwitchActions}. // Implements {@link KeyboardState.SwitchActions}.
@ -223,7 +228,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
if (DEBUG_ACTION) { if (DEBUG_ACTION) {
Log.d(TAG, "setAlphabetAutomaticShiftedKeyboard"); Log.d(TAG, "setAlphabetAutomaticShiftedKeyboard");
} }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED)); setKeyboard(KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardSwitchState.OTHER);
} }
// Implements {@link KeyboardState.SwitchActions}. // Implements {@link KeyboardState.SwitchActions}.
@ -232,7 +237,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
if (DEBUG_ACTION) { if (DEBUG_ACTION) {
Log.d(TAG, "setAlphabetShiftLockedKeyboard"); Log.d(TAG, "setAlphabetShiftLockedKeyboard");
} }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED)); setKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED, KeyboardSwitchState.OTHER);
} }
// Implements {@link KeyboardState.SwitchActions}. // Implements {@link KeyboardState.SwitchActions}.
@ -241,7 +246,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
if (DEBUG_ACTION) { if (DEBUG_ACTION) {
Log.d(TAG, "setAlphabetShiftLockShiftedKeyboard"); Log.d(TAG, "setAlphabetShiftLockShiftedKeyboard");
} }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED)); setKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED, KeyboardSwitchState.OTHER);
} }
// Implements {@link KeyboardState.SwitchActions}. // Implements {@link KeyboardState.SwitchActions}.
@ -250,11 +255,29 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
if (DEBUG_ACTION) { if (DEBUG_ACTION) {
Log.d(TAG, "setSymbolsKeyboard"); Log.d(TAG, "setSymbolsKeyboard");
} }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS)); setKeyboard(KeyboardId.ELEMENT_SYMBOLS, KeyboardSwitchState.OTHER);
} }
private void setMainKeyboardFrame(final SettingsValues settingsValues) { // Implements {@link KeyboardState.SwitchActions}.
final int visibility = settingsValues.mHasHardwareKeyboard ? View.GONE : View.VISIBLE; @Override
public void setSymbolsShiftedKeyboard() {
if (DEBUG_ACTION) {
Log.d(TAG, "setSymbolsShiftedKeyboard");
}
setKeyboard(KeyboardId.ELEMENT_SYMBOLS_SHIFTED, KeyboardSwitchState.SYMBOLS_SHIFTED);
}
public boolean isImeSuppressedByHardwareKeyboard(
@Nonnull final SettingsValues settingsValues,
@Nonnull final KeyboardSwitchState toggleState) {
return settingsValues.mHasHardwareKeyboard && toggleState == KeyboardSwitchState.HIDDEN;
}
private void setMainKeyboardFrame(
@Nonnull final SettingsValues settingsValues,
@Nonnull final KeyboardSwitchState toggleState) {
final int visibility = isImeSuppressedByHardwareKeyboard(settingsValues, toggleState)
? View.GONE : View.VISIBLE;
mKeyboardView.setVisibility(visibility); mKeyboardView.setVisibility(visibility);
// The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}. // The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
// @see #getVisibleKeyboardView() and // @see #getVisibleKeyboardView() and
@ -282,24 +305,55 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mEmojiPalettesView.setVisibility(View.VISIBLE); mEmojiPalettesView.setVisibility(View.VISIBLE);
} }
public void onToggleEmojiKeyboard() { public enum KeyboardSwitchState {
final boolean needsToLoadKeyboard = (mKeyboardLayoutSet == null); HIDDEN(-1),
if (needsToLoadKeyboard || !isShowingEmojiPalettes()) { SYMBOLS_SHIFTED(KeyboardId.ELEMENT_SYMBOLS_SHIFTED),
mLatinIME.startShowingInputView(needsToLoadKeyboard); EMOJI(KeyboardId.ELEMENT_EMOJI_RECENTS),
setEmojiKeyboard(); OTHER(-1);
} else {
mLatinIME.stopShowingInputView(); final int mKeyboardId;
setAlphabetKeyboard();
KeyboardSwitchState(int keyboardId) {
mKeyboardId = keyboardId;
} }
} }
// Implements {@link KeyboardState.SwitchActions}. public KeyboardSwitchState getKeyboardSwitchState() {
@Override boolean hidden = !isShowingEmojiPalettes()
public void setSymbolsShiftedKeyboard() { && (mKeyboardLayoutSet == null
if (DEBUG_ACTION) { || mKeyboardView == null
Log.d(TAG, "setSymbolsShiftedKeyboard"); || !mKeyboardView.isShown());
KeyboardSwitchState state;
if (hidden) {
return KeyboardSwitchState.HIDDEN;
} else if (isShowingEmojiPalettes()) {
return KeyboardSwitchState.EMOJI;
} else if (isShowingKeyboardId(KeyboardId.ELEMENT_SYMBOLS_SHIFTED)) {
return KeyboardSwitchState.SYMBOLS_SHIFTED;
}
return KeyboardSwitchState.OTHER;
}
public void onToggleKeyboard(@Nonnull final KeyboardSwitchState toggleState) {
KeyboardSwitchState currentState = getKeyboardSwitchState();
Log.w(TAG, "onToggleKeyboard() : Current = " + currentState + " : Toggle = " + toggleState);
if (currentState == toggleState) {
mLatinIME.stopShowingInputView();
mLatinIME.hideWindow();
setAlphabetKeyboard();
} else {
mLatinIME.startShowingInputView(true);
if (toggleState == KeyboardSwitchState.EMOJI) {
setEmojiKeyboard();
} else {
mEmojiPalettesView.stopEmojiPalettes();
mEmojiPalettesView.setVisibility(View.GONE);
mMainKeyboardFrame.setVisibility(View.VISIBLE);
mKeyboardView.setVisibility(View.VISIBLE);
setKeyboard(toggleState.mKeyboardId, toggleState);
}
} }
setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS_SHIFTED));
} }
// Future method for requesting an updating to the shift state. // Future method for requesting an updating to the shift state.
@ -355,6 +409,19 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mState.onEvent(event, currentAutoCapsState, currentRecapitalizeState); mState.onEvent(event, currentAutoCapsState, currentRecapitalizeState);
} }
public boolean isShowingKeyboardId(@Nonnull int... keyboardIds) {
if (mKeyboardView == null || !mKeyboardView.isShown()) {
return false;
}
int activeKeyboardId = mKeyboardView.getKeyboard().mId.mElementId;
for (int keyboardId : keyboardIds) {
if (activeKeyboardId == keyboardId) {
return true;
}
}
return false;
}
public boolean isShowingEmojiPalettes() { public boolean isShowingEmojiPalettes() {
return mEmojiPalettesView != null && mEmojiPalettesView.isShown(); return mEmojiPalettesView != null && mEmojiPalettesView.isShown();
} }

View File

@ -16,88 +16,140 @@
package com.android.inputmethod.latin; package com.android.inputmethod.latin;
import android.content.res.Resources;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.Settings;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
/** /**
* A class for detecting Emoji-Alt physical key. * A class for detecting Emoji-Alt physical key.
*/ */
final class EmojiAltPhysicalKeyDetector { final class EmojiAltPhysicalKeyDetector {
private static final String TAG = "EmojiAltPhysicalKeyDetector"; private static final String TAG = "EmojiAltPhysicalKeyDetector";
private final RichInputConnection mRichInputConnection; private final Map<Integer, Integer> mEmojiSwitcherMap;
private final Map<Integer, Integer> mSymbolsShiftedSwitcherMap;
private final Map<Integer, Integer> mCombinedSwitcherMap;
// True if the Alt key has been used as a modifier. In this case the Alt key up isn't // Set of keys codes that have been used as modifiers.
// recognized as an emoji key. private Set<Integer> mActiveModifiers;
private boolean mAltHasBeenUsedAsAModifier;
public EmojiAltPhysicalKeyDetector(final RichInputConnection richInputConnection) { public EmojiAltPhysicalKeyDetector(@Nonnull final Resources resources) {
mRichInputConnection = richInputConnection; mEmojiSwitcherMap = parseSwitchDefinition(resources, R.array.keyboard_switcher_emoji);
mSymbolsShiftedSwitcherMap = parseSwitchDefinition(
resources, R.array.keyboard_switcher_symbols_shifted);
mCombinedSwitcherMap = new HashMap<>();
mCombinedSwitcherMap.putAll(mEmojiSwitcherMap);
mCombinedSwitcherMap.putAll(mSymbolsShiftedSwitcherMap);
mActiveModifiers = new HashSet<>();
}
private static Map<Integer, Integer> parseSwitchDefinition(
@Nonnull final Resources resources,
final int resourceId) {
final Map<Integer, Integer> definition = new HashMap<>();
final String name = resources.getResourceEntryName(resourceId);
final String[] values = resources.getStringArray(resourceId);
for (int i = 0; values != null && i < values.length; i++) {
String[] valuePair = values[i].split(",");
if (valuePair.length != 2) {
Log.w(TAG, "Expected 2 integers in " + name + "[" + i + "] : " + values[i]);
}
try {
definition.put(Integer.parseInt(valuePair[0]), Integer.parseInt(valuePair[1]));
} catch (NumberFormatException e) {
Log.w(TAG, "Failed to parse " + name + "[" + i + "] : " + values[i], e);
}
}
return definition;
} }
/** /**
* Record a down key event. * Determine whether an up key event came from a mapped modifier key.
* @param keyEvent a down key event. *
*/
public void onKeyDown(final KeyEvent keyEvent) {
if (isAltKey(keyEvent)) {
mAltHasBeenUsedAsAModifier = false;
}
if (containsAltModifier(keyEvent)) {
mAltHasBeenUsedAsAModifier = true;
}
}
/**
* Determine whether an up key event is a special key up or not.
* @param keyEvent an up key event. * @param keyEvent an up key event.
*/ */
public void onKeyUp(final KeyEvent keyEvent) { public void onKeyUp(@Nonnull final KeyEvent keyEvent) {
Log.d(TAG, "onKeyUp() : " + keyEvent);
if (!Settings.getInstance().getCurrent().mEnableEmojiAltPhysicalKey) {
// The feature is disabled.
Log.d(TAG, "onKeyUp() : Disabled");
return;
}
if (keyEvent.isCanceled()) { if (keyEvent.isCanceled()) {
// This key up event was a part of key combinations and should be ignored. // This key up event was a part of key combinations and should be ignored.
Log.d(TAG, "onKeyUp() : Canceled");
return; return;
} }
if (!isAltKey(keyEvent)) { final Integer mappedModifier = getMappedModifier(keyEvent);
mAltHasBeenUsedAsAModifier |= containsAltModifier(keyEvent); if (mappedModifier != null) {
// If the key was modified by a mapped key, then ignore the next time
// the same modifier key comes up.
Log.d(TAG, "onKeyUp() : Using Modifier: " + mappedModifier);
mActiveModifiers.add(mappedModifier);
return; return;
} }
if (containsAltModifier(keyEvent)) {
mAltHasBeenUsedAsAModifier = true;
return;
}
if (!Settings.getInstance().getCurrent().mEnableEmojiAltPhysicalKey) {
return;
}
if (mAltHasBeenUsedAsAModifier) {
return;
}
onEmojiAltKeyDetected();
}
private static void onEmojiAltKeyDetected() {
KeyboardSwitcher.getInstance().onToggleEmojiKeyboard();
}
private static boolean isAltKey(final KeyEvent keyEvent) {
final int keyCode = keyEvent.getKeyCode(); final int keyCode = keyEvent.getKeyCode();
return keyCode == KeyEvent.KEYCODE_ALT_LEFT || keyCode == KeyEvent.KEYCODE_ALT_RIGHT; if (mActiveModifiers.contains(keyCode)) {
// Used as a modifier, not a standalone key press.
Log.d(TAG, "onKeyUp() : Used as Modifier: " + keyCode);
mActiveModifiers.remove(keyCode);
return;
}
if (!isMappedKeyCode(keyEvent)) {
// Nothing special about this key.
Log.d(TAG, "onKeyUp() : Not Mapped: " + keyCode);
return;
}
final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
if (mEmojiSwitcherMap.keySet().contains(keyCode)) {
switcher.onToggleKeyboard(KeyboardSwitcher.KeyboardSwitchState.EMOJI);
} else if (mSymbolsShiftedSwitcherMap.keySet().contains(keyCode)) {
switcher.onToggleKeyboard(KeyboardSwitcher.KeyboardSwitchState.SYMBOLS_SHIFTED);
} else {
Log.w(TAG, "Cannot toggle on keyCode: " + keyCode);
}
} }
private static boolean containsAltModifier(final KeyEvent keyEvent) { /**
final int metaState = keyEvent.getMetaState(); * @param keyEvent pressed key event
// TODO: Support multiple keyboards. Take device id into account. * @return true iff the user pressed a mapped modifier key.
switch (keyEvent.getKeyCode()) { */
case KeyEvent.KEYCODE_ALT_LEFT: private boolean isMappedKeyCode(@Nonnull final KeyEvent keyEvent) {
// Return true if Left-Alt is pressed with Right-Alt pressed. return mCombinedSwitcherMap.get(keyEvent.getKeyCode()) != null;
return (metaState & KeyEvent.META_ALT_RIGHT_ON) != 0;
case KeyEvent.KEYCODE_ALT_RIGHT:
// Return true if Right-Alt is pressed with Left-Alt pressed.
return (metaState & KeyEvent.META_ALT_LEFT_ON) != 0;
default:
return (metaState & (KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON)) != 0;
} }
/**
* @param keyEvent pressed key event
* @return the mapped modifier used with this key opress, if any.
*/
private Integer getMappedModifier(@Nonnull final KeyEvent keyEvent) {
final int keyCode = keyEvent.getKeyCode();
final int metaState = keyEvent.getMetaState();
for (int mappedKeyCode : mCombinedSwitcherMap.keySet()) {
if (keyCode == mappedKeyCode) {
Log.d(TAG, "getMappedModifier() : KeyCode = MappedKeyCode = " + mappedKeyCode);
continue;
}
final Integer mappedMeta = mCombinedSwitcherMap.get(mappedKeyCode);
if (mappedMeta == null || mappedMeta.intValue() == -1) {
continue;
}
if ((metaState & mappedMeta) != 0) {
Log.d(TAG, "getMappedModifier() : MetaState(" + metaState
+ ") contains MappedMeta(" + mappedMeta + ")");
return mappedKeyCode;
}
}
return null;
} }
} }

View File

@ -142,8 +142,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private RichInputMethodManager mRichImm; private RichInputMethodManager mRichImm;
@UsedForTesting final KeyboardSwitcher mKeyboardSwitcher; @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeState mSubtypeState = new SubtypeState(); private final SubtypeState mSubtypeState = new SubtypeState();
private final EmojiAltPhysicalKeyDetector mEmojiAltPhysicalKeyDetector = private EmojiAltPhysicalKeyDetector mEmojiAltPhysicalKeyDetector;
new EmojiAltPhysicalKeyDetector(mInputLogic.mConnection);
private StatsUtilsManager mStatsUtilsManager; private StatsUtilsManager mStatsUtilsManager;
// Working variable for {@link #startShowingInputView()} and // Working variable for {@link #startShowingInputView()} and
// {@link #onEvaluateInputViewShown()}. // {@link #onEvaluateInputViewShown()}.
@ -702,6 +701,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mInputLogic.recycle(); mInputLogic.recycle();
} }
private boolean isImeSuppressedByHardwareKeyboard() {
final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance();
return switcher.isImeSuppressedByHardwareKeyboard(
mSettings.getCurrent(), switcher.getKeyboardSwitchState());
}
@Override @Override
public void onConfigurationChanged(final Configuration conf) { public void onConfigurationChanged(final Configuration conf) {
SettingsValues settingsValues = mSettings.getCurrent(); SettingsValues settingsValues = mSettings.getCurrent();
@ -716,7 +721,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// have a change in hardware keyboard configuration. // have a change in hardware keyboard configuration.
loadSettings(); loadSettings();
settingsValues = mSettings.getCurrent(); settingsValues = mSettings.getCurrent();
if (settingsValues.mHasHardwareKeyboard) { if (isImeSuppressedByHardwareKeyboard()) {
// We call cleanupInternalStateForFinishInput() because it's the right thing to do; // We call cleanupInternalStateForFinishInput() because it's the right thing to do;
// however, it seems at the moment the framework is passing us a seemingly valid // however, it seems at the moment the framework is passing us a seemingly valid
// but actually non-functional InputConnection object. So if this bug ever gets // but actually non-functional InputConnection object. So if this bug ever gets
@ -874,7 +879,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// can go into the correct mode, so we need to do some housekeeping here. // can go into the correct mode, so we need to do some housekeeping here.
final boolean needToCallLoadKeyboardLater; final boolean needToCallLoadKeyboardLater;
final Suggest suggest = mInputLogic.mSuggest; final Suggest suggest = mInputLogic.mSuggest;
if (!currentSettingsValues.mHasHardwareKeyboard) { if (!isImeSuppressedByHardwareKeyboard()) {
// The app calling setText() has the effect of clearing the composing // The app calling setText() has the effect of clearing the composing
// span, so we should reset our state unconditionally, even if restarting is true. // span, so we should reset our state unconditionally, even if restarting is true.
// We also tell the input logic about the combining rules for the current subtype, so // We also tell the input logic about the combining rules for the current subtype, so
@ -1118,8 +1123,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return; return;
} }
final int inputHeight = mInputView.getHeight(); final int inputHeight = mInputView.getHeight();
final boolean hasHardwareKeyboard = settingsValues.mHasHardwareKeyboard; if (isImeSuppressedByHardwareKeyboard() && !visibleKeyboardView.isShown()) {
if (hasHardwareKeyboard && visibleKeyboardView.getVisibility() == View.GONE) {
// If there is a hardware keyboard and a visible software keyboard view has been hidden, // If there is a hardware keyboard and a visible software keyboard view has been hidden,
// no visual element will be shown on the screen. // no visual element will be shown on the screen.
outInsets.contentTopInsets = inputHeight; outInsets.contentTopInsets = inputHeight;
@ -1165,7 +1169,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override @Override
public boolean onShowInputRequested(final int flags, final boolean configChange) { public boolean onShowInputRequested(final int flags, final boolean configChange) {
if (Settings.getInstance().getCurrent().mHasHardwareKeyboard) { if (isImeSuppressedByHardwareKeyboard()) {
return true; return true;
} }
return super.onShowInputRequested(flags, configChange); return super.onShowInputRequested(flags, configChange);
@ -1182,7 +1186,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override @Override
public boolean onEvaluateFullscreenMode() { public boolean onEvaluateFullscreenMode() {
final SettingsValues settingsValues = mSettings.getCurrent(); final SettingsValues settingsValues = mSettings.getCurrent();
if (settingsValues.mHasHardwareKeyboard) { if (isImeSuppressedByHardwareKeyboard()) {
// If there is a hardware keyboard, disable full screen mode. // If there is a hardware keyboard, disable full screen mode.
return false; return false;
} }
@ -1646,8 +1650,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Hooks for hardware keyboard // Hooks for hardware keyboard
@Override @Override
public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) { public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) {
// TODO: This should be processed in {@link InputLogic}.
mEmojiAltPhysicalKeyDetector.onKeyDown(keyEvent);
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) { if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
return super.onKeyDown(keyCode, keyEvent); return super.onKeyDown(keyCode, keyEvent);
} }
@ -1668,7 +1670,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override @Override
public boolean onKeyUp(final int keyCode, final KeyEvent keyEvent) { public boolean onKeyUp(final int keyCode, final KeyEvent keyEvent) {
// TODO: This should be processed in {@link InputLogic}. if (mEmojiAltPhysicalKeyDetector == null) {
mEmojiAltPhysicalKeyDetector = new EmojiAltPhysicalKeyDetector(
getApplicationContext().getResources());
}
mEmojiAltPhysicalKeyDetector.onKeyUp(keyEvent); mEmojiAltPhysicalKeyDetector.onKeyUp(keyEvent);
if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) { if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) {
return super.onKeyUp(keyCode, keyEvent); return super.onKeyUp(keyCode, keyEvent);