KeyguardPasswordView.java revision 69bdee7c873c4a2295651efda2d0e79c515acc17
15e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller/*
2dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Copyright (C) 2012 The Android Open Source Project
35e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller *
45e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * Licensed under the Apache License, Version 2.0 (the "License");
55e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * you may not use this file except in compliance with the License.
65e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * You may obtain a copy of the License at
75e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller *
85e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller *      http://www.apache.org/licenses/LICENSE-2.0
95e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller *
105e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * Unless required by applicable law or agreed to in writing, software
115e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * distributed under the License is distributed on an "AS IS" BASIS,
125e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * See the License for the specific language governing permissions and
145e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * limitations under the License.
155e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller */
165e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller
17dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpackage com.android.internal.policy.impl.keyguard;
185e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller
19dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.Context;
20dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.AttributeSet;
21dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.View;
22dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
23dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.R;
24dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.widget.LockPatternUtils;
25858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Millerimport java.util.List;
26858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller
27f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Millerimport android.app.admin.DevicePolicyManager;
285475906f53e2d79807548932dfabbf9945143740Jim Millerimport android.content.res.Configuration;
29148e73eaed1fc0c12cdf84f0eb20a24624397a11Jim Millerimport android.graphics.Rect;
305e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller
31a781d016108d64b2735740d42b5a7c57eb420406Jim Millerimport com.android.internal.widget.PasswordEntryKeyboardView;
325e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller
33f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Millerimport android.os.CountDownTimer;
34f1818ffd82ad288f52e81dae8eccc44db10c6564Jim Millerimport android.os.SystemClock;
358ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Millerimport android.text.Editable;
36da3ae8fba865e4b02016bcb65b87a1fbfa000158Jim Millerimport android.text.InputType;
378ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Millerimport android.text.TextWatcher;
388b9dda28c9850b4a68b6958b8d4f751dd64157adJim Millerimport android.text.method.DigitsKeyListener;
398b9dda28c9850b4a68b6958b8d4f751dd64157adJim Millerimport android.text.method.TextKeyListener;
405e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport android.view.KeyEvent;
41a781d016108d64b2735740d42b5a7c57eb420406Jim Millerimport android.view.inputmethod.EditorInfo;
42858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Millerimport android.view.inputmethod.InputMethodInfo;
43858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Millerimport android.view.inputmethod.InputMethodManager;
44858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Millerimport android.view.inputmethod.InputMethodSubtype;
45a781d016108d64b2735740d42b5a7c57eb420406Jim Millerimport android.widget.EditText;
465e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport android.widget.LinearLayout;
475e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Millerimport android.widget.TextView;
48a781d016108d64b2735740d42b5a7c57eb420406Jim Millerimport android.widget.TextView.OnEditorActionListener;
49a781d016108d64b2735740d42b5a7c57eb420406Jim Miller
50a781d016108d64b2735740d42b5a7c57eb420406Jim Millerimport com.android.internal.widget.PasswordEntryKeyboardHelper;
515e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller/**
525e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * Displays a dialer-like interface or alphanumeric (latin-1) key entry for the user to enter
535e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller * an unlock password
545e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller */
555e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller
5669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandlerpublic class KeyguardPasswordView extends KeyguardAbsKeyInputView
579cf2c523d82ec14632fd0db920dcc8909c0f44a5Jim Miller        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
5869bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
59dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private PasswordEntryKeyboardView mKeyboardView;
60dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private PasswordEntryKeyboardHelper mKeyboardHelper;
61dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private boolean mIsAlpha;
62ac8f5751f52fa445af641604e476703dd5e89504Jim Miller
63dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardPasswordView(Context context) {
645e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller        super(context);
65dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
66dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
67dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardPasswordView(Context context, AttributeSet attrs) {
68dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super(context, attrs);
69dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
705475906f53e2d79807548932dfabbf9945143740Jim Miller
7169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler    protected void resetState() {
720ff7f010f8bfd011f0915031b02739ae3bee401eJim Miller        mSecurityMessageDisplay.setMessage(
730a4f900463024908220d0c9bf4b291a6e1284846Adam Cohen                mIsAlpha ? R.string.kg_password_instructions : R.string.kg_pin_instructions, false);
7408b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        mPasswordEntry.setEnabled(true);
7508b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller        mKeyboardView.setEnabled(true);
7608b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller    }
7708b2b6bfe2550b65c68ad7b4bef8283f1ff17561Jim Miller
78dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
79dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onFinishInflate() {
8069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        super.onFinishInflate();
815e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller
82dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        final int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality();
83f9a166ab8236b5824049f5103c4365e12b52b4acKonstantin Lopyrev        mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality
84a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
85a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97Konstantin Lopyrev                || DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
86f7c5d0e46ced3ec3edb6f656acd82900b9ac988cJim Miller
87a781d016108d64b2735740d42b5a7c57eb420406Jim Miller        mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
885e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller
893af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Miller        mKeyboardHelper = new PasswordEntryKeyboardHelper(mContext, mKeyboardView, this, false,
903af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Miller                new int[] {
913af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Miller                    R.xml.kg_password_kbd_numeric,
923af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Miller                    com.android.internal.R.xml.password_kbd_qwerty,
933af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Miller                    com.android.internal.R.xml.password_kbd_qwerty_shifted,
943af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Miller                    com.android.internal.R.xml.password_kbd_symbols,
953af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Miller                    com.android.internal.R.xml.password_kbd_symbols_shift
963af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Miller                    }
973af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Miller        );
983fb0af38a1de9258cc80b227361c9a8ded88cfefJeff Sharkey        mKeyboardHelper.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled());
99dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
100d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller        boolean imeOrDeleteButtonVisible = false;
1016b05d58018c2806459c121e507c005639b74aee9Jim Miller        if (mIsAlpha) {
1026b05d58018c2806459c121e507c005639b74aee9Jim Miller            // We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard
1036b05d58018c2806459c121e507c005639b74aee9Jim Miller            mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
1046b05d58018c2806459c121e507c005639b74aee9Jim Miller            mKeyboardView.setVisibility(View.GONE);
1058171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung        } else {
1068171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
107ac8f5751f52fa445af641604e476703dd5e89504Jim Miller
108ac8f5751f52fa445af641604e476703dd5e89504Jim Miller            // Use lockscreen's numeric keyboard if the physical keyboard isn't showing
109ac8f5751f52fa445af641604e476703dd5e89504Jim Miller            boolean hardKeyboardVisible = getResources().getConfiguration().hardKeyboardHidden
110ac8f5751f52fa445af641604e476703dd5e89504Jim Miller                    == Configuration.HARDKEYBOARDHIDDEN_NO;
111ac8f5751f52fa445af641604e476703dd5e89504Jim Miller            mKeyboardView.setVisibility(
112ac8f5751f52fa445af641604e476703dd5e89504Jim Miller                    (ENABLE_HIDE_KEYBOARD && hardKeyboardVisible) ? View.INVISIBLE : View.VISIBLE);
11351ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo
11451ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo            // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
11551ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo            // not a separate view
116dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            View pinDelete = findViewById(R.id.delete_button);
11751ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo            if (pinDelete != null) {
11851ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo                pinDelete.setVisibility(View.VISIBLE);
119d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller                imeOrDeleteButtonVisible = true;
12051ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo                pinDelete.setOnClickListener(new OnClickListener() {
12151ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo                    public void onClick(View v) {
12251ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo                        mKeyboardHelper.handleBackspace();
12351ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo                    }
12451ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo                });
12551ea88a86e5cf418e956b199de35658f0a5fd623Ben Komalo            }
1268171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung        }
1275e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller
1288ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller        // This allows keyboards with overlapping qwerty/numeric keys to choose just numeric keys.
129f9a166ab8236b5824049f5103c4365e12b52b4acKonstantin Lopyrev        if (mIsAlpha) {
1308b9dda28c9850b4a68b6958b8d4f751dd64157adJim Miller            mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
1318ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller            mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
1328ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller                    | InputType.TYPE_TEXT_VARIATION_PASSWORD);
1338b9dda28c9850b4a68b6958b8d4f751dd64157adJim Miller        } else {
1348b9dda28c9850b4a68b6958b8d4f751dd64157adJim Miller            mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
1358ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller            mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
1368ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller                    | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
1378b9dda28c9850b4a68b6958b8d4f751dd64157adJim Miller        }
1388b9dda28c9850b4a68b6958b8d4f751dd64157adJim Miller
1396b05d58018c2806459c121e507c005639b74aee9Jim Miller        // Poke the wakelock any time the text is selected or modified
1406b05d58018c2806459c121e507c005639b74aee9Jim Miller        mPasswordEntry.setOnClickListener(new OnClickListener() {
1416b05d58018c2806459c121e507c005639b74aee9Jim Miller            public void onClick(View v) {
142dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                mCallback.userActivity(0); // TODO: customize timeout for text?
1436b05d58018c2806459c121e507c005639b74aee9Jim Miller            }
1446b05d58018c2806459c121e507c005639b74aee9Jim Miller        });
145dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1468ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller        mPasswordEntry.addTextChangedListener(new TextWatcher() {
1478ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller            public void onTextChanged(CharSequence s, int start, int before, int count) {
1488ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller            }
1498ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller
1508ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
1518ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller            }
1528ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller
1538ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller            public void afterTextChanged(Editable s) {
154ac8a59d3d3a6ddb32a293e4dfc74fb55a0ea6e82Adam Cohen                if (mCallback != null) {
155ac8a59d3d3a6ddb32a293e4dfc74fb55a0ea6e82Adam Cohen                    mCallback.userActivity(0);
156ac8a59d3d3a6ddb32a293e4dfc74fb55a0ea6e82Adam Cohen                }
1578ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller            }
1588ecfac1d8c2988c3d5031e78f9edefff6e663fd1Jim Miller        });
159858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller
16069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        mPasswordEntry.requestFocus();
16169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler
162858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        // If there's more than one IME, enable the IME switcher button
163858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        View switchImeButton = findViewById(R.id.switch_ime_button);
164858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        final InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
165858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                Context.INPUT_METHOD_SERVICE);
166b0166bc62f781c3dd921560c0ebafd965603fb16Jim Miller        if (mIsAlpha && switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) {
167858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            switchImeButton.setVisibility(View.VISIBLE);
168d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller            imeOrDeleteButtonVisible = true;
169858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            switchImeButton.setOnClickListener(new OnClickListener() {
170858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                public void onClick(View v) {
171dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    mCallback.userActivity(0); // Leave the screen on a bit longer
172858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                    imm.showInputMethodPicker();
173858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                }
174858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            });
175858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        }
176d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller
17770bc9f24ce6098a8c82245ac1ce7721d354ecd3dAdam Powell        // If no icon is visible, reset the start margin on the password field so the text is
178d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller        // still centered.
179d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller        if (!imeOrDeleteButtonVisible) {
180d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller            android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
181d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller            if (params instanceof MarginLayoutParams) {
18270bc9f24ce6098a8c82245ac1ce7721d354ecd3dAdam Powell                final MarginLayoutParams mlp = (MarginLayoutParams) params;
18370bc9f24ce6098a8c82245ac1ce7721d354ecd3dAdam Powell                mlp.setMarginStart(0);
184d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller                mPasswordEntry.setLayoutParams(params);
185d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller            }
186d9d09451ccec7c551d5f9c2f1417c9c1de2952a6Jim Miller        }
187858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller    }
188858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller
189858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller    /**
190858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller     * Method adapted from com.android.inputmethod.latin.Utils
191858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller     *
192858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller     * @param imm The input method manager
193858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller     * @param shouldIncludeAuxiliarySubtypes
194858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller     * @return true if we have multiple IMEs to choose from
195858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller     */
196858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller    private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
197858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            final boolean shouldIncludeAuxiliarySubtypes) {
198858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
199858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller
200858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        // Number of the filtered IMEs
201858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        int filteredImisCount = 0;
202858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller
203858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        for (InputMethodInfo imi : enabledImis) {
204858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            // We can return true immediately after we find two or more filtered IMEs.
205858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            if (filteredImisCount > 1) return true;
206858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            final List<InputMethodSubtype> subtypes =
207858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                    imm.getEnabledInputMethodSubtypeList(imi, true);
208858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            // IMEs that have no subtypes should be counted.
209858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            if (subtypes.isEmpty()) {
210858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                ++filteredImisCount;
211858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                continue;
212858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            }
213858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller
214858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            int auxCount = 0;
215858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            for (InputMethodSubtype subtype : subtypes) {
216858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                if (subtype.isAuxiliary()) {
217858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                    ++auxCount;
218858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                }
219858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            }
220858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            final int nonAuxCount = subtypes.size() - auxCount;
221858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller
222858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            // IMEs that have one or more non-auxiliary subtypes should be counted.
223858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
224858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            // subtypes should be counted as well.
225858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
226858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                ++filteredImisCount;
227858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                continue;
228858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller            }
229858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        }
230858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller
231858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        return filteredImisCount > 1
232858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
233858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller        // input method subtype (The current IME should be LatinIME.)
234858f8eaac75bcd1b296b41837caf3dae82d1d72aJim Miller                || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
2355e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller    }
2365e0f7ba8fa8045aab98664b5103d8620e9ac7f06Jim Miller}
237dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
238