Refactor IMEAndLanguageSettings to use PreferenceController
Bug: 32642706
Bug: 32637613
Bug: 32643833
Test: RunSettingsRoboTests
This change is necessary to test preference controlling logic, as well
as making preferences reusable in other Preference pages in the new
information architecture.
Change-Id: I9e2fd2f6800579f005a5c303ed03ae06477006a6
diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml
index d829dc4..992af92 100644
--- a/res/xml/language_settings.xml
+++ b/res/xml/language_settings.xml
@@ -27,11 +27,11 @@
<!-- Spell checker preference title, summary and fragment will be set programmatically. -->
<!-- Note: Mark this as persistent="false" to remove unnecessarily saved shared preference.
See: InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference. -->
- <PreferenceScreen
- android:key="spellcheckers_settings"
- android:title="@string/spellcheckers_settings_title"
- android:persistent="false"
- />
+ <Preference
+ android:key="spellcheckers_settings"
+ android:title="@string/spellcheckers_settings_title"
+ android:fragment="com.android.settings.inputmethod.SpellCheckersSettings"
+ android:persistent="false"/>
<!-- User dictionary preference title and fragment will be set programmatically. -->
<PreferenceScreen
diff --git a/src/com/android/settings/VoiceInputOutputSettings.java b/src/com/android/settings/VoiceInputOutputSettings.java
deleted file mode 100644
index 3a8f1a5..0000000
--- a/src/com/android/settings/VoiceInputOutputSettings.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.speech.tts.TtsEngines;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceGroup;
-
-/**
- * Settings screen for voice input/output.
- */
-public class VoiceInputOutputSettings {
-
- private static final String TAG = "VoiceInputOutputSettings";
-
- private static final String KEY_VOICE_CATEGORY = "voice_category";
- private static final String KEY_TTS_SETTINGS = "tts_settings";
-
- private PreferenceGroup mParent;
- private PreferenceCategory mVoiceCategory;
- private Preference mVoiceInputSettingsPref;
- private Preference mTtsSettingsPref;
- private final SettingsPreferenceFragment mFragment;
- private final TtsEngines mTtsEngines;
-
- public VoiceInputOutputSettings(SettingsPreferenceFragment fragment) {
- mFragment = fragment;
- mTtsEngines = new TtsEngines(fragment.getPreferenceScreen().getContext());
- }
-
- public void onCreate() {
- mParent = mFragment.getPreferenceScreen();
- mVoiceCategory = (PreferenceCategory) mParent.findPreference(KEY_VOICE_CATEGORY);
- mTtsSettingsPref = mVoiceCategory.findPreference(KEY_TTS_SETTINGS);
-
- populateOrRemovePreferences();
- }
-
- private void populateOrRemovePreferences() {
- boolean hasTtsPrefs = populateOrRemoveTtsPrefs();
- if (!hasTtsPrefs) {
- // There were no TTS settings and no recognizer settings,
- // so it should be safe to hide the preference category
- // entirely.
- mFragment.getPreferenceScreen().removePreference(mVoiceCategory);
- }
- }
-
- private boolean populateOrRemoveTtsPrefs() {
- if (mTtsEngines.getEngines().isEmpty()) {
- mVoiceCategory.removePreference(mTtsSettingsPref);
- return false;
- }
-
- return true;
- }
-}
diff --git a/src/com/android/settings/inputmethod/GameControllerPreferenceController.java b/src/com/android/settings/inputmethod/GameControllerPreferenceController.java
new file mode 100644
index 0000000..f8232b8
--- /dev/null
+++ b/src/com/android/settings/inputmethod/GameControllerPreferenceController.java
@@ -0,0 +1,131 @@
+/*
+ * 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.content.Context;
+import android.hardware.input.InputManager;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+import android.view.InputDevice;
+
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
+
+public class GameControllerPreferenceController extends PreferenceController
+ implements InputManager.InputDeviceListener, LifecycleObserver, OnResume, OnPause {
+
+ public static final String PREF_KEY = "vibrate_input_devices";
+ private static final String CATEGORY_KEY = "game_controller_settings_category";
+
+ private final InputManager mIm;
+
+ private PreferenceScreen mScreen;
+ private Preference mCategory;
+ private Preference mPreference;
+
+ public GameControllerPreferenceController(Context context) {
+ super(context);
+ mIm = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
+ }
+
+ @Override
+ public void onResume() {
+ mIm.registerInputDeviceListener(this, null);
+ }
+
+ @Override
+ public void onPause() {
+ mIm.unregisterInputDeviceListener(this);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mScreen = screen;
+ mCategory = screen.findPreference(CATEGORY_KEY);
+ mPreference = screen.findPreference(PREF_KEY);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ final int[] devices = mIm.getInputDeviceIds();
+ for (int deviceId : devices) {
+ InputDevice device = mIm.getInputDevice(deviceId);
+ if (device != null && !device.isVirtual() && device.getVibrator().hasVibrator()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (TextUtils.equals(PREF_KEY, preference.getKey())) {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.VIBRATE_INPUT_DEVICES,
+ ((SwitchPreference) preference).isChecked() ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return CATEGORY_KEY;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (preference == null) {
+ return;
+ }
+ ((SwitchPreference) preference).setChecked(Settings.System.getInt(
+ mContext.getContentResolver(),
+ Settings.System.VIBRATE_INPUT_DEVICES, 1) > 0);
+ }
+
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ updateGameControllers();
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ updateGameControllers();
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ updateGameControllers();
+ }
+
+ private void updateGameControllers() {
+ if (isAvailable()) {
+ mScreen.addPreference(mCategory);
+ updateState(mPreference);
+ } else {
+ if (mCategory != null) {
+ mScreen.removePreference(mCategory);
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index 9fa2645..351f6b5 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -17,7 +17,6 @@
package com.android.settings.inputmethod;
import android.app.Activity;
-import android.app.Fragment;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -25,52 +24,38 @@
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
import android.hardware.input.KeyboardLayout;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.provider.Settings.System;
import android.speech.tts.TtsEngines;
-import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceCategory;
import android.view.InputDevice;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
-import android.view.textservice.SpellCheckerInfo;
-import android.view.textservice.TextServicesManager;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Settings.KeyboardLayoutPickerActivity;
-import com.android.settings.SettingsActivity;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.SubSettings;
-import com.android.settings.UserDictionarySettings;
import com.android.settings.Utils;
-import com.android.settings.VoiceInputOutputSettings;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.SummaryLoader;
+import com.android.settings.language.PhoneLanguagePreferenceController;
+import com.android.settings.language.TtsPreferenceController;
+import com.android.settings.language.UserDictionaryPreferenceController;
import com.android.settings.localepicker.LocaleFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
+import com.android.settingslib.drawer.CategoryKey;
import java.util.ArrayList;
import java.util.List;
-import java.util.TreeSet;
-public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
- implements InputManager.InputDeviceListener,
- KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener, Indexable {
+public class InputMethodAndLanguageSettings extends DashboardFragment
+ implements KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener, Indexable {
- private static final String KEY_SPELL_CHECKERS = "spellcheckers_settings";
- private static final String KEY_PHONE_LANGUAGE = "phone_language";
- private static final String KEY_USER_DICTIONARY_SETTINGS = "key_user_dictionary_settings";
+ private static final String TAG = "IMEAndLanguageSetting";
- private PreferenceCategory mGameControllerCategory;
- private Preference mLanguagePref;
- private InputManager mIm;
private Intent mIntentWaitingForResult;
@Override
@@ -79,137 +64,33 @@
}
@Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- addPreferencesFromResource(R.xml.language_settings);
-
- final Activity activity = getActivity();
-
- if (activity.getAssets().getLocales().length == 1) {
- // No "Select language" pref if there's only one system locale available.
- getPreferenceScreen().removePreference(findPreference(KEY_PHONE_LANGUAGE));
- } else {
- mLanguagePref = findPreference(KEY_PHONE_LANGUAGE);
- }
-
- new VoiceInputOutputSettings(this).onCreate();
-
- mGameControllerCategory = (PreferenceCategory)findPreference(
- "game_controller_settings_category");
-
- // Build hard keyboard and game controller preference categories.
- mIm = (InputManager)activity.getSystemService(Context.INPUT_SERVICE);
- updateInputDevices();
-
- // Spell Checker
- final Preference spellChecker = findPreference(KEY_SPELL_CHECKERS);
- if (spellChecker != null) {
- // Note: KEY_SPELL_CHECKERS preference is marked as persistent="false" in XML.
- InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference(spellChecker);
- final Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClass(activity, SubSettings.class);
- intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT,
- SpellCheckersSettings.class.getName());
- intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID,
- R.string.spellcheckers_settings_title);
- spellChecker.setIntent(intent);
- }
- }
-
- private void updateUserDictionaryPreference(Preference userDictionaryPreference) {
- final Activity activity = getActivity();
- final TreeSet<String> localeSet = UserDictionaryList.getUserDictionaryLocalesSet(activity);
- if (null == localeSet) {
- // The locale list is null if and only if the user dictionary service is
- // not present or disabled. In this case we need to remove the preference.
- getPreferenceScreen().removePreference(userDictionaryPreference);
- } else {
- userDictionaryPreference.setOnPreferenceClickListener(
- new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference arg0) {
- // Redirect to UserDictionarySettings if the user needs only one
- // language.
- final Bundle extras = new Bundle();
- final Class<? extends Fragment> targetFragment;
- if (localeSet.size() <= 1) {
- if (!localeSet.isEmpty()) {
- // If the size of localeList is 0, we don't set the locale
- // parameter in the extras. This will be interpreted by the
- // UserDictionarySettings class as meaning
- // "the current locale". Note that with the current code for
- // UserDictionaryList#getUserDictionaryLocalesSet()
- // the locale list always has at least one element, since it
- // always includes the current locale explicitly.
- // @see UserDictionaryList.getUserDictionaryLocalesSet().
- extras.putString("locale", localeSet.first());
- }
- targetFragment = UserDictionarySettings.class;
- } else {
- targetFragment = UserDictionaryList.class;
- }
- startFragment(InputMethodAndLanguageSettings.this,
- targetFragment.getCanonicalName(), -1, -1, extras);
- return true;
- }
- });
- }
+ protected String getCategoryKey() {
+ return CategoryKey.CATEGORY_SYSTEM_LANGUAGE;
}
@Override
- public void onResume() {
- super.onResume();
-
- mIm.registerInputDeviceListener(this, null);
-
- final Preference spellChecker = findPreference(KEY_SPELL_CHECKERS);
- if (spellChecker != null) {
- final TextServicesManager tsm = (TextServicesManager) getSystemService(
- Context.TEXT_SERVICES_MANAGER_SERVICE);
- if (!tsm.isSpellCheckerEnabled()) {
- spellChecker.setSummary(R.string.switch_off_text);
- } else {
- final SpellCheckerInfo sci = tsm.getCurrentSpellChecker();
- if (sci != null) {
- spellChecker.setSummary(sci.loadLabel(getPackageManager()));
- } else {
- spellChecker.setSummary(R.string.spell_checker_not_selected);
- }
- }
- }
-
- if (mLanguagePref != null) {
- final String localeNames = FeatureFactory.getFactory(getContext())
- .getLocaleFeatureProvider().getLocaleNames();
- mLanguagePref.setSummary(localeNames);
- }
-
- updateUserDictionaryPreference(findPreference(KEY_USER_DICTIONARY_SETTINGS));
-
- updateInputDevices();
+ protected String getLogTag() {
+ return TAG;
}
@Override
- public void onPause() {
- super.onPause();
-
- mIm.unregisterInputDeviceListener(this);
+ protected int getPreferenceScreenResId() {
+ return R.xml.language_settings;
}
@Override
- public void onInputDeviceAdded(int deviceId) {
- updateInputDevices();
- }
+ protected List<PreferenceController> getPreferenceControllers(Context context) {
+ final GameControllerPreferenceController gameControllerPreferenceController =
+ new GameControllerPreferenceController(context);
+ getLifecycle().addObserver(gameControllerPreferenceController);
- @Override
- public void onInputDeviceChanged(int deviceId) {
- updateInputDevices();
- }
-
- @Override
- public void onInputDeviceRemoved(int deviceId) {
- updateInputDevices();
+ final List<PreferenceController> list = new ArrayList<>();
+ list.add(gameControllerPreferenceController);
+ list.add(new PhoneLanguagePreferenceController(context));
+ list.add(new SpellCheckerPreferenceController(context));
+ list.add(new UserDictionaryPreferenceController(context));
+ list.add(new TtsPreferenceController(context, new TtsEngines(context)));
+ return list;
}
@Override
@@ -218,21 +99,9 @@
if (Utils.isMonkeyRunning()) {
return false;
}
- if (preference instanceof SwitchPreference) {
- final SwitchPreference pref = (SwitchPreference) preference;
- if (pref == mGameControllerCategory.findPreference("vibrate_input_devices")) {
- System.putInt(getContentResolver(), Settings.System.VIBRATE_INPUT_DEVICES,
- pref.isChecked() ? 1 : 0);
- return true;
- }
- }
return super.onPreferenceTreeClick(preference);
}
- private void updateInputDevices() {
- updateGameControllers();
- }
-
private void showKeyboardLayoutDialog(InputDeviceIdentifier inputDeviceIdentifier) {
KeyboardLayoutDialogFragment fragment = (KeyboardLayoutDialogFragment)
getFragmentManager().findFragmentByTag("keyboardLayout");
@@ -265,38 +134,12 @@
}
}
- private void updateGameControllers() {
- if (haveInputDeviceWithVibrator()) {
- getPreferenceScreen().addPreference(mGameControllerCategory);
-
- SwitchPreference pref = (SwitchPreference)
- mGameControllerCategory.findPreference("vibrate_input_devices");
- pref.setChecked(System.getInt(getContentResolver(),
- Settings.System.VIBRATE_INPUT_DEVICES, 1) > 0);
- } else {
- getPreferenceScreen().removePreference(mGameControllerCategory);
- }
- }
-
- private static boolean haveInputDeviceWithVibrator() {
- final int[] devices = InputDevice.getDeviceIds();
- for (int i = 0; i < devices.length; i++) {
- InputDevice device = InputDevice.getDevice(devices[i]);
- if (device != null && !device.isVirtual() && device.getVibrator().hasVibrator()) {
- return true;
- }
- }
- return false;
- }
-
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
- private final Context mContext;
private final SummaryLoader mSummaryLoader;
private LocaleFeatureProvider mLocaleFeatureProvider;
public SummaryProvider(Context context, SummaryLoader summaryLoader) {
- mContext = context;
mSummaryLoader = summaryLoader;
mLocaleFeatureProvider = FeatureFactory.getFactory(context).getLocaleFeatureProvider();
}
@@ -328,11 +171,13 @@
final String screenTitle = context.getString(R.string.language_keyboard_settings_title);
// Locale picker.
- if (context.getAssets().getLocales().length > 1) {
+ final PhoneLanguagePreferenceController mLanguagePrefController =
+ new PhoneLanguagePreferenceController(context);
+ if (mLanguagePrefController.isAvailable()) {
String localeNames = FeatureFactory.getFactory(context).getLocaleFeatureProvider()
.getLocaleNames();
SearchIndexableRaw indexable = new SearchIndexableRaw(context);
- indexable.key = KEY_PHONE_LANGUAGE;
+ indexable.key = mLanguagePrefController.getPreferenceKey();
indexable.title = context.getString(R.string.phone_language);
indexable.summaryOn = localeNames;
indexable.summaryOff = localeNames;
@@ -342,7 +187,7 @@
// Spell checker.
SearchIndexableRaw indexable = new SearchIndexableRaw(context);
- indexable.key = KEY_SPELL_CHECKERS;
+ indexable.key = SpellCheckerPreferenceController.KEY_SPELL_CHECKERS;
indexable.title = context.getString(R.string.spellcheckers_settings_title);
indexable.screenTitle = screenTitle;
indexable.keywords = context.getString(R.string.keywords_spell_checker);
@@ -465,9 +310,9 @@
indexables.add(indexable);
// Game controllers.
- if (haveInputDeviceWithVibrator()) {
+ if (!new GameControllerPreferenceController(context).isAvailable()) {
indexable = new SearchIndexableRaw(context);
- indexable.key = "vibrate_input_devices";
+ indexable.key = GameControllerPreferenceController.PREF_KEY;
indexable.title = context.getString(R.string.vibrate_input_devices);
indexable.summaryOn = context.getString(R.string.vibrate_input_devices_summary);
indexable.summaryOff = context.getString(R.string.vibrate_input_devices_summary);
diff --git a/src/com/android/settings/inputmethod/SpellCheckerPreferenceController.java b/src/com/android/settings/inputmethod/SpellCheckerPreferenceController.java
new file mode 100644
index 0000000..17d3fdc
--- /dev/null
+++ b/src/com/android/settings/inputmethod/SpellCheckerPreferenceController.java
@@ -0,0 +1,80 @@
+/*
+ * 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.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.view.textservice.SpellCheckerInfo;
+import android.view.textservice.TextServicesManager;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceController;
+
+public class SpellCheckerPreferenceController extends PreferenceController {
+
+ public static final String KEY_SPELL_CHECKERS = "spellcheckers_settings";
+
+ private final TextServicesManager mTextServicesManager;
+
+ public SpellCheckerPreferenceController(Context context) {
+ super(context);
+ mTextServicesManager = (TextServicesManager) context.getSystemService(
+ Context.TEXT_SERVICES_MANAGER_SERVICE);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ final Preference preference = screen.findPreference(KEY_SPELL_CHECKERS);
+ if (preference != null) {
+ InputMethodAndSubtypeUtil.removeUnnecessaryNonPersistentPreference(preference);
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ return false;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_SPELL_CHECKERS;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (preference == null) {
+ return;
+ }
+ if (!mTextServicesManager.isSpellCheckerEnabled()) {
+ preference.setSummary(R.string.switch_off_text);
+ } else {
+ final SpellCheckerInfo sci = mTextServicesManager.getCurrentSpellChecker();
+ if (sci != null) {
+ preference.setSummary(sci.loadLabel(mContext.getPackageManager()));
+ } else {
+ preference.setSummary(R.string.spell_checker_not_selected);
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/language/PhoneLanguagePreferenceController.java b/src/com/android/settings/language/PhoneLanguagePreferenceController.java
new file mode 100644
index 0000000..2b87fd9
--- /dev/null
+++ b/src/com/android/settings/language/PhoneLanguagePreferenceController.java
@@ -0,0 +1,57 @@
+/*
+ * 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.language;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+
+public class PhoneLanguagePreferenceController extends PreferenceController {
+
+ private static final String KEY_PHONE_LANGUAGE = "phone_language";
+
+ public PhoneLanguagePreferenceController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mContext.getAssets().getLocales().length > 1;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ return false;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (preference == null) {
+ return;
+ }
+ final String localeNames = FeatureFactory.getFactory(mContext)
+ .getLocaleFeatureProvider().getLocaleNames();
+ preference.setSummary(localeNames);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_PHONE_LANGUAGE;
+ }
+}
diff --git a/src/com/android/settings/language/TtsPreferenceController.java b/src/com/android/settings/language/TtsPreferenceController.java
new file mode 100644
index 0000000..ffc1eb1
--- /dev/null
+++ b/src/com/android/settings/language/TtsPreferenceController.java
@@ -0,0 +1,60 @@
+/*
+ * 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.language;
+
+import android.content.Context;
+import android.speech.tts.TtsEngines;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.core.PreferenceController;
+
+public class TtsPreferenceController extends PreferenceController {
+
+ private static final String KEY_VOICE_CATEGORY = "voice_category";
+ private static final String KEY_TTS_SETTINGS = "tts_settings";
+
+ private final TtsEngines mTtsEngines;
+
+ public TtsPreferenceController(Context context, TtsEngines ttsEngines) {
+ super(context);
+ mTtsEngines = ttsEngines;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return !mTtsEngines.getEngines().isEmpty();
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ if (!isAvailable()) {
+ removePreference(screen, KEY_VOICE_CATEGORY);
+ }
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ return false;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_TTS_SETTINGS;
+ }
+}
diff --git a/src/com/android/settings/language/UserDictionaryPreferenceController.java b/src/com/android/settings/language/UserDictionaryPreferenceController.java
new file mode 100644
index 0000000..d26761b
--- /dev/null
+++ b/src/com/android/settings/language/UserDictionaryPreferenceController.java
@@ -0,0 +1,86 @@
+/*
+ * 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.language;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.UserDictionarySettings;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.inputmethod.UserDictionaryList;
+
+import java.util.TreeSet;
+
+public class UserDictionaryPreferenceController extends PreferenceController {
+
+ private static final String KEY_USER_DICTIONARY_SETTINGS = "key_user_dictionary_settings";
+
+ public UserDictionaryPreferenceController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ final TreeSet<String> localeSet = getDictionaryLocales();
+ // The locale list is null if and only if the user dictionary service is
+ // not present or disabled. In this case we need to remove the preference.
+ return localeSet != null;
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ return false;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_USER_DICTIONARY_SETTINGS;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (!isAvailable() || preference == null) {
+ return;
+ }
+ final TreeSet<String> localeSet = getDictionaryLocales();
+ final Bundle extras = preference.getExtras();
+ final Class<? extends Fragment> targetFragment;
+ if (localeSet.size() <= 1) {
+ if (!localeSet.isEmpty()) {
+ // If the size of localeList is 0, we don't set the locale
+ // parameter in the extras. This will be interpreted by the
+ // UserDictionarySettings class as meaning
+ // "the current locale". Note that with the current code for
+ // UserDictionaryList#getUserDictionaryLocalesSet()
+ // the locale list always has at least one element, since it
+ // always includes the current locale explicitly.
+ // @see UserDictionaryList.getUserDictionaryLocalesSet().
+ extras.putString("locale", localeSet.first());
+ }
+ targetFragment = UserDictionarySettings.class;
+ } else {
+ targetFragment = UserDictionaryList.class;
+ }
+ preference.setFragment(targetFragment.getCanonicalName());
+ }
+
+ protected TreeSet<String> getDictionaryLocales() {
+ return UserDictionaryList.getUserDictionaryLocalesSet(mContext);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java
index e2b4473..578b853 100644
--- a/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/SwipeToNotificationPreferenceControllerTest.java
@@ -22,6 +22,7 @@
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.TwoStatePreference;
+import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import org.junit.Before;
@@ -30,7 +31,6 @@
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
@@ -41,7 +41,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SwipeToNotificationPreferenceControllerTest {
diff --git a/tests/robotests/src/com/android/settings/inputmethod/GameControllerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/GameControllerPreferenceControllerTest.java
new file mode 100644
index 0000000..c1bd0e0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/inputmethod/GameControllerPreferenceControllerTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.content.Context;
+import android.hardware.input.InputManager;
+import android.view.InputDevice;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class GameControllerPreferenceControllerTest {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private InputManager mInputManager;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private InputDevice mInputDevice;
+
+ private GameControllerPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getSystemService(Context.INPUT_SERVICE)).thenReturn(mInputManager);
+ mController = new GameControllerPreferenceController(mContext);
+ }
+
+ @Test
+ public void testLifecycle_shouldRegisterInputManager() {
+ mController.onResume();
+
+ // register is called, but unregister should not be called.
+ verify(mInputManager).registerInputDeviceListener(mController, null);
+ verify(mInputManager, never()).unregisterInputDeviceListener(mController);
+
+ mController.onPause();
+ // register is not called any more times, but unregister should be called once.
+ verify(mInputManager).registerInputDeviceListener(mController, null);
+ verify(mInputManager).unregisterInputDeviceListener(mController);
+ }
+
+ @Test
+ public void testIsAvailable_hasDeviceWithVibrator_shouldReturnTrue() {
+ when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mInputManager.getInputDevice(1)).thenReturn(mInputDevice);
+ when(mInputDevice.isVirtual()).thenReturn(false);
+ when(mInputDevice.getVibrator().hasVibrator()).thenReturn(true);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void testIsAvailable_hasNoVibratingDevice_shouldReturnFalse() {
+ when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mInputManager.getInputDevice(1)).thenReturn(mInputDevice);
+ when(mInputDevice.isVirtual()).thenReturn(false);
+ when(mInputDevice.getVibrator().hasVibrator()).thenReturn(false);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void testIsAvailable_hasNoPhysicalDevice_shouldReturnFalse() {
+ when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{1});
+ when(mInputManager.getInputDevice(1)).thenReturn(mInputDevice);
+ when(mInputDevice.isVirtual()).thenReturn(true);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void testIsAvailable_hasNoDevice_shouldReturnFalse() {
+ when(mInputManager.getInputDeviceIds()).thenReturn(new int[]{});
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/inputmethod/SpellCheckerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/SpellCheckerPreferenceControllerTest.java
new file mode 100644
index 0000000..78c0590
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/inputmethod/SpellCheckerPreferenceControllerTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.content.Context;
+import android.support.v7.preference.Preference;
+import android.view.textservice.SpellCheckerInfo;
+import android.view.textservice.TextServicesManager;
+
+import com.android.settings.R;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SpellCheckerPreferenceControllerTest {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private TextServicesManager mTextServicesManager;
+ private Context mAppContext;
+ private Preference mPreference;
+ private SpellCheckerPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mAppContext = ShadowApplication.getInstance().getApplicationContext();
+ when(mContext.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE))
+ .thenReturn(mTextServicesManager);
+ mPreference = new Preference(mAppContext);
+ mController = new SpellCheckerPreferenceController(mContext);
+ }
+
+ @Test
+ public void updateState_NoSpellerChecker_shouldSetSummaryToDefault() {
+ when(mTextServicesManager.isSpellCheckerEnabled()).thenReturn(true);
+ when(mTextServicesManager.getCurrentSpellChecker()).thenReturn(null);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mAppContext.getString(R.string.spell_checker_not_selected));
+ }
+
+ @Test
+ public void updateState_spellerCheckerDisabled_shouldSetSummaryToDisabledText() {
+ when(mTextServicesManager.isSpellCheckerEnabled()).thenReturn(false);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mAppContext.getString(R.string.switch_off_text));
+ }
+
+ @Test
+ public void updateState_hasSpellerChecker_shouldSetSummaryToAppName() {
+ final String spellCheckerAppLabel = "test";
+ final SpellCheckerInfo sci = mock(SpellCheckerInfo.class);
+ when(mTextServicesManager.isSpellCheckerEnabled()).thenReturn(true);
+ when(mTextServicesManager.getCurrentSpellChecker()).thenReturn(sci);
+ when(sci.loadLabel(mContext.getPackageManager())).thenReturn(spellCheckerAppLabel);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getSummary()).isEqualTo(spellCheckerAppLabel);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/language/PhoneLanguagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/language/PhoneLanguagePreferenceControllerTest.java
new file mode 100644
index 0000000..e7367bb
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/language/PhoneLanguagePreferenceControllerTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.language;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class PhoneLanguagePreferenceControllerTest {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private Preference mPreference;
+ private FakeFeatureFactory mFeatureFactory;
+ private PhoneLanguagePreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest(mContext);
+ mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+ mController = new PhoneLanguagePreferenceController(mContext);
+ }
+
+ @Test
+ public void testIsAvailable_hasMultipleLocales_shouldReturnTrue() {
+ when(mContext.getAssets().getLocales()).thenReturn(new String[]{"en", "de"});
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void testIsAvailable_hasSingleLocales_shouldReturnFalse() {
+ when(mContext.getAssets().getLocales()).thenReturn(new String[]{"en"});
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void testUpdateState_shouldUpdateSummary() {
+ final String testSummary = "test";
+ when(mFeatureFactory.localeFeatureProvider.getLocaleNames()).thenReturn(testSummary);
+
+ mController.updateState(mPreference);
+
+ verify(mPreference).setSummary(testSummary);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/language/TtsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/language/TtsPreferenceControllerTest.java
new file mode 100644
index 0000000..0e41784
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/language/TtsPreferenceControllerTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.language;
+
+import android.content.Context;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.TtsEngines;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class TtsPreferenceControllerTest {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private TtsEngines mTtsEngines;
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private TtsPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mController = new TtsPreferenceController(mContext, mTtsEngines);
+ }
+
+ @Test
+ public void testIsAvailable_ttsEngineEmpty_shouldReturnFalse() {
+
+ // Not available when there is no engine.
+ when(mTtsEngines.getEngines()).thenReturn(new ArrayList<>());
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void testIsAvailable_ttsEngineInstalled_shouldReturnTrue() {
+ final List<TextToSpeech.EngineInfo> infolist = new ArrayList<>();
+ infolist.add(mock(TextToSpeech.EngineInfo.class));
+ when(mTtsEngines.getEngines()).thenReturn(infolist);
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void displayPreference_notAvailable_shouldRemoveCategory() {
+ when(mScreen.findPreference(anyString())).thenReturn(mock(Preference.class));
+
+ mController.displayPreference(mScreen);
+
+ // Remove both category and preference.
+ verify(mScreen, times(2)).removePreference(any(Preference.class));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/language/UserDictionaryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/language/UserDictionaryPreferenceControllerTest.java
new file mode 100644
index 0000000..d2032ed
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/language/UserDictionaryPreferenceControllerTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.language;
+
+import android.content.Context;
+import android.speech.tts.TtsEngines;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.UserDictionarySettings;
+import com.android.settings.inputmethod.UserDictionaryList;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.TreeSet;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class UserDictionaryPreferenceControllerTest {
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private TtsEngines mTtsEngines;
+ private Preference mPreference;
+ private TestController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest(mContext);
+ mController = new TestController(mContext);
+ mPreference = new Preference(ShadowApplication.getInstance().getApplicationContext());
+ }
+
+ @Test
+ public void testIsAvailable_noLocale_shouldReturnFalse() {
+ mController.mLocales = null;
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void testIsAvailable_hasLocale_shouldReturnTrue() {
+ mController.mLocales.add("en");
+
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void updateState_noLocale_setUserDictionarySettingsAsFragment() {
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getFragment())
+ .isEqualTo(UserDictionarySettings.class.getCanonicalName());
+ }
+
+ @Test
+ public void updateState_singleLocale_setUserDictionarySettingsAsFragment_setLocaleInExtra() {
+ mController.mLocales.add("en");
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getFragment())
+ .isEqualTo(UserDictionarySettings.class.getCanonicalName());
+ assertThat(mPreference.getExtras().getString("locale"))
+ .isEqualTo("en");
+ }
+
+ @Test
+ public void updateState_multiLocale_setUserDictionaryListAsFragment() {
+ mController.mLocales.add("en");
+ mController.mLocales.add("de");
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getFragment())
+ .isEqualTo(UserDictionaryList.class.getCanonicalName());
+ }
+
+ /**
+ * Fake Controller that overrides getDictionaryLocales to make testing the rest of stuff easier.
+ */
+ private class TestController extends UserDictionaryPreferenceController {
+
+ private TreeSet<String> mLocales = new TreeSet<>();
+
+ @Override
+ protected TreeSet<String> getDictionaryLocales() {
+ return mLocales;
+ }
+
+ public TestController(Context context) {
+ super(context);
+ }
+ }
+
+}