OSDN Git Service

Add AvailableVirtualKeyboardFragment to TV
authorTony Mantler <nicoya@google.com>
Fri, 31 Mar 2017 20:54:17 +0000 (13:54 -0700)
committerTony Mantler <nicoya@google.com>
Tue, 4 Apr 2017 15:49:47 +0000 (15:49 +0000)
Allows enabling/disabling IMEs on TV.
Moves InputMethodPreference to SettingsLib.
Also minor code tidying

Bug: 36079941
Test: Keyboard settings still work on Fugu and Ryu
Change-Id: Idf42cf5c46d5bb32db59924819d64f73d533d105
(cherry picked from commit 2ec69563cdfbeae7cf4f729d93b4cf32f7065698)

res/values/strings.xml
src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
src/com/android/settings/inputmethod/InputMethodPreference.java [deleted file]
src/com/android/settings/inputmethod/VirtualKeyboardFragment.java

index 3173e85..8925dcd 100644 (file)
     <string name="show_password">Show passwords</string>
     <!-- On Security & location settings screen. This is a short summary text describing what "Show passwords" setting does -->
     <string name="show_password_summary">Display characters briefly as you type</string>
-    <!-- Warning message about security implications of enabling an input method, displayed as a dialog
-         message when the user selects to enable an IME. -->
-    <string name="ime_security_warning">This input method may be able to collect
-    all the text you type, including personal data like passwords and credit
-    card numbers.  It comes from the app
-    <xliff:g id="ime_application_name">%1$s</xliff:g>.
-    Use this input method?</string>
     <!-- Warning message about security implications of enabling a spell checker, displayed as a dialog
          message when the user selects to enable a spell checker. -->
     <string name="spellchecker_security_warning">This spell checker may be able to collect
     <string name="spellchecker_quick_settings">Settings</string>
     <!-- Image button description for spell checker language. -->
     <string name="spellchecker_language">Language</string>
-    <!-- Toast that settings for an application is failed to open. -->
-    <string name="failed_to_open_app_settings_toast">Failed to open settings for <xliff:g id="spell_application_name">%1$s</xliff:g></string>
-
     <!-- Title for the 'keyboard and input methods' preference category. [CHAR LIMIT=45] -->
     <string name="keyboard_and_input_methods_category">Keyboard &amp; inputs</string>
     <!-- Title for the 'virtual keyboard' preference sub-screen. [CHAR LIMIT=35] -->
index a6df7a3..a7862ae 100644 (file)
@@ -43,12 +43,11 @@ import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
+import com.android.settingslib.inputmethod.InputMethodPreference;
 import com.android.settingslib.inputmethod.InputMethodSettingValuesWrapper;
 
 import java.text.Collator;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
 public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFragment
@@ -115,7 +114,7 @@ public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFr
     private static Drawable getInputMethodIcon(@NonNull final PackageManager packageManager,
             @NonNull final InputMethodInfo imi) {
         final ServiceInfo si = imi.getServiceInfo();
-        final ApplicationInfo ai = si.applicationInfo;
+        final ApplicationInfo ai = si != null ? si.applicationInfo : null;
         final String packageName = imi.getPackageName();
         if (si == null || ai == null || packageName == null) {
             return new ColorDrawable(Color.TRANSPARENT);
@@ -151,8 +150,8 @@ public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFr
         final Context context = getPrefContext();
         final PackageManager packageManager = getActivity().getPackageManager();
         final List<InputMethodInfo> imis = mInputMethodSettingValues.getInputMethodList();
-        final int N = (imis == null ? 0 : imis.size());
-        for (int i = 0; i < N; ++i) {
+        final int numImis = (imis == null ? 0 : imis.size());
+        for (int i = 0; i < numImis; ++i) {
             final InputMethodInfo imi = imis.get(i);
             final boolean isAllowedByOrganization = permittedList == null
                     || permittedList.contains(imi.getPackageName());
@@ -162,14 +161,9 @@ public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFr
             mInputMethodPreferenceList.add(pref);
         }
         final Collator collator = Collator.getInstance();
-        Collections.sort(mInputMethodPreferenceList, new Comparator<InputMethodPreference>() {
-            @Override
-            public int compare(InputMethodPreference lhs, InputMethodPreference rhs) {
-                return lhs.compareTo(rhs, collator);
-            }
-        });
+        mInputMethodPreferenceList.sort((lhs, rhs) -> lhs.compareTo(rhs, collator));
         getPreferenceScreen().removeAll();
-        for (int i = 0; i < N; ++i) {
+        for (int i = 0; i < numImis; ++i) {
             final InputMethodPreference pref = mInputMethodPreferenceList.get(i);
             pref.setOrder(i);
             getPreferenceScreen().addPreference(pref);
@@ -190,8 +184,6 @@ public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFr
     static List<SearchIndexableRaw> buildSearchIndexOfInputMethods(final Context context,
             final List<InputMethodInfo> inputMethods, final String screenTitle) {
         final List<SearchIndexableRaw> indexes = new ArrayList<>();
-        final InputMethodManager imm = (InputMethodManager) context.getSystemService(
-                Context.INPUT_METHOD_SERVICE);
         for (int i = 0; i < inputMethods.size(); i++) {
             final InputMethodInfo imi = inputMethods.get(i);
             final ServiceInfo serviceInfo = imi.getServiceInfo();
@@ -207,7 +199,7 @@ public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFr
         return indexes;
     }
 
-    public static Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
         @Override
         public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
diff --git a/src/com/android/settings/inputmethod/InputMethodPreference.java b/src/com/android/settings/inputmethod/InputMethodPreference.java
deleted file mode 100755 (executable)
index 463a043..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.inputmethod;
-
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.UserHandle;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
-import android.widget.Toast;
-
-import com.android.internal.inputmethod.InputMethodUtils;
-import com.android.settings.R;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
-import com.android.settingslib.inputmethod.InputMethodSettingValuesWrapper;
-
-import java.text.Collator;
-import java.util.List;
-
-/**
- * Input method preference.
- *
- * This preference represents an IME. It is used for two purposes. 1) An instance with a switch
- * is used to enable or disable the IME. 2) An instance without a switch is used to invoke the
- * setting activity of the IME.
- */
-class InputMethodPreference extends RestrictedSwitchPreference implements OnPreferenceClickListener,
-        OnPreferenceChangeListener {
-    private static final String TAG = InputMethodPreference.class.getSimpleName();
-    private static final String EMPTY_TEXT = "";
-    private static final int NO_WIDGET = 0;
-
-    interface OnSavePreferenceListener {
-        /**
-         * Called when this preference needs to be saved its state.
-         *
-         * Note that this preference is non-persistent and needs explicitly to be saved its state.
-         * Because changing one IME state may change other IMEs' state, this is a place to update
-         * other IMEs' state as well.
-         *
-         * @param pref This preference.
-         */
-        public void onSaveInputMethodPreference(InputMethodPreference pref);
-    }
-
-    private final InputMethodInfo mImi;
-    private final boolean mHasPriorityInSorting;
-    private final OnSavePreferenceListener mOnSaveListener;
-    private final InputMethodSettingValuesWrapper mInputMethodSettingValues;
-    private final boolean mIsAllowedByOrganization;
-
-    private AlertDialog mDialog = null;
-
-    /**
-     * A preference entry of an input method.
-     *
-     * @param context The Context this is associated with.
-     * @param imi The {@link InputMethodInfo} of this preference.
-     * @param isImeEnabler true if this preference is the IME enabler that has enable/disable
-     *     switches for all available IMEs, not the list of enabled IMEs.
-     * @param isAllowedByOrganization false if the IME has been disabled by a device or profile
-     *     owner.
-     * @param onSaveListener The listener called when this preference has been changed and needs
-     *     to save the state to shared preference.
-     */
-    InputMethodPreference(final Context context, final InputMethodInfo imi,
-            final boolean isImeEnabler, final boolean isAllowedByOrganization,
-            final OnSavePreferenceListener onSaveListener) {
-        super(context);
-        setPersistent(false);
-        mImi = imi;
-        mIsAllowedByOrganization = isAllowedByOrganization;
-        mOnSaveListener = onSaveListener;
-        if (!isImeEnabler) {
-            // Remove switch widget.
-            setWidgetLayoutResource(NO_WIDGET);
-        }
-        // Disable on/off switch texts.
-        setSwitchTextOn(EMPTY_TEXT);
-        setSwitchTextOff(EMPTY_TEXT);
-        setKey(imi.getId());
-        setTitle(imi.loadLabel(context.getPackageManager()));
-        final String settingsActivity = imi.getSettingsActivity();
-        if (TextUtils.isEmpty(settingsActivity)) {
-            setIntent(null);
-        } else {
-            // Set an intent to invoke settings activity of an input method.
-            final Intent intent = new Intent(Intent.ACTION_MAIN);
-            intent.setClassName(imi.getPackageName(), settingsActivity);
-            setIntent(intent);
-        }
-        mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(context);
-        mHasPriorityInSorting = InputMethodUtils.isSystemIme(imi)
-                && mInputMethodSettingValues.isValidSystemNonAuxAsciiCapableIme(imi, context);
-        setOnPreferenceClickListener(this);
-        setOnPreferenceChangeListener(this);
-    }
-
-    public InputMethodInfo getInputMethodInfo() {
-        return mImi;
-    }
-
-    private boolean isImeEnabler() {
-        // If this {@link SwitchPreference} doesn't have a widget layout, we explicitly hide the
-        // switch widget at constructor.
-        return getWidgetLayoutResource() != NO_WIDGET;
-    }
-
-    @Override
-    public boolean onPreferenceChange(final Preference preference, final Object newValue) {
-        // Always returns false to prevent default behavior.
-        // See {@link TwoStatePreference#onClick()}.
-        if (!isImeEnabler()) {
-            // Prevent disabling an IME because this preference is for invoking a settings activity.
-            return false;
-        }
-        if (isChecked()) {
-            // Disable this IME.
-            setCheckedInternal(false);
-            return false;
-        }
-        if (InputMethodUtils.isSystemIme(mImi)) {
-            // Enable a system IME. No need to show a security warning dialog,
-            // but we might need to prompt if it's not Direct Boot aware.
-            if (mImi.getServiceInfo().directBootAware) {
-                setCheckedInternal(true);
-            } else {
-                showDirectBootWarnDialog();
-            }
-        } else {
-            // Once security is confirmed, we might prompt if the IME isn't
-            // Direct Boot aware.
-            showSecurityWarnDialog();
-        }
-        return false;
-    }
-
-    @Override
-    public boolean onPreferenceClick(final Preference preference) {
-        // Always returns true to prevent invoking an intent without catching exceptions.
-        // See {@link Preference#performClick(PreferenceScreen)}/
-        if (isImeEnabler()) {
-            // Prevent invoking a settings activity because this preference is for enabling and
-            // disabling an input method.
-            return true;
-        }
-        final Context context = getContext();
-        try {
-            final Intent intent = getIntent();
-            if (intent != null) {
-                // Invoke a settings activity of an input method.
-                context.startActivity(intent);
-            }
-        } catch (final ActivityNotFoundException e) {
-            Log.d(TAG, "IME's Settings Activity Not Found", e);
-            final String message = context.getString(
-                    R.string.failed_to_open_app_settings_toast,
-                    mImi.loadLabel(context.getPackageManager()));
-            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
-        }
-        return true;
-    }
-
-    void updatePreferenceViews() {
-        final boolean isAlwaysChecked = mInputMethodSettingValues.isAlwaysCheckedIme(
-                mImi, getContext());
-        // When this preference has a switch and an input method should be always enabled,
-        // this preference should be disabled to prevent accidentally disabling an input method.
-        // This preference should also be disabled in case the admin does not allow this input
-        // method.
-        if (isAlwaysChecked && isImeEnabler()) {
-            setDisabledByAdmin(null);
-            setEnabled(false);
-        } else if (!mIsAllowedByOrganization) {
-            EnforcedAdmin admin =
-                    RestrictedLockUtils.checkIfInputMethodDisallowed(getContext(),
-                            mImi.getPackageName(), UserHandle.myUserId());
-            setDisabledByAdmin(admin);
-        } else {
-            setEnabled(true);
-        }
-        setChecked(mInputMethodSettingValues.isEnabledImi(mImi));
-        if (!isDisabledByAdmin()) {
-            setSummary(getSummaryString());
-        }
-    }
-
-    private InputMethodManager getInputMethodManager() {
-        return (InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-    }
-
-    private String getSummaryString() {
-        final InputMethodManager imm = getInputMethodManager();
-        final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(mImi, true);
-        return InputMethodAndSubtypeUtil.getSubtypeLocaleNameListAsSentence(
-                subtypes, getContext(), mImi);
-    }
-
-    private void setCheckedInternal(boolean checked) {
-        super.setChecked(checked);
-        mOnSaveListener.onSaveInputMethodPreference(InputMethodPreference.this);
-        notifyChanged();
-    }
-
-    private void showSecurityWarnDialog() {
-        if (mDialog != null && mDialog.isShowing()) {
-            mDialog.dismiss();
-        }
-        final Context context = getContext();
-        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-        builder.setCancelable(true /* cancelable */);
-        builder.setTitle(android.R.string.dialog_alert_title);
-        final CharSequence label = mImi.getServiceInfo().applicationInfo.loadLabel(
-                context.getPackageManager());
-        builder.setMessage(context.getString(R.string.ime_security_warning, label));
-        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(final DialogInterface dialog, final int which) {
-                // The user confirmed to enable a 3rd party IME, but we might
-                // need to prompt if it's not Direct Boot aware.
-                if (mImi.getServiceInfo().directBootAware) {
-                    setCheckedInternal(true);
-                } else {
-                    showDirectBootWarnDialog();
-                }
-            }
-        });
-        builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(final DialogInterface dialog, final int which) {
-                // The user canceled to enable a 3rd party IME.
-                setCheckedInternal(false);
-            }
-        });
-        mDialog = builder.create();
-        mDialog.show();
-    }
-
-    private void showDirectBootWarnDialog() {
-        if (mDialog != null && mDialog.isShowing()) {
-            mDialog.dismiss();
-        }
-        final Context context = getContext();
-        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-        builder.setCancelable(true /* cancelable */);
-        builder.setMessage(context.getText(R.string.direct_boot_unaware_dialog_message));
-        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(final DialogInterface dialog, final int which) {
-                setCheckedInternal(true);
-            }
-        });
-        builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(final DialogInterface dialog, final int which) {
-                setCheckedInternal(false);
-            }
-        });
-        mDialog = builder.create();
-        mDialog.show();
-    }
-
-    int compareTo(final InputMethodPreference rhs, final Collator collator) {
-        if (this == rhs) {
-            return 0;
-        }
-        if (mHasPriorityInSorting == rhs.mHasPriorityInSorting) {
-            final CharSequence t0 = getTitle();
-            final CharSequence t1 = rhs.getTitle();
-            if (TextUtils.isEmpty(t0)) {
-                return 1;
-            }
-            if (TextUtils.isEmpty(t1)) {
-                return -1;
-            }
-            return collator.compare(t0.toString(), t1.toString());
-        }
-        // Prefer always checked system IMEs
-        return mHasPriorityInSorting ? -1 : 1;
-    }
-}
index c362389..7b7c599 100644 (file)
@@ -35,6 +35,7 @@ import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
+import com.android.settingslib.inputmethod.InputMethodPreference;
 
 import java.text.Collator;
 import java.util.ArrayList;
@@ -104,12 +105,7 @@ public final class VirtualKeyboardFragment extends SettingsPreferenceFragment im
             mInputMethodPreferenceList.add(pref);
         }
         final Collator collator = Collator.getInstance();
-        Collections.sort(mInputMethodPreferenceList, new Comparator<InputMethodPreference>() {
-            @Override
-            public int compare(InputMethodPreference lhs, InputMethodPreference rhs) {
-                return lhs.compareTo(rhs, collator);
-            }
-        });
+        mInputMethodPreferenceList.sort((lhs, rhs) -> lhs.compareTo(rhs, collator));
         getPreferenceScreen().removeAll();
         for (int i = 0; i < N; ++i) {
             final InputMethodPreference pref = mInputMethodPreferenceList.get(i);