1976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki/* 2976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * Copyright (C) 2016 The Android Open Source Project 3976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * 4976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * Licensed under the Apache License, Version 2.0 (the "License"); 5976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * you may not use this file except in compliance with the License. 6976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * You may obtain a copy of the License at 7976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * 8976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * http://www.apache.org/licenses/LICENSE-2.0 9976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * 10976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * Unless required by applicable law or agreed to in writing, software 11976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * distributed under the License is distributed on an "AS IS" BASIS, 12976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * See the License for the specific language governing permissions and 14976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki * limitations under the License. 15976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki */ 16976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki 17976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokipackage com.android.settings.inputmethod; 18976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki 19976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport android.app.Activity; 20976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport android.app.admin.DevicePolicyManager; 21976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport android.content.Context; 22567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Tokiimport android.graphics.Color; 23567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Tokiimport android.graphics.drawable.ColorDrawable; 24567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Tokiimport android.graphics.drawable.Drawable; 25976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport android.os.Bundle; 26e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport android.provider.SearchIndexableResource; 27976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport android.support.v7.preference.Preference; 28976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport android.view.inputmethod.InputMethodInfo; 29976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport android.view.inputmethod.InputMethodManager; 30e776821a8d5429bfe9e2aa259169d6980718f420Tadashi G. Takaoka 31265d3c2a0c36251bf8a9f571d7239b6dd404d942Tamas Berghammerimport com.android.internal.logging.nano.MetricsProto.MetricsEvent; 32976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport com.android.internal.util.Preconditions; 33976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport com.android.settings.R; 34976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport com.android.settings.SettingsPreferenceFragment; 35e776821a8d5429bfe9e2aa259169d6980718f420Tadashi G. Takaokaimport com.android.settings.search.BaseSearchIndexProvider; 36e776821a8d5429bfe9e2aa259169d6980718f420Tadashi G. Takaokaimport com.android.settings.search.Indexable; 374d27b2ce5bea7d29f81cf30104b4e176c066fc72Tony Mantlerimport com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil; 382ec69563cdfbeae7cf4f729d93b4cf32f7065698Tony Mantlerimport com.android.settingslib.inputmethod.InputMethodPreference; 39976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki 40976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport java.text.Collator; 41976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport java.util.ArrayList; 42e3535d9998363cbf352b5f8feb9277475e380944Fan Zhangimport java.util.Arrays; 43976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Tokiimport java.util.List; 44976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki 45e776821a8d5429bfe9e2aa259169d6980718f420Tadashi G. Takaokapublic final class VirtualKeyboardFragment extends SettingsPreferenceFragment implements Indexable { 46976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki 47976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki private static final String ADD_VIRTUAL_KEYBOARD_SCREEN = "add_virtual_keyboard_screen"; 48567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Toki private static final Drawable NO_ICON = new ColorDrawable(Color.TRANSPARENT); 49976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki 50976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki private final ArrayList<InputMethodPreference> mInputMethodPreferenceList = new ArrayList<>(); 51976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki private InputMethodManager mImm; 52976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki private DevicePolicyManager mDpm; 53976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki private Preference mAddVirtualKeyboardScreen; 54976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki 55976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki @Override 56976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki public void onCreatePreferences(Bundle bundle, String s) { 57976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki Activity activity = Preconditions.checkNotNull(getActivity()); 58976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki addPreferencesFromResource(R.xml.virtual_keyboard_settings); 59976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki mImm = Preconditions.checkNotNull(activity.getSystemService(InputMethodManager.class)); 60976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki mDpm = Preconditions.checkNotNull(activity.getSystemService(DevicePolicyManager.class)); 61976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki mAddVirtualKeyboardScreen = Preconditions.checkNotNull( 62976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki findPreference(ADD_VIRTUAL_KEYBOARD_SCREEN)); 63976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki } 64976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki 65976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki @Override 66976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki public void onResume() { 67976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki super.onResume(); 68976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki // Refresh internal states in mInputMethodSettingValues to keep the latest 69976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki // "InputMethodInfo"s and "InputMethodSubtype"s 70976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki updateInputMethodPreferenceViews(); 71976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki } 72976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki 73976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki @Override 746507613ebcd22e4691c2af92a5c161bd327db336Fan Zhang public int getMetricsCategory() { 753e19fc5600f739e7f172fb9331cfc0f4a884d4ceJason Monk return MetricsEvent.VIRTUAL_KEYBOARDS; 76976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki } 77976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki 78976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki private void updateInputMethodPreferenceViews() { 79976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki // Clear existing "InputMethodPreference"s 80976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki mInputMethodPreferenceList.clear(); 81976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki List<String> permittedList = mDpm.getPermittedInputMethodsForCurrentUser(); 82976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki final Context context = getPrefContext(); 83976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki final List<InputMethodInfo> imis = mImm.getEnabledInputMethodList(); 84976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki final int N = (imis == null ? 0 : imis.size()); 85976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki for (int i = 0; i < N; ++i) { 86976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki final InputMethodInfo imi = imis.get(i); 87976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki final boolean isAllowedByOrganization = permittedList == null 88976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki || permittedList.contains(imi.getPackageName()); 89567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Toki Drawable icon; 90567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Toki try { 91567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Toki // TODO: Consider other ways to retrieve an icon to show here. 92567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Toki icon = getActivity().getPackageManager().getApplicationIcon(imi.getPackageName()); 93567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Toki } catch (Exception e) { 94567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Toki // TODO: Consider handling the error differently perhaps by showing default icons. 95567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Toki icon = NO_ICON; 96567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Toki } 97976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki final InputMethodPreference pref = new InputMethodPreference( 98976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki context, 99976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki imi, 100976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki false, /* isImeEnabler */ 101976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki isAllowedByOrganization, 102976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki null /* this can be null since isImeEnabler is false */); 103567ebd68e1e0c1621d51e252f8456411f9daa656Abodunrinwa Toki pref.setIcon(icon); 104976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki mInputMethodPreferenceList.add(pref); 105976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki } 106976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki final Collator collator = Collator.getInstance(); 1072ec69563cdfbeae7cf4f729d93b4cf32f7065698Tony Mantler mInputMethodPreferenceList.sort((lhs, rhs) -> lhs.compareTo(rhs, collator)); 108976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki getPreferenceScreen().removeAll(); 109976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki for (int i = 0; i < N; ++i) { 110976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki final InputMethodPreference pref = mInputMethodPreferenceList.get(i); 111976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki pref.setOrder(i); 112976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki getPreferenceScreen().addPreference(pref); 113976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference(pref); 114976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki pref.updatePreferenceViews(); 115976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki } 116a1bda3aa9fbf45b93da97a4249ab1e5ea63ef8b9Abodunrinwa Toki mAddVirtualKeyboardScreen.setIcon(R.drawable.ic_add_24dp); 117976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki mAddVirtualKeyboardScreen.setOrder(N); 118976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki getPreferenceScreen().addPreference(mAddVirtualKeyboardScreen); 119976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki } 120e776821a8d5429bfe9e2aa259169d6980718f420Tadashi G. Takaoka 121e776821a8d5429bfe9e2aa259169d6980718f420Tadashi G. Takaoka public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 122e776821a8d5429bfe9e2aa259169d6980718f420Tadashi G. Takaoka new BaseSearchIndexProvider() { 123e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang @Override 124e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang public List<SearchIndexableResource> getXmlResourcesToIndex( 125e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang Context context, boolean enabled) { 126e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang final SearchIndexableResource sir = new SearchIndexableResource(context); 127e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang sir.xmlResId = R.xml.virtual_keyboard_settings; 128e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang return Arrays.asList(sir); 129e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang } 130e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang 131e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang @Override 132e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang public List<String> getNonIndexableKeys(Context context) { 133e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang final List<String> keys = super.getNonIndexableKeys(context); 134e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang keys.add("add_virtual_keyboard_screen"); 135e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang return keys; 136e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang } 137e3535d9998363cbf352b5f8feb9277475e380944Fan Zhang }; 138976bb3f45915bdd5165d9a50402d4c1163dae809Abodunrinwa Toki} 139