13fa13775e805df6cc7244d3f93105c5d3a5b748fsatok/*
23fa13775e805df6cc7244d3f93105c5d3a5b748fsatok * Copyright (C) 2011 The Android Open Source Project
33fa13775e805df6cc7244d3f93105c5d3a5b748fsatok *
43fa13775e805df6cc7244d3f93105c5d3a5b748fsatok * Licensed under the Apache License, Version 2.0 (the "License");
53fa13775e805df6cc7244d3f93105c5d3a5b748fsatok * you may not use this file except in compliance with the License.
63fa13775e805df6cc7244d3f93105c5d3a5b748fsatok * You may obtain a copy of the License at
73fa13775e805df6cc7244d3f93105c5d3a5b748fsatok *
83fa13775e805df6cc7244d3f93105c5d3a5b748fsatok *      http://www.apache.org/licenses/LICENSE-2.0
93fa13775e805df6cc7244d3f93105c5d3a5b748fsatok *
103fa13775e805df6cc7244d3f93105c5d3a5b748fsatok * Unless required by applicable law or agreed to in writing, software
113fa13775e805df6cc7244d3f93105c5d3a5b748fsatok * distributed under the License is distributed on an "AS IS" BASIS,
123fa13775e805df6cc7244d3f93105c5d3a5b748fsatok * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133fa13775e805df6cc7244d3f93105c5d3a5b748fsatok * See the License for the specific language governing permissions and
143fa13775e805df6cc7244d3f93105c5d3a5b748fsatok * limitations under the License.
153fa13775e805df6cc7244d3f93105c5d3a5b748fsatok */
163fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
173fa13775e805df6cc7244d3f93105c5d3a5b748fsatokpackage com.android.settings.inputmethod;
183fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
193fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.app.AlertDialog;
201c2b175d7ab8da48a12191c4930bd4ed451a9952Ken Wakasaimport android.content.ActivityNotFoundException;
21c6fc8e46f2e78187cb751f2ae81e6101181c93c0Satoshi Kataokaimport android.content.Context;
223fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.content.DialogInterface;
233fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.content.Intent;
24f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shankaimport android.os.UserHandle;
2539b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v14.preference.SwitchPreference;
2639b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference;
2739b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference.OnPreferenceChangeListener;
2839b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference.OnPreferenceClickListener;
293fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.text.TextUtils;
303fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.util.Log;
313fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.view.inputmethod.InputMethodInfo;
323fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.view.inputmethod.InputMethodManager;
333fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport android.view.inputmethod.InputMethodSubtype;
34e508dc25f2d3168f37fe5963fc99b0a034a3a298satokimport android.widget.Toast;
353fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
3674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaokaimport com.android.internal.inputmethod.InputMethodUtils;
3774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaokaimport com.android.settings.R;
389c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shankaimport com.android.settingslib.RestrictedLockUtils;
399c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shankaimport com.android.settingslib.RestrictedSwitchPreference;
4074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka
41ef120bea7b8cb3b891ae3f39d7a97989c107a16fSatoshi Kataokaimport java.text.Collator;
423fa13775e805df6cc7244d3f93105c5d3a5b748fsatokimport java.util.List;
433fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
449c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shankaimport static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
459c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka
4674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka/**
4774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka * Input method preference.
4874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka *
4974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka * This preference represents an IME. It is used for two purposes. 1) An instance with a switch
5074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka * is used to enable or disable the IME. 2) An instance without a switch is used to invoke the
5174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka * setting activity of the IME.
5274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka */
539c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shankaclass InputMethodPreference extends RestrictedSwitchPreference implements OnPreferenceClickListener,
5474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        OnPreferenceChangeListener {
553fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private static final String TAG = InputMethodPreference.class.getSimpleName();
5674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    private static final String EMPTY_TEXT = "";
57a9341c38e3a3e38ebf6de1803304026b84d4c15dYohei Yukawa    private static final int NO_WIDGET = 0;
5874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka
59cd6fdead7c7a42f4a18a37523bb4feef230559c0Tadashi G. Takaoka    interface OnSavePreferenceListener {
6074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        /**
6174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka         * Called when this preference needs to be saved its state.
6274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka         *
6374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka         * Note that this preference is non-persistent and needs explicitly to be saved its state.
6474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka         * Because changing one IME state may change other IMEs' state, this is a place to update
6574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka         * other IMEs' state as well.
6674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka         *
6774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka         * @param pref This preference.
6874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka         */
6974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        public void onSaveInputMethodPreference(InputMethodPreference pref);
7074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    }
7174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka
723fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private final InputMethodInfo mImi;
7374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    private final boolean mHasPriorityInSorting;
74cd6fdead7c7a42f4a18a37523bb4feef230559c0Tadashi G. Takaoka    private final OnSavePreferenceListener mOnSaveListener;
7574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    private final InputMethodSettingValuesWrapper mInputMethodSettingValues;
76333f2bc71a0866053f8e2fce8efbfb0bcec68811Kenny Guy    private final boolean mIsAllowedByOrganization;
773fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
783fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    private AlertDialog mDialog = null;
79054fc44cae0d412ca5e72c709f0d5e3deb7768a7satok
8074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    /**
8174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka     * A preference entry of an input method.
8274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka     *
8374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka     * @param context The Context this is associated with.
8474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka     * @param imi The {@link InputMethodInfo} of this preference.
8574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka     * @param isImeEnabler true if this preference is the IME enabler that has enable/disable
8674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka     *     switches for all available IMEs, not the list of enabled IMEs.
87333f2bc71a0866053f8e2fce8efbfb0bcec68811Kenny Guy     * @param isAllowedByOrganization false if the IME has been disabled by a device or profile
889c32468cd59cbe5b8e7692235a67034c936b4788Sudheer Shanka     *     owner.
8974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka     * @param onSaveListener The listener called when this preference has been changed and needs
9074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka     *     to save the state to shared preference.
9174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka     */
9274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    InputMethodPreference(final Context context, final InputMethodInfo imi,
93333f2bc71a0866053f8e2fce8efbfb0bcec68811Kenny Guy            final boolean isImeEnabler, final boolean isAllowedByOrganization,
94333f2bc71a0866053f8e2fce8efbfb0bcec68811Kenny Guy            final OnSavePreferenceListener onSaveListener) {
9574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        super(context);
9674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        setPersistent(false);
973fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        mImi = imi;
98333f2bc71a0866053f8e2fce8efbfb0bcec68811Kenny Guy        mIsAllowedByOrganization = isAllowedByOrganization;
9974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        mOnSaveListener = onSaveListener;
10074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        if (!isImeEnabler) {
101a9341c38e3a3e38ebf6de1803304026b84d4c15dYohei Yukawa            // Remove switch widget.
102a9341c38e3a3e38ebf6de1803304026b84d4c15dYohei Yukawa            setWidgetLayoutResource(NO_WIDGET);
10374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        }
10474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        // Disable on/off switch texts.
10574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        setSwitchTextOn(EMPTY_TEXT);
10674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        setSwitchTextOff(EMPTY_TEXT);
10774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        setKey(imi.getId());
10874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        setTitle(imi.loadLabel(context.getPackageManager()));
10974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        final String settingsActivity = imi.getSettingsActivity();
11074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        if (TextUtils.isEmpty(settingsActivity)) {
11174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            setIntent(null);
11274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        } else {
11374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            // Set an intent to invoke settings activity of an input method.
11474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            final Intent intent = new Intent(Intent.ACTION_MAIN);
11574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            intent.setClassName(imi.getPackageName(), settingsActivity);
11674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            setIntent(intent);
11774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        }
11874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(context);
11974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        mHasPriorityInSorting = InputMethodUtils.isSystemIme(imi)
12074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                && mInputMethodSettingValues.isValidSystemNonAuxAsciiCapableIme(imi, context);
12174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        setOnPreferenceClickListener(this);
12274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        setOnPreferenceChangeListener(this);
1233fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
1243fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
1259a8b4f239f219bb2cd2d08470b8c858fd74341e7Tadashi G. Takaoka    public InputMethodInfo getInputMethodInfo() {
1269a8b4f239f219bb2cd2d08470b8c858fd74341e7Tadashi G. Takaoka        return mImi;
1279a8b4f239f219bb2cd2d08470b8c858fd74341e7Tadashi G. Takaoka    }
1289a8b4f239f219bb2cd2d08470b8c858fd74341e7Tadashi G. Takaoka
12974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    private boolean isImeEnabler() {
13074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        // If this {@link SwitchPreference} doesn't have a widget layout, we explicitly hide the
13174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        // switch widget at constructor.
132a9341c38e3a3e38ebf6de1803304026b84d4c15dYohei Yukawa        return getWidgetLayoutResource() != NO_WIDGET;
1333fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
1343fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
1353fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    @Override
13674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    public boolean onPreferenceChange(final Preference preference, final Object newValue) {
13774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        // Always returns false to prevent default behavior.
13874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        // See {@link TwoStatePreference#onClick()}.
13974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        if (!isImeEnabler()) {
14074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            // Prevent disabling an IME because this preference is for invoking a settings activity.
14174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            return false;
1423fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
14374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        if (isChecked()) {
14474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            // Disable this IME.
14574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            setChecked(false);
14674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            mOnSaveListener.onSaveInputMethodPreference(this);
14774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            return false;
148054fc44cae0d412ca5e72c709f0d5e3deb7768a7satok        }
14974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        if (InputMethodUtils.isSystemIme(mImi)) {
15074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            // Enable a system IME. No need to show a security warning dialog.
15174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            setChecked(true);
15274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            mOnSaveListener.onSaveInputMethodPreference(this);
15374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            return false;
1543fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
15574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        // Enable a 3rd party IME.
15674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        showSecurityWarnDialog(mImi);
15774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        return false;
1583fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
1593fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
16074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    @Override
16174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    public boolean onPreferenceClick(final Preference preference) {
16274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        // Always returns true to prevent invoking an intent without catching exceptions.
16374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        // See {@link Preference#performClick(PreferenceScreen)}/
16474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        if (isImeEnabler()) {
16574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            // Prevent invoking a settings activity because this preference is for enabling and
16674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            // disabling an input method.
1673fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            return true;
1683fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
16974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        final Context context = getContext();
17074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        try {
17174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            final Intent intent = getIntent();
17274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            if (intent != null) {
17374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                // Invoke a settings activity of an input method.
17474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                context.startActivity(intent);
1753fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            }
17674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        } catch (final ActivityNotFoundException e) {
17774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            Log.d(TAG, "IME's Settings Activity Not Found", e);
17874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            final String message = context.getString(
17974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                    R.string.failed_to_open_app_settings_toast,
18074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                    mImi.loadLabel(context.getPackageManager()));
18174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
18274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        }
18374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        return true;
1843fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
1853fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
18674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    void updatePreferenceViews() {
18774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        final boolean isAlwaysChecked = mInputMethodSettingValues.isAlwaysCheckedIme(
18874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                mImi, getContext());
189f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka        // When this preference has a switch and an input method should be always enabled,
19074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        // this preference should be disabled to prevent accidentally disabling an input method.
191f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka        // This preference should also be disabled in case the admin does not allow this input
192f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka        // method.
193f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka        if (isAlwaysChecked && isImeEnabler()) {
194f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka            setDisabledByAdmin(null);
195f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka            setEnabled(false);
196f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka        } else if (!mIsAllowedByOrganization) {
197f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka            EnforcedAdmin admin =
198f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka                    RestrictedLockUtils.checkIfInputMethodDisallowed(getContext(),
199f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka                            mImi.getPackageName(), UserHandle.myUserId());
200f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka            setDisabledByAdmin(admin);
201f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka        } else {
202f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka            setEnabled(true);
203f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka        }
20474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        setChecked(mInputMethodSettingValues.isEnabledImi(mImi));
205f755baf1c3b8fcbcee68720c8367e03381fffb4bSudheer Shanka        if (!isDisabledByAdmin()) {
206ba1a68b8abecf64fbcb53fdf0c3e46f63defe17dSudheer Shanka            setSummary(getSummaryString());
207ba1a68b8abecf64fbcb53fdf0c3e46f63defe17dSudheer Shanka        }
2083fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
2093fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
21074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    private InputMethodManager getInputMethodManager() {
21174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        return (InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
2123fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
2133fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
21474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    private String getSummaryString() {
21574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        final InputMethodManager imm = getInputMethodManager();
21674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(mImi, true);
21791c23ca03f9ffa9ac9f2644e50e51e481a423662Yohei Yukawa        return InputMethodAndSubtypeUtil.getSubtypeLocaleNameListAsSentence(
21891c23ca03f9ffa9ac9f2644e50e51e481a423662Yohei Yukawa                subtypes, getContext(), mImi);
219f6d8961843f5b977640146dd5dc8872eaab60ce7Amith Yamasani    }
220f6d8961843f5b977640146dd5dc8872eaab60ce7Amith Yamasani
22174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    private void showSecurityWarnDialog(final InputMethodInfo imi) {
2223fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        if (mDialog != null && mDialog.isShowing()) {
2233fa13775e805df6cc7244d3f93105c5d3a5b748fsatok            mDialog.dismiss();
2243fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
22574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        final Context context = getContext();
22674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
22774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        builder.setCancelable(true /* cancelable */);
22874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        builder.setTitle(android.R.string.dialog_alert_title);
22974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        final CharSequence label = imi.getServiceInfo().applicationInfo.loadLabel(
23074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                context.getPackageManager());
23174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        builder.setMessage(context.getString(R.string.ime_security_warning, label));
23274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
23374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            @Override
23474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            public void onClick(final DialogInterface dialog, final int which) {
23574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                // The user confirmed to enable a 3rd party IME.
23674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                setChecked(true);
23774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                mOnSaveListener.onSaveInputMethodPreference(InputMethodPreference.this);
23874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                notifyChanged();
23974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            }
24074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        });
24174e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
24274e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            @Override
24374e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            public void onClick(final DialogInterface dialog, final int which) {
24474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                // The user canceled to enable a 3rd party IME.
24574e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                setChecked(false);
24674e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                mOnSaveListener.onSaveInputMethodPreference(InputMethodPreference.this);
24774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka                notifyChanged();
24874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            }
24974e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        });
25074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        mDialog = builder.create();
2513fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        mDialog.show();
2523fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
2533fa13775e805df6cc7244d3f93105c5d3a5b748fsatok
25474e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka    int compareTo(final InputMethodPreference rhs, final Collator collator) {
25555aee124063dc28e740efcfdadafa5738b0b538aTadashi G. Takaoka        if (this == rhs) {
25655aee124063dc28e740efcfdadafa5738b0b538aTadashi G. Takaoka            return 0;
25755aee124063dc28e740efcfdadafa5738b0b538aTadashi G. Takaoka        }
25874e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        if (mHasPriorityInSorting == rhs.mHasPriorityInSorting) {
259ef120bea7b8cb3b891ae3f39d7a97989c107a16fSatoshi Kataoka            final CharSequence t0 = getTitle();
26074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            final CharSequence t1 = rhs.getTitle();
261ef120bea7b8cb3b891ae3f39d7a97989c107a16fSatoshi Kataoka            if (TextUtils.isEmpty(t0)) {
262ef120bea7b8cb3b891ae3f39d7a97989c107a16fSatoshi Kataoka                return 1;
263ef120bea7b8cb3b891ae3f39d7a97989c107a16fSatoshi Kataoka            }
264ef120bea7b8cb3b891ae3f39d7a97989c107a16fSatoshi Kataoka            if (TextUtils.isEmpty(t1)) {
265ef120bea7b8cb3b891ae3f39d7a97989c107a16fSatoshi Kataoka                return -1;
266ef120bea7b8cb3b891ae3f39d7a97989c107a16fSatoshi Kataoka            }
26774e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka            return collator.compare(t0.toString(), t1.toString());
2683fa13775e805df6cc7244d3f93105c5d3a5b748fsatok        }
269ef120bea7b8cb3b891ae3f39d7a97989c107a16fSatoshi Kataoka        // Prefer always checked system IMEs
27074e7c3e3601f4808854cf12bffe11ebf4c6ea8abTadashi G. Takaoka        return mHasPriorityInSorting ? -1 : 1;
2713fa13775e805df6cc7244d3f93105c5d3a5b748fsatok    }
2723fa13775e805df6cc7244d3f93105c5d3a5b748fsatok}
273