/* * Copyright (C) 2016 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 android.app.Activity; import android.app.admin.DevicePolicyManager; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.res.Configuration; import android.os.Bundle; import android.provider.SearchIndexableResource; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtilCompat; import com.android.settingslib.inputmethod.InputMethodPreference; import com.android.settingslib.inputmethod.InputMethodSettingValuesWrapper; import com.android.settingslib.search.SearchIndexable; import java.text.Collator; import java.util.ArrayList; import java.util.List; @SearchIndexable public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFragment implements InputMethodPreference.OnSavePreferenceListener { private final ArrayList mInputMethodPreferenceList = new ArrayList<>(); private InputMethodSettingValuesWrapper mInputMethodSettingValues; private InputMethodManager mImm; private DevicePolicyManager mDpm; @Override public void onCreatePreferences(Bundle bundle, String s) { addPreferencesFromResource(R.xml.available_virtual_keyboard); Activity activity = getActivity(); mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(activity); mImm = activity.getSystemService(InputMethodManager.class); mDpm = activity.getSystemService(DevicePolicyManager.class); } @Override public void onResume() { super.onResume(); // Refresh internal states in mInputMethodSettingValues to keep the latest // "InputMethodInfo"s and "InputMethodSubtype"s mInputMethodSettingValues.refreshAllInputMethodAndSubtypes(); updateInputMethodPreferenceViews(); } @Override public void onSaveInputMethodPreference(final InputMethodPreference pref) { final boolean hasHardwareKeyboard = getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY; InputMethodAndSubtypeUtilCompat.saveInputMethodSubtypeList(this, getContentResolver(), mImm.getInputMethodList(), hasHardwareKeyboard); // Update input method settings and preference list. mInputMethodSettingValues.refreshAllInputMethodAndSubtypes(); for (final InputMethodPreference p : mInputMethodPreferenceList) { p.updatePreferenceViews(); } } @Override public int getMetricsCategory() { return SettingsEnums.ENABLE_VIRTUAL_KEYBOARDS; } private void updateInputMethodPreferenceViews() { mInputMethodSettingValues.refreshAllInputMethodAndSubtypes(); // Clear existing "InputMethodPreference"s mInputMethodPreferenceList.clear(); List permittedList = mDpm.getPermittedInputMethodsForCurrentUser(); final Context context = getPrefContext(); final List imis = mInputMethodSettingValues.getInputMethodList(); final List enabledImis = mImm.getEnabledInputMethodList(); final int numImis = (imis == null ? 0 : imis.size()); for (int i = 0; i < numImis; ++i) { final InputMethodInfo imi = imis.get(i); // TODO (b/182876800): Move this logic out of isAllowedByOrganization and // into a new boolean. // If an input method is enabled but not included in the permitted list, then set it as // allowed by organization. Doing so will allow the user to disable the input method and // remain complaint with the organization's policy. Once disabled, the input method // cannot be re-enabled because it is not in the permitted list. final boolean isAllowedByOrganization = permittedList == null || permittedList.contains(imi.getPackageName()) || enabledImis.contains(imi); final InputMethodPreference pref = new InputMethodPreference( context, imi, true, isAllowedByOrganization, this); pref.setIcon(imi.loadIcon(context.getPackageManager())); mInputMethodPreferenceList.add(pref); } final Collator collator = Collator.getInstance(); mInputMethodPreferenceList.sort((lhs, rhs) -> lhs.compareTo(rhs, collator)); getPreferenceScreen().removeAll(); for (int i = 0; i < numImis; ++i) { final InputMethodPreference pref = mInputMethodPreferenceList.get(i); pref.setOrder(i); getPreferenceScreen().addPreference(pref); InputMethodAndSubtypeUtilCompat.removeUnnecessaryNonPersistentPreference(pref); pref.updatePreferenceViews(); } } public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider() { @Override public List getXmlResourcesToIndex(Context context, boolean enabled) { List res = new ArrayList<>(); SearchIndexableResource index = new SearchIndexableResource(context); index.xmlResId = R.xml.available_virtual_keyboard; res.add(index); return res; } }; }