1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.language; 18 19 import android.app.Activity; 20 import android.content.ComponentName; 21 import android.content.ContentResolver; 22 import android.content.Context; 23 import android.content.pm.PackageManager; 24 import android.provider.SearchIndexableResource; 25 import android.provider.Settings; 26 import android.speech.tts.TtsEngines; 27 import android.support.annotation.NonNull; 28 import android.support.annotation.Nullable; 29 import android.text.TextUtils; 30 import android.view.inputmethod.InputMethodInfo; 31 import android.view.inputmethod.InputMethodManager; 32 33 import com.android.internal.logging.nano.MetricsProto; 34 import com.android.settings.R; 35 import com.android.settings.applications.defaultapps.DefaultAutofillPreferenceController; 36 import com.android.settings.dashboard.DashboardFragment; 37 import com.android.settings.dashboard.SummaryLoader; 38 import com.android.settings.inputmethod.GameControllerPreferenceController; 39 import com.android.settings.inputmethod.PhysicalKeyboardPreferenceController; 40 import com.android.settings.inputmethod.SpellCheckerPreferenceController; 41 import com.android.settings.inputmethod.VirtualKeyboardPreferenceController; 42 import com.android.settings.search.BaseSearchIndexProvider; 43 import com.android.settingslib.core.AbstractPreferenceController; 44 import com.android.settingslib.core.lifecycle.Lifecycle; 45 46 import java.util.ArrayList; 47 import java.util.Arrays; 48 import java.util.List; 49 50 public class LanguageAndInputSettings extends DashboardFragment { 51 52 private static final String TAG = "LangAndInputSettings"; 53 54 private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary"; 55 private static final String KEY_PHYSICAL_KEYBOARD = "physical_keyboard_pref"; 56 57 @Override 58 public int getMetricsCategory() { 59 return MetricsProto.MetricsEvent.SETTINGS_LANGUAGE_CATEGORY; 60 } 61 62 @Override 63 protected String getLogTag() { 64 return TAG; 65 } 66 67 @Override 68 public void onAttach(Context context) { 69 super.onAttach(context); 70 mProgressiveDisclosureMixin.setTileLimit(2); 71 72 } 73 74 @Override 75 public void onResume() { 76 super.onResume(); 77 // Hack to update action bar title. It's necessary to refresh title because this page user 78 // can change locale from here and fragment won't relaunch. Once language changes, title 79 // must display in the new language. 80 final Activity activity = getActivity(); 81 if (activity == null) { 82 return; 83 } 84 activity.setTitle(R.string.language_settings); 85 } 86 87 @Override 88 protected int getPreferenceScreenResId() { 89 return R.xml.language_and_input; 90 } 91 92 @Override 93 protected List<AbstractPreferenceController> getPreferenceControllers(Context context) { 94 return buildPreferenceControllers(context, getLifecycle()); 95 } 96 97 private static List<AbstractPreferenceController> buildPreferenceControllers( 98 @NonNull Context context, @Nullable Lifecycle lifecycle) { 99 final List<AbstractPreferenceController> controllers = new ArrayList<>(); 100 // Language 101 controllers.add(new PhoneLanguagePreferenceController(context)); 102 controllers.add(new SpellCheckerPreferenceController(context)); 103 controllers.add(new UserDictionaryPreferenceController(context)); 104 controllers.add(new TtsPreferenceController(context, new TtsEngines(context))); 105 // Input 106 controllers.add(new VirtualKeyboardPreferenceController(context)); 107 controllers.add(new PhysicalKeyboardPreferenceController(context, lifecycle)); 108 final GameControllerPreferenceController gameControllerPreferenceController 109 = new GameControllerPreferenceController(context); 110 if (lifecycle != null) { 111 lifecycle.addObserver(gameControllerPreferenceController); 112 } 113 114 controllers.add(gameControllerPreferenceController); 115 controllers.add(new DefaultAutofillPreferenceController(context)); 116 return controllers; 117 } 118 119 private static class SummaryProvider implements SummaryLoader.SummaryProvider { 120 121 private final Context mContext; 122 private final SummaryLoader mSummaryLoader; 123 124 public SummaryProvider(Context context, SummaryLoader summaryLoader) { 125 mContext = context; 126 mSummaryLoader = summaryLoader; 127 } 128 129 @Override 130 public void setListening(boolean listening) { 131 final ContentResolver contentResolver = mContext.getContentResolver(); 132 if (listening) { 133 final String flattenComponent = Settings.Secure.getString( 134 contentResolver, Settings.Secure.DEFAULT_INPUT_METHOD); 135 if (!TextUtils.isEmpty(flattenComponent)) { 136 final PackageManager packageManage = mContext.getPackageManager(); 137 final String pkg = ComponentName.unflattenFromString(flattenComponent) 138 .getPackageName(); 139 final InputMethodManager imm = (InputMethodManager) 140 mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 141 final List<InputMethodInfo> imis = imm.getInputMethodList(); 142 for (InputMethodInfo imi : imis) { 143 if (TextUtils.equals(imi.getPackageName(), pkg)) { 144 mSummaryLoader.setSummary(this, imi.loadLabel(packageManage)); 145 return; 146 } 147 } 148 } 149 mSummaryLoader.setSummary(this, ""); 150 } 151 } 152 } 153 154 public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY 155 = (activity, summaryLoader) -> new SummaryProvider(activity, summaryLoader); 156 157 public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 158 new BaseSearchIndexProvider() { 159 @Override 160 public List<SearchIndexableResource> getXmlResourcesToIndex( 161 Context context, boolean enabled) { 162 final SearchIndexableResource sir = new SearchIndexableResource(context); 163 sir.xmlResId = R.xml.language_and_input; 164 return Arrays.asList(sir); 165 } 166 167 @Override 168 public List<AbstractPreferenceController> getPreferenceControllers( 169 Context context) { 170 return buildPreferenceControllers(context, null); 171 } 172 173 @Override 174 public List<String> getNonIndexableKeys(Context context) { 175 List<String> keys = super.getNonIndexableKeys(context); 176 // Duplicates in summary and details pages. 177 keys.add(KEY_TEXT_TO_SPEECH); 178 keys.add(KEY_PHYSICAL_KEYBOARD); 179 180 return keys; 181 } 182 }; 183 } 184