Home | History | Annotate | Download | only in keyboard
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.inputmethod.keyboard;
     18 
     19 import android.content.Context;
     20 import android.content.res.Resources;
     21 import android.util.Log;
     22 import android.view.ContextThemeWrapper;
     23 import android.view.LayoutInflater;
     24 import android.view.View;
     25 import android.view.inputmethod.EditorInfo;
     26 
     27 import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
     28 import com.android.inputmethod.event.Event;
     29 import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetException;
     30 import com.android.inputmethod.keyboard.emoji.EmojiPalettesView;
     31 import com.android.inputmethod.keyboard.internal.KeyboardState;
     32 import com.android.inputmethod.keyboard.internal.KeyboardTextsSet;
     33 import com.android.inputmethod.latin.InputView;
     34 import com.android.inputmethod.latin.LatinIME;
     35 import com.android.inputmethod.latin.R;
     36 import com.android.inputmethod.latin.RichInputMethodManager;
     37 import com.android.inputmethod.latin.WordComposer;
     38 import com.android.inputmethod.latin.define.ProductionFlags;
     39 import com.android.inputmethod.latin.settings.Settings;
     40 import com.android.inputmethod.latin.settings.SettingsValues;
     41 import com.android.inputmethod.latin.utils.CapsModeUtils;
     42 import com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils;
     43 import com.android.inputmethod.latin.utils.RecapitalizeStatus;
     44 import com.android.inputmethod.latin.utils.ResourceUtils;
     45 import com.android.inputmethod.latin.utils.ScriptUtils;
     46 
     47 import javax.annotation.Nonnull;
     48 
     49 public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
     50     private static final String TAG = KeyboardSwitcher.class.getSimpleName();
     51 
     52     private InputView mCurrentInputView;
     53     private View mMainKeyboardFrame;
     54     private MainKeyboardView mKeyboardView;
     55     private EmojiPalettesView mEmojiPalettesView;
     56     private LatinIME mLatinIME;
     57     private RichInputMethodManager mRichImm;
     58     private boolean mIsHardwareAcceleratedDrawingEnabled;
     59 
     60     private KeyboardState mState;
     61 
     62     private KeyboardLayoutSet mKeyboardLayoutSet;
     63     // TODO: The following {@link KeyboardTextsSet} should be in {@link KeyboardLayoutSet}.
     64     private final KeyboardTextsSet mKeyboardTextsSet = new KeyboardTextsSet();
     65 
     66     private KeyboardTheme mKeyboardTheme;
     67     private Context mThemeContext;
     68 
     69     private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
     70 
     71     public static KeyboardSwitcher getInstance() {
     72         return sInstance;
     73     }
     74 
     75     private KeyboardSwitcher() {
     76         // Intentional empty constructor for singleton.
     77     }
     78 
     79     public static void init(final LatinIME latinIme) {
     80         sInstance.initInternal(latinIme);
     81     }
     82 
     83     private void initInternal(final LatinIME latinIme) {
     84         mLatinIME = latinIme;
     85         mRichImm = RichInputMethodManager.getInstance();
     86         mState = new KeyboardState(this);
     87         mIsHardwareAcceleratedDrawingEnabled =
     88                 InputMethodServiceCompatUtils.enableHardwareAcceleration(mLatinIME);
     89     }
     90 
     91     public void updateKeyboardTheme() {
     92         final boolean themeUpdated = updateKeyboardThemeAndContextThemeWrapper(
     93                 mLatinIME, KeyboardTheme.getKeyboardTheme(mLatinIME /* context */));
     94         if (themeUpdated && mKeyboardView != null) {
     95             mLatinIME.setInputView(onCreateInputView(mIsHardwareAcceleratedDrawingEnabled));
     96         }
     97     }
     98 
     99     private boolean updateKeyboardThemeAndContextThemeWrapper(final Context context,
    100             final KeyboardTheme keyboardTheme) {
    101         if (mThemeContext == null || !keyboardTheme.equals(mKeyboardTheme)) {
    102             mKeyboardTheme = keyboardTheme;
    103             mThemeContext = new ContextThemeWrapper(context, keyboardTheme.mStyleId);
    104             KeyboardLayoutSet.onKeyboardThemeChanged();
    105             return true;
    106         }
    107         return false;
    108     }
    109 
    110     public void loadKeyboard(final EditorInfo editorInfo, final SettingsValues settingsValues,
    111             final int currentAutoCapsState, final int currentRecapitalizeState) {
    112         final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
    113                 mThemeContext, editorInfo);
    114         final Resources res = mThemeContext.getResources();
    115         final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
    116         final int keyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues);
    117         builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
    118         builder.setSubtype(mRichImm.getCurrentSubtype());
    119         builder.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey);
    120         builder.setLanguageSwitchKeyEnabled(mLatinIME.shouldShowLanguageSwitchKey());
    121         builder.setSplitLayoutEnabledByUser(ProductionFlags.IS_SPLIT_KEYBOARD_SUPPORTED
    122                 && settingsValues.mIsSplitKeyboardEnabled);
    123         mKeyboardLayoutSet = builder.build();
    124         try {
    125             mState.onLoadKeyboard(currentAutoCapsState, currentRecapitalizeState);
    126             mKeyboardTextsSet.setLocale(mRichImm.getCurrentSubtypeLocale(), mThemeContext);
    127         } catch (KeyboardLayoutSetException e) {
    128             Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
    129         }
    130     }
    131 
    132     public void saveKeyboardState() {
    133         if (getKeyboard() != null || isShowingEmojiPalettes()) {
    134             mState.onSaveKeyboardState();
    135         }
    136     }
    137 
    138     public void onHideWindow() {
    139         if (mKeyboardView != null) {
    140             mKeyboardView.onHideWindow();
    141         }
    142     }
    143 
    144     private void setKeyboard(
    145             @Nonnull final int keyboardId,
    146             @Nonnull final KeyboardSwitchState toggleState) {
    147         // Make {@link MainKeyboardView} visible and hide {@link EmojiPalettesView}.
    148         final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent();
    149         setMainKeyboardFrame(currentSettingsValues, toggleState);
    150         // TODO: pass this object to setKeyboard instead of getting the current values.
    151         final MainKeyboardView keyboardView = mKeyboardView;
    152         final Keyboard oldKeyboard = keyboardView.getKeyboard();
    153         final Keyboard newKeyboard = mKeyboardLayoutSet.getKeyboard(keyboardId);
    154         keyboardView.setKeyboard(newKeyboard);
    155         mCurrentInputView.setKeyboardTopPadding(newKeyboard.mTopPadding);
    156         keyboardView.setKeyPreviewPopupEnabled(
    157                 currentSettingsValues.mKeyPreviewPopupOn,
    158                 currentSettingsValues.mKeyPreviewPopupDismissDelay);
    159         keyboardView.setKeyPreviewAnimationParams(
    160                 currentSettingsValues.mHasCustomKeyPreviewAnimationParams,
    161                 currentSettingsValues.mKeyPreviewShowUpStartXScale,
    162                 currentSettingsValues.mKeyPreviewShowUpStartYScale,
    163                 currentSettingsValues.mKeyPreviewShowUpDuration,
    164                 currentSettingsValues.mKeyPreviewDismissEndXScale,
    165                 currentSettingsValues.mKeyPreviewDismissEndYScale,
    166                 currentSettingsValues.mKeyPreviewDismissDuration);
    167         keyboardView.updateShortcutKey(mRichImm.isShortcutImeReady());
    168         final boolean subtypeChanged = (oldKeyboard == null)
    169                 || !newKeyboard.mId.mSubtype.equals(oldKeyboard.mId.mSubtype);
    170         final int languageOnSpacebarFormatType = LanguageOnSpacebarUtils
    171                 .getLanguageOnSpacebarFormatType(newKeyboard.mId.mSubtype);
    172         final boolean hasMultipleEnabledIMEsOrSubtypes = mRichImm
    173                 .hasMultipleEnabledIMEsOrSubtypes(true /* shouldIncludeAuxiliarySubtypes */);
    174         keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, languageOnSpacebarFormatType,
    175                 hasMultipleEnabledIMEsOrSubtypes);
    176     }
    177 
    178     public Keyboard getKeyboard() {
    179         if (mKeyboardView != null) {
    180             return mKeyboardView.getKeyboard();
    181         }
    182         return null;
    183     }
    184 
    185     // TODO: Remove this method. Come up with a more comprehensive way to reset the keyboard layout
    186     // when a keyboard layout set doesn't get reloaded in LatinIME.onStartInputViewInternal().
    187     public void resetKeyboardStateToAlphabet(final int currentAutoCapsState,
    188             final int currentRecapitalizeState) {
    189         mState.onResetKeyboardStateToAlphabet(currentAutoCapsState, currentRecapitalizeState);
    190     }
    191 
    192     public void onPressKey(final int code, final boolean isSinglePointer,
    193             final int currentAutoCapsState, final int currentRecapitalizeState) {
    194         mState.onPressKey(code, isSinglePointer, currentAutoCapsState, currentRecapitalizeState);
    195     }
    196 
    197     public void onReleaseKey(final int code, final boolean withSliding,
    198             final int currentAutoCapsState, final int currentRecapitalizeState) {
    199         mState.onReleaseKey(code, withSliding, currentAutoCapsState, currentRecapitalizeState);
    200     }
    201 
    202     public void onFinishSlidingInput(final int currentAutoCapsState,
    203             final int currentRecapitalizeState) {
    204         mState.onFinishSlidingInput(currentAutoCapsState, currentRecapitalizeState);
    205     }
    206 
    207     // Implements {@link KeyboardState.SwitchActions}.
    208     @Override
    209     public void setAlphabetKeyboard() {
    210         if (DEBUG_ACTION) {
    211             Log.d(TAG, "setAlphabetKeyboard");
    212         }
    213         setKeyboard(KeyboardId.ELEMENT_ALPHABET, KeyboardSwitchState.OTHER);
    214     }
    215 
    216     // Implements {@link KeyboardState.SwitchActions}.
    217     @Override
    218     public void setAlphabetManualShiftedKeyboard() {
    219         if (DEBUG_ACTION) {
    220             Log.d(TAG, "setAlphabetManualShiftedKeyboard");
    221         }
    222         setKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED, KeyboardSwitchState.OTHER);
    223     }
    224 
    225     // Implements {@link KeyboardState.SwitchActions}.
    226     @Override
    227     public void setAlphabetAutomaticShiftedKeyboard() {
    228         if (DEBUG_ACTION) {
    229             Log.d(TAG, "setAlphabetAutomaticShiftedKeyboard");
    230         }
    231         setKeyboard(KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardSwitchState.OTHER);
    232     }
    233 
    234     // Implements {@link KeyboardState.SwitchActions}.
    235     @Override
    236     public void setAlphabetShiftLockedKeyboard() {
    237         if (DEBUG_ACTION) {
    238             Log.d(TAG, "setAlphabetShiftLockedKeyboard");
    239         }
    240         setKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED, KeyboardSwitchState.OTHER);
    241     }
    242 
    243     // Implements {@link KeyboardState.SwitchActions}.
    244     @Override
    245     public void setAlphabetShiftLockShiftedKeyboard() {
    246         if (DEBUG_ACTION) {
    247             Log.d(TAG, "setAlphabetShiftLockShiftedKeyboard");
    248         }
    249         setKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED, KeyboardSwitchState.OTHER);
    250     }
    251 
    252     // Implements {@link KeyboardState.SwitchActions}.
    253     @Override
    254     public void setSymbolsKeyboard() {
    255         if (DEBUG_ACTION) {
    256             Log.d(TAG, "setSymbolsKeyboard");
    257         }
    258         setKeyboard(KeyboardId.ELEMENT_SYMBOLS, KeyboardSwitchState.OTHER);
    259     }
    260 
    261     // Implements {@link KeyboardState.SwitchActions}.
    262     @Override
    263     public void setSymbolsShiftedKeyboard() {
    264         if (DEBUG_ACTION) {
    265             Log.d(TAG, "setSymbolsShiftedKeyboard");
    266         }
    267         setKeyboard(KeyboardId.ELEMENT_SYMBOLS_SHIFTED, KeyboardSwitchState.SYMBOLS_SHIFTED);
    268     }
    269 
    270     public boolean isImeSuppressedByHardwareKeyboard(
    271             @Nonnull final SettingsValues settingsValues,
    272             @Nonnull final KeyboardSwitchState toggleState) {
    273         return settingsValues.mHasHardwareKeyboard && toggleState == KeyboardSwitchState.HIDDEN;
    274     }
    275 
    276     private void setMainKeyboardFrame(
    277             @Nonnull final SettingsValues settingsValues,
    278             @Nonnull final KeyboardSwitchState toggleState) {
    279         final int visibility =  isImeSuppressedByHardwareKeyboard(settingsValues, toggleState)
    280                 ? View.GONE : View.VISIBLE;
    281         mKeyboardView.setVisibility(visibility);
    282         // The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
    283         // @see #getVisibleKeyboardView() and
    284         // @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets)
    285         mMainKeyboardFrame.setVisibility(visibility);
    286         mEmojiPalettesView.setVisibility(View.GONE);
    287         mEmojiPalettesView.stopEmojiPalettes();
    288     }
    289 
    290     // Implements {@link KeyboardState.SwitchActions}.
    291     @Override
    292     public void setEmojiKeyboard() {
    293         if (DEBUG_ACTION) {
    294             Log.d(TAG, "setEmojiKeyboard");
    295         }
    296         final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
    297         mMainKeyboardFrame.setVisibility(View.GONE);
    298         // The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
    299         // @see #getVisibleKeyboardView() and
    300         // @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets)
    301         mKeyboardView.setVisibility(View.GONE);
    302         mEmojiPalettesView.startEmojiPalettes(
    303                 mKeyboardTextsSet.getText(KeyboardTextsSet.SWITCH_TO_ALPHA_KEY_LABEL),
    304                 mKeyboardView.getKeyVisualAttribute(), keyboard.mIconsSet);
    305         mEmojiPalettesView.setVisibility(View.VISIBLE);
    306     }
    307 
    308     public enum KeyboardSwitchState {
    309         HIDDEN(-1),
    310         SYMBOLS_SHIFTED(KeyboardId.ELEMENT_SYMBOLS_SHIFTED),
    311         EMOJI(KeyboardId.ELEMENT_EMOJI_RECENTS),
    312         OTHER(-1);
    313 
    314         final int mKeyboardId;
    315 
    316         KeyboardSwitchState(int keyboardId) {
    317             mKeyboardId = keyboardId;
    318         }
    319     }
    320 
    321     public KeyboardSwitchState getKeyboardSwitchState() {
    322         boolean hidden = !isShowingEmojiPalettes()
    323                 && (mKeyboardLayoutSet == null
    324                 || mKeyboardView == null
    325                 || !mKeyboardView.isShown());
    326         KeyboardSwitchState state;
    327         if (hidden) {
    328             return KeyboardSwitchState.HIDDEN;
    329         } else if (isShowingEmojiPalettes()) {
    330             return KeyboardSwitchState.EMOJI;
    331         } else if (isShowingKeyboardId(KeyboardId.ELEMENT_SYMBOLS_SHIFTED)) {
    332             return KeyboardSwitchState.SYMBOLS_SHIFTED;
    333         }
    334         return KeyboardSwitchState.OTHER;
    335     }
    336 
    337     public void onToggleKeyboard(@Nonnull final KeyboardSwitchState toggleState) {
    338         KeyboardSwitchState currentState = getKeyboardSwitchState();
    339         Log.w(TAG, "onToggleKeyboard() : Current = " + currentState + " : Toggle = " + toggleState);
    340         if (currentState == toggleState) {
    341             mLatinIME.stopShowingInputView();
    342             mLatinIME.hideWindow();
    343             setAlphabetKeyboard();
    344         } else {
    345             mLatinIME.startShowingInputView(true);
    346             if (toggleState == KeyboardSwitchState.EMOJI) {
    347                 setEmojiKeyboard();
    348             } else {
    349                 mEmojiPalettesView.stopEmojiPalettes();
    350                 mEmojiPalettesView.setVisibility(View.GONE);
    351 
    352                 mMainKeyboardFrame.setVisibility(View.VISIBLE);
    353                 mKeyboardView.setVisibility(View.VISIBLE);
    354                 setKeyboard(toggleState.mKeyboardId, toggleState);
    355             }
    356         }
    357     }
    358 
    359     // Future method for requesting an updating to the shift state.
    360     @Override
    361     public void requestUpdatingShiftState(final int autoCapsFlags, final int recapitalizeMode) {
    362         if (DEBUG_ACTION) {
    363             Log.d(TAG, "requestUpdatingShiftState: "
    364                     + " autoCapsFlags=" + CapsModeUtils.flagsToString(autoCapsFlags)
    365                     + " recapitalizeMode=" + RecapitalizeStatus.modeToString(recapitalizeMode));
    366         }
    367         mState.onUpdateShiftState(autoCapsFlags, recapitalizeMode);
    368     }
    369 
    370     // Implements {@link KeyboardState.SwitchActions}.
    371     @Override
    372     public void startDoubleTapShiftKeyTimer() {
    373         if (DEBUG_TIMER_ACTION) {
    374             Log.d(TAG, "startDoubleTapShiftKeyTimer");
    375         }
    376         final MainKeyboardView keyboardView = getMainKeyboardView();
    377         if (keyboardView != null) {
    378             keyboardView.startDoubleTapShiftKeyTimer();
    379         }
    380     }
    381 
    382     // Implements {@link KeyboardState.SwitchActions}.
    383     @Override
    384     public void cancelDoubleTapShiftKeyTimer() {
    385         if (DEBUG_TIMER_ACTION) {
    386             Log.d(TAG, "setAlphabetKeyboard");
    387         }
    388         final MainKeyboardView keyboardView = getMainKeyboardView();
    389         if (keyboardView != null) {
    390             keyboardView.cancelDoubleTapShiftKeyTimer();
    391         }
    392     }
    393 
    394     // Implements {@link KeyboardState.SwitchActions}.
    395     @Override
    396     public boolean isInDoubleTapShiftKeyTimeout() {
    397         if (DEBUG_TIMER_ACTION) {
    398             Log.d(TAG, "isInDoubleTapShiftKeyTimeout");
    399         }
    400         final MainKeyboardView keyboardView = getMainKeyboardView();
    401         return keyboardView != null && keyboardView.isInDoubleTapShiftKeyTimeout();
    402     }
    403 
    404     /**
    405      * Updates state machine to figure out when to automatically switch back to the previous mode.
    406      */
    407     public void onEvent(final Event event, final int currentAutoCapsState,
    408             final int currentRecapitalizeState) {
    409         mState.onEvent(event, currentAutoCapsState, currentRecapitalizeState);
    410     }
    411 
    412     public boolean isShowingKeyboardId(@Nonnull int... keyboardIds) {
    413         if (mKeyboardView == null || !mKeyboardView.isShown()) {
    414             return false;
    415         }
    416         int activeKeyboardId = mKeyboardView.getKeyboard().mId.mElementId;
    417         for (int keyboardId : keyboardIds) {
    418             if (activeKeyboardId == keyboardId) {
    419                 return true;
    420             }
    421         }
    422         return false;
    423     }
    424 
    425     public boolean isShowingEmojiPalettes() {
    426         return mEmojiPalettesView != null && mEmojiPalettesView.isShown();
    427     }
    428 
    429     public boolean isShowingMoreKeysPanel() {
    430         if (isShowingEmojiPalettes()) {
    431             return false;
    432         }
    433         return mKeyboardView.isShowingMoreKeysPanel();
    434     }
    435 
    436     public View getVisibleKeyboardView() {
    437         if (isShowingEmojiPalettes()) {
    438             return mEmojiPalettesView;
    439         }
    440         return mKeyboardView;
    441     }
    442 
    443     public MainKeyboardView getMainKeyboardView() {
    444         return mKeyboardView;
    445     }
    446 
    447     public void deallocateMemory() {
    448         if (mKeyboardView != null) {
    449             mKeyboardView.cancelAllOngoingEvents();
    450             mKeyboardView.deallocateMemory();
    451         }
    452         if (mEmojiPalettesView != null) {
    453             mEmojiPalettesView.stopEmojiPalettes();
    454         }
    455     }
    456 
    457     public View onCreateInputView(final boolean isHardwareAcceleratedDrawingEnabled) {
    458         if (mKeyboardView != null) {
    459             mKeyboardView.closing();
    460         }
    461 
    462         updateKeyboardThemeAndContextThemeWrapper(
    463                 mLatinIME, KeyboardTheme.getKeyboardTheme(mLatinIME /* context */));
    464         mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(
    465                 R.layout.input_view, null);
    466         mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame);
    467         mEmojiPalettesView = (EmojiPalettesView)mCurrentInputView.findViewById(
    468                 R.id.emoji_palettes_view);
    469 
    470         mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
    471         mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
    472         mKeyboardView.setKeyboardActionListener(mLatinIME);
    473         mEmojiPalettesView.setHardwareAcceleratedDrawingEnabled(
    474                 isHardwareAcceleratedDrawingEnabled);
    475         mEmojiPalettesView.setKeyboardActionListener(mLatinIME);
    476         return mCurrentInputView;
    477     }
    478 
    479     public int getKeyboardShiftMode() {
    480         final Keyboard keyboard = getKeyboard();
    481         if (keyboard == null) {
    482             return WordComposer.CAPS_MODE_OFF;
    483         }
    484         switch (keyboard.mId.mElementId) {
    485         case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
    486         case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
    487             return WordComposer.CAPS_MODE_MANUAL_SHIFT_LOCKED;
    488         case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
    489             return WordComposer.CAPS_MODE_MANUAL_SHIFTED;
    490         case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
    491             return WordComposer.CAPS_MODE_AUTO_SHIFTED;
    492         default:
    493             return WordComposer.CAPS_MODE_OFF;
    494         }
    495     }
    496 
    497     public int getCurrentKeyboardScriptId() {
    498         if (null == mKeyboardLayoutSet) {
    499             return ScriptUtils.SCRIPT_UNKNOWN;
    500         }
    501         return mKeyboardLayoutSet.getScriptId();
    502     }
    503 }
    504