diff options
10 files changed, 442 insertions, 255 deletions
diff --git a/res/xml/user_dictionary_list_fragment.xml b/res/xml/user_dictionary_list_fragment.xml new file mode 100644 index 0000000000..46418c196a --- /dev/null +++ b/res/xml/user_dictionary_list_fragment.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2018 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. +--> + +<PreferenceScreen + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:settings="http://schemas.android.com/apk/res-auto" + android:key="user_dict_list" + android:title="@string/user_dict_settings_title" + settings:controller="com.android.settings.inputmethod.UserDictionaryListPreferenceController"> + +</PreferenceScreen> diff --git a/src/com/android/settings/core/PreferenceControllerListHelper.java b/src/com/android/settings/core/PreferenceControllerListHelper.java index 738a6952e8..5879ba443b 100644 --- a/src/com/android/settings/core/PreferenceControllerListHelper.java +++ b/src/com/android/settings/core/PreferenceControllerListHelper.java @@ -54,7 +54,8 @@ public class PreferenceControllerListHelper { List<Bundle> preferenceMetadata; try { preferenceMetadata = PreferenceXmlParserUtils.extractMetadata(context, xmlResId, - MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_PREF_CONTROLLER); + MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_PREF_CONTROLLER + | MetadataFlag.FLAG_INCLUDE_PREF_SCREEN); } catch (IOException | XmlPullParserException e) { Log.e(TAG, "Failed to parse preference xml for getting controllers", e); return controllers; diff --git a/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java b/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java index 620bc65281..716226db4c 100644 --- a/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java +++ b/src/com/android/settings/inputmethod/UserDictionaryAddWordContents.java @@ -60,8 +60,8 @@ public class UserDictionaryAddWordContents { private String mSavedShortcut; /* package */ UserDictionaryAddWordContents(final View view, final Bundle args) { - mWordEditText = (EditText)view.findViewById(R.id.user_dictionary_add_word_text); - mShortcutEditText = (EditText)view.findViewById(R.id.user_dictionary_add_shortcut); + mWordEditText = (EditText) view.findViewById(R.id.user_dictionary_add_word_text); + mShortcutEditText = (EditText) view.findViewById(R.id.user_dictionary_add_shortcut); final String word = args.getString(EXTRA_WORD); if (null != word) { mWordEditText.setText(word); @@ -81,8 +81,8 @@ public class UserDictionaryAddWordContents { /* package */ UserDictionaryAddWordContents(final View view, final UserDictionaryAddWordContents oldInstanceToBeEdited) { - mWordEditText = (EditText)view.findViewById(R.id.user_dictionary_add_word_text); - mShortcutEditText = (EditText)view.findViewById(R.id.user_dictionary_add_shortcut); + mWordEditText = (EditText) view.findViewById(R.id.user_dictionary_add_word_text); + mShortcutEditText = (EditText) view.findViewById(R.id.user_dictionary_add_shortcut); mMode = MODE_EDIT; mOldWord = oldInstanceToBeEdited.mSavedWord; mOldShortcut = oldInstanceToBeEdited.mSavedShortcut; @@ -167,23 +167,24 @@ public class UserDictionaryAddWordContents { return UserDictionaryAddWordActivity.CODE_WORD_ADDED; } - private static final String[] HAS_WORD_PROJECTION = { UserDictionary.Words.WORD }; + private static final String[] HAS_WORD_PROJECTION = {UserDictionary.Words.WORD}; private static final String HAS_WORD_SELECTION_ONE_LOCALE = UserDictionary.Words.WORD + "=? AND " + UserDictionary.Words.LOCALE + "=?"; private static final String HAS_WORD_SELECTION_ALL_LOCALES = UserDictionary.Words.WORD + "=? AND " + UserDictionary.Words.LOCALE + " is null"; + private boolean hasWord(final String word, final Context context) { final Cursor cursor; // mLocale == "" indicates this is an entry for all languages. Here, mLocale can't // be null at all (it's ensured by the updateLocale method). if ("".equals(mLocale)) { cursor = context.getContentResolver().query(UserDictionary.Words.CONTENT_URI, - HAS_WORD_PROJECTION, HAS_WORD_SELECTION_ALL_LOCALES, - new String[] { word }, null /* sort order */); + HAS_WORD_PROJECTION, HAS_WORD_SELECTION_ALL_LOCALES, + new String[] {word}, null /* sort order */); } else { cursor = context.getContentResolver().query(UserDictionary.Words.CONTENT_URI, - HAS_WORD_PROJECTION, HAS_WORD_SELECTION_ONE_LOCALE, - new String[] { word, mLocale }, null /* sort order */); + HAS_WORD_PROJECTION, HAS_WORD_SELECTION_ONE_LOCALE, + new String[] {word, mLocale}, null /* sort order */); } try { if (null == cursor) return false; @@ -196,6 +197,7 @@ public class UserDictionaryAddWordContents { public static class LocaleRenderer { private final String mLocaleString; private final String mDescription; + // LocaleString may NOT be null. public LocaleRenderer(final Context context, final String localeString) { mLocaleString = localeString; @@ -207,13 +209,16 @@ public class UserDictionaryAddWordContents { mDescription = Utils.createLocaleFromString(localeString).getDisplayName(); } } + @Override public String toString() { return mDescription; } + public String getLocaleString() { return mLocaleString; } + // "More languages..." is null ; "All languages" is the empty string. public boolean isMoreLanguages() { return null == mLocaleString; @@ -229,7 +234,8 @@ public class UserDictionaryAddWordContents { // Helper method to get the list of locales to display for this word public ArrayList<LocaleRenderer> getLocalesList(final Activity activity) { - final TreeSet<String> locales = UserDictionaryList.getUserDictionaryLocalesSet(activity); + final TreeSet<String> locales = + UserDictionaryListPreferenceController.getUserDictionaryLocalesSet(activity); // Remove our locale if it's in, because we're always gonna put it at the top locales.remove(mLocale); // mLocale may not be null final String systemLocale = Locale.getDefault().toString(); diff --git a/src/com/android/settings/inputmethod/UserDictionaryList.java b/src/com/android/settings/inputmethod/UserDictionaryList.java index 2f59dc90da..46723bc461 100644 --- a/src/com/android/settings/inputmethod/UserDictionaryList.java +++ b/src/com/android/settings/inputmethod/UserDictionaryList.java @@ -16,33 +16,17 @@ package com.android.settings.inputmethod; -import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.database.Cursor; import android.os.Bundle; -import android.provider.UserDictionary; -import android.support.annotation.NonNull; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceGroup; -import android.text.TextUtils; -import android.view.inputmethod.InputMethodInfo; -import android.view.inputmethod.InputMethodManager; -import android.view.inputmethod.InputMethodSubtype; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.Utils; +import com.android.settings.dashboard.DashboardFragment; -import java.util.List; -import java.util.Locale; -import java.util.TreeSet; +public class UserDictionaryList extends DashboardFragment { -public class UserDictionaryList extends SettingsPreferenceFragment { - public static final String USER_DICTIONARY_SETTINGS_INTENT_ACTION = - "android.settings.USER_DICTIONARY_SETTINGS"; - private String mLocale; + private static final String TAG = "UserDictionaryList"; @Override public int getMetricsCategory() { @@ -50,15 +34,8 @@ public class UserDictionaryList extends SettingsPreferenceFragment { } @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity())); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - getActivity().getActionBar().setTitle(R.string.user_dict_settings_title); + public void onAttach(Context context) { + super.onAttach(context); final Intent intent = getActivity().getIntent(); final String localeFromIntent = @@ -76,122 +53,17 @@ public class UserDictionaryList extends SettingsPreferenceFragment { } else { locale = null; } - mLocale = locale; - } - - @NonNull - public static TreeSet<String> getUserDictionaryLocalesSet(Context context) { - final Cursor cursor = context.getContentResolver().query( - UserDictionary.Words.CONTENT_URI, new String[]{UserDictionary.Words.LOCALE}, - null, null, null); - final TreeSet<String> localeSet = new TreeSet<>(); - if (cursor == null) { - // The user dictionary service is not present or disabled. Return empty set. - return localeSet; - } - try { - if (cursor.moveToFirst()) { - final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE); - do { - final String locale = cursor.getString(columnIndex); - localeSet.add(null != locale ? locale : ""); - } while (cursor.moveToNext()); - } - } finally { - cursor.close(); - } - - // CAVEAT: Keep this for consistency of the implementation between Keyboard and Settings - // if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { - // // For ICS, we need to show "For all languages" in case that the keyboard locale - // // is different from the system locale - // localeSet.add(""); - // } - - final InputMethodManager imm = - (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); - final List<InputMethodInfo> imis = imm.getEnabledInputMethodList(); - for (final InputMethodInfo imi : imis) { - final List<InputMethodSubtype> subtypes = - imm.getEnabledInputMethodSubtypeList( - imi, true /* allowsImplicitlySelectedSubtypes */); - for (InputMethodSubtype subtype : subtypes) { - final String locale = subtype.getLocale(); - if (!TextUtils.isEmpty(locale)) { - localeSet.add(locale); - } - } - } - - // We come here after we have collected locales from existing user dictionary entries and - // enabled subtypes. If we already have the locale-without-country version of the system - // locale, we don't add the system locale to avoid confusion even though it's technically - // correct to add it. - if (!localeSet.contains(Locale.getDefault().getLanguage().toString())) { - localeSet.add(Locale.getDefault().toString()); - } - return localeSet; + use(UserDictionaryListPreferenceController.class).setLocale(locale); } - /** - * Creates the entries that allow the user to go into the user dictionary for each locale. - * - * @param userDictGroup The group to put the settings in. - */ - protected void createUserDictSettings(PreferenceGroup userDictGroup) { - final Activity activity = getActivity(); - userDictGroup.removeAll(); - final TreeSet<String> localeSet = - UserDictionaryList.getUserDictionaryLocalesSet(activity); - if (mLocale != null) { - // If the caller explicitly specify empty string as a locale, we'll show "all languages" - // in the list. - localeSet.add(mLocale); - } - if (localeSet.size() > 1) { - // Have an "All languages" entry in the languages list if there are two or more active - // languages - localeSet.add(""); - } - - if (localeSet.isEmpty()) { - userDictGroup.addPreference(createUserDictionaryPreference(null, activity)); - } else { - for (String locale : localeSet) { - userDictGroup.addPreference(createUserDictionaryPreference(locale, activity)); - } - } - } - - /** - * Create a single User Dictionary Preference object, with its parameters set. - * - * @param locale The locale for which this user dictionary is for. - * @return The corresponding preference. - */ - protected Preference createUserDictionaryPreference(String locale, Activity activity) { - final Preference newPref = new Preference(getPrefContext()); - final Intent intent = new Intent(USER_DICTIONARY_SETTINGS_INTENT_ACTION); - if (null == locale) { - newPref.setTitle(Locale.getDefault().getDisplayName()); - } else { - if ("".equals(locale)) { - newPref.setTitle(getString(R.string.user_dict_settings_all_languages)); - } else { - newPref.setTitle(Utils.createLocaleFromString(locale).getDisplayName()); - } - intent.putExtra("locale", locale); - newPref.getExtras().putString("locale", locale); - } - newPref.setIntent(intent); - newPref.setFragment(UserDictionarySettings.class.getName()); - return newPref; + @Override + protected int getPreferenceScreenResId() { + return R.xml.user_dictionary_list_fragment; } @Override - public void onResume() { - super.onResume(); - createUserDictSettings(getPreferenceScreen()); + protected String getLogTag() { + return TAG; } } diff --git a/src/com/android/settings/inputmethod/UserDictionaryListPreferenceController.java b/src/com/android/settings/inputmethod/UserDictionaryListPreferenceController.java new file mode 100644 index 0000000000..715246aa17 --- /dev/null +++ b/src/com/android/settings/inputmethod/UserDictionaryListPreferenceController.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2018 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.content.Intent; +import android.database.Cursor; +import android.provider.UserDictionary; +import android.support.annotation.NonNull; +import android.support.annotation.VisibleForTesting; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.text.TextUtils; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.settings.R; +import com.android.settings.Utils; +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; + +import java.util.List; +import java.util.Locale; +import java.util.TreeSet; + +public class UserDictionaryListPreferenceController extends BasePreferenceController implements + LifecycleObserver, OnStart { + + public static final String USER_DICTIONARY_SETTINGS_INTENT_ACTION = + "android.settings.USER_DICTIONARY_SETTINGS"; + private final String KEY_ALL_LANGUAGE = "all_languages"; + private String mLocale; + private PreferenceScreen mScreen; + + public UserDictionaryListPreferenceController(Context context, String key) { + super(context, key); + } + + public void setLocale(String locale) { + mLocale = locale; + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + // This is to make newly inserted languages being sorted alphabetically when updating + // the existing preferenceScreen, and for "For all languages" to be always on the top. + screen.setOrderingAsAdded(false); + mScreen = screen; + } + + @Override + public void onStart() { + createUserDictSettings(); + } + + @NonNull + public static TreeSet<String> getUserDictionaryLocalesSet(Context context) { + final Cursor cursor = context.getContentResolver().query( + UserDictionary.Words.CONTENT_URI, new String[] {UserDictionary.Words.LOCALE}, + null, null, null); + final TreeSet<String> localeSet = new TreeSet<>(); + if (cursor == null) { + // The user dictionary service is not present or disabled. Return empty set. + return localeSet; + } + try { + if (cursor.moveToFirst()) { + final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE); + do { + final String locale = cursor.getString(columnIndex); + localeSet.add(null != locale ? locale : ""); + } while (cursor.moveToNext()); + } + } finally { + cursor.close(); + } + + // CAVEAT: Keep this for consistency of the implementation between Keyboard and Settings + // if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) { + // // For ICS, we need to show "For all languages" in case that the keyboard locale + // // is different from the system locale + // localeSet.add(""); + // } + + final InputMethodManager imm = + (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + final List<InputMethodInfo> imis = imm.getEnabledInputMethodList(); + for (final InputMethodInfo imi : imis) { + final List<InputMethodSubtype> subtypes = + imm.getEnabledInputMethodSubtypeList( + imi, true /* allowsImplicitlySelectedSubtypes */); + for (InputMethodSubtype subtype : subtypes) { + final String locale = subtype.getLocale(); + if (!TextUtils.isEmpty(locale)) { + localeSet.add(locale); + } + } + } + + // We come here after we have collected locales from existing user dictionary entries and + // enabled subtypes. If we already have the locale-without-country version of the system + // locale, we don't add the system locale to avoid confusion even though it's technically + // correct to add it. + if (!localeSet.contains(Locale.getDefault().getLanguage().toString())) { + localeSet.add(Locale.getDefault().toString()); + } + + return localeSet; + } + + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + TreeSet<String> getUserDictLocalesSet(Context context) { + return getUserDictionaryLocalesSet(context); + } + + /** + * Creates the entries that allow the user to go into the user dictionary for each locale. + */ + private void createUserDictSettings() { + + final TreeSet<String> localeSet = getUserDictLocalesSet(mContext); + final int prefCount = mScreen.getPreferenceCount(); + String prefKey; + + if (mLocale != null) { + // If the caller explicitly specify empty string as a locale, we'll show "all languages" + // in the list. + localeSet.add(mLocale); + } + if (localeSet.size() > 1) { + // Have an "All languages" entry in the languages list if there are two or more active + // languages + localeSet.add(""); + } + + // Update the existing preferenceScreen according to the corresponding data set. + if (prefCount > 0) { + for (int i = prefCount - 1; i >= 0; i--) { + prefKey = mScreen.getPreference(i).getKey(); + if (KEY_ALL_LANGUAGE.equals(prefKey)) { + prefKey = ""; + } + if (!localeSet.isEmpty() && localeSet.contains(prefKey)) { + localeSet.remove(prefKey); + continue; + } + mScreen.removePreference(mScreen.findPreference(prefKey)); + } + } + + if (localeSet.isEmpty() && prefCount == 0) { + mScreen.addPreference(createUserDictionaryPreference(null)); + } else { + for (String locale : localeSet) { + mScreen.addPreference(createUserDictionaryPreference(locale)); + } + } + } + + /** + * Create a single User Dictionary Preference object, with its parameters set. + * + * @param locale The locale for which this user dictionary is for. + * @return The corresponding preference. + */ + private Preference createUserDictionaryPreference(String locale) { + final String KEY_LOCALE = "locale"; + final Preference newPref = new Preference(mScreen.getContext()); + final Intent intent = new Intent(USER_DICTIONARY_SETTINGS_INTENT_ACTION); + if (locale == null) { + newPref.setTitle(Locale.getDefault().getDisplayName()); + newPref.setKey(Locale.getDefault().toString()); + } else { + if (TextUtils.isEmpty(locale)) { + newPref.setTitle(mContext.getString(R.string.user_dict_settings_all_languages)); + newPref.setKey(KEY_ALL_LANGUAGE); + newPref.setOrder(0); + } else { + newPref.setTitle(Utils.createLocaleFromString(locale).getDisplayName()); + newPref.setKey(locale); + } + intent.putExtra(KEY_LOCALE, locale); + newPref.getExtras().putString(KEY_LOCALE, locale); + } + newPref.setIntent(intent); + newPref.setFragment(UserDictionarySettings.class.getName()); + return newPref; + } +} diff --git a/src/com/android/settings/language/UserDictionaryPreferenceController.java b/src/com/android/settings/language/UserDictionaryPreferenceController.java index 3a1d6e0ff4..fa6dce6c92 100644 --- a/src/com/android/settings/language/UserDictionaryPreferenceController.java +++ b/src/com/android/settings/language/UserDictionaryPreferenceController.java @@ -23,6 +23,7 @@ import android.support.v7.preference.Preference; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.inputmethod.UserDictionaryList; +import com.android.settings.inputmethod.UserDictionaryListPreferenceController; import com.android.settings.inputmethod.UserDictionarySettings; import com.android.settingslib.core.AbstractPreferenceController; @@ -61,10 +62,10 @@ public class UserDictionaryPreferenceController extends AbstractPreferenceContro // 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() + // UserDictionaryListPreferenceController#getUserDictionaryLocalesSet() // the locale list always has at least one element, since it // always includes the current locale explicitly. - // @see UserDictionaryList.getUserDictionaryLocalesSet(). + // @see UserDictionaryListPreferenceController.getUserDictionaryLocalesSet(). extras.putString("locale", localeSet.first()); } targetFragment = UserDictionarySettings.class; @@ -75,6 +76,6 @@ public class UserDictionaryPreferenceController extends AbstractPreferenceContro } protected TreeSet<String> getDictionaryLocales() { - return UserDictionaryList.getUserDictionaryLocalesSet(mContext); + return UserDictionaryListPreferenceController.getUserDictionaryLocalesSet(mContext); } } diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider index 39e63d4baa..d3fc65e136 100644 --- a/tests/robotests/assets/grandfather_not_implementing_index_provider +++ b/tests/robotests/assets/grandfather_not_implementing_index_provider @@ -8,6 +8,7 @@ com.android.settings.fuelgauge.AdvancedPowerUsageDetail com.android.settings.development.featureflags.FeatureFlagsDashboard com.android.settings.development.qstile.DevelopmentTileConfigFragment com.android.settings.deviceinfo.StorageProfileFragment +com.android.settings.inputmethod.UserDictionaryList com.android.settings.notification.ChannelNotificationSettings com.android.settings.notification.ChannelGroupNotificationSettings com.android.settings.notification.AppNotificationSettings diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable index 5a89072b2e..b7b41a652f 100644 --- a/tests/robotests/assets/grandfather_not_implementing_indexable +++ b/tests/robotests/assets/grandfather_not_implementing_indexable @@ -12,7 +12,6 @@ com.android.settings.fingerprint.FingerprintSettings$FingerprintSettingsFragment com.android.settings.applications.ProcessStatsDetail com.android.settings.wifi.WifiInfo com.android.settings.applications.VrListenerSettings -com.android.settings.inputmethod.UserDictionaryList com.android.settings.datausage.DataSaverSummary com.android.settings.datausage.AppDataUsage com.android.settings.accessibility.FontSizePreferenceFragmentForSetupWizard diff --git a/tests/robotests/src/com/android/settings/inputmethod/UserDictionaryListControllerTest.java b/tests/robotests/src/com/android/settings/inputmethod/UserDictionaryListControllerTest.java new file mode 100644 index 0000000000..273a0054c7 --- /dev/null +++ b/tests/robotests/src/com/android/settings/inputmethod/UserDictionaryListControllerTest.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2018 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.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.provider.UserDictionary; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceManager; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.shadows.ShadowContentResolver; + +import java.util.TreeSet; + +@RunWith(SettingsRobolectricTestRunner.class) +public class UserDictionaryListControllerTest { + + private Preference mPreference; + private PreferenceScreen mPreferenceScreen; + private FakeProvider mContentProvider; + private UserDictionaryListPreferenceController mController; + private Context mContext; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContentProvider = new FakeProvider(); + ShadowContentResolver.registerProviderInternal(UserDictionary.AUTHORITY, mContentProvider); + mContext = RuntimeEnvironment.application; + mController = spy(new UserDictionaryListPreferenceController(mContext, "controller_key")); + mPreference = new Preference(mContext); + final PreferenceManager preferenceManager = new PreferenceManager(mContext); + mPreferenceScreen = preferenceManager.createPreferenceScreen(mContext); + } + + @Test + public void userDictionaryList_byDefault_shouldBeShown() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void getUserDictionaryLocalesSet_noLocale_shouldReturnEmptySet() { + mContentProvider.hasDictionary = false; + + assertThat(UserDictionaryListPreferenceController.getUserDictionaryLocalesSet( + mContext)).isEmpty(); + } + + @Test + public void displayPreference_isOrderingAsAdd_shouldBeFalse() { + mController.displayPreference(mPreferenceScreen); + + assertThat(mPreferenceScreen.isOrderingAsAdded()).isFalse(); + } + + @Test + public void createUserDictSettings_emptyLocaleSetWithNewScreen_shouldAddOnePreference() { + final TreeSet<String> locales = new TreeSet<>(); + + doReturn(locales).when(mController).getUserDictLocalesSet(mContext); + + mController.setLocale(null); + mController.displayPreference(mPreferenceScreen); + mController.onStart(); + + assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(1); + } + + @Test + public void createUserDictSettings_emptyLocaleSetWithOldScreen_shouldNotAddNewPreference() { + final TreeSet<String> locales = new TreeSet<>(); + + doReturn(locales).when(mController).getUserDictLocalesSet(mContext); + mPreferenceScreen.addPreference(mPreference); + + mController.setLocale(null); + mController.displayPreference(mPreferenceScreen); + mController.onStart(); + + assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(1); + } + + @Test + public void createUserDictSettings_threeLocales_shouldAddFourPreference() { + //There will be 4 preferences : 3 locales + 1 "All languages" entry + final TreeSet<String> locales = new TreeSet<>(); + locales.add("en"); + locales.add("es"); + locales.add("fr"); + + doReturn(locales).when(mController).getUserDictLocalesSet(mContext); + + mController.setLocale("en"); + mController.displayPreference(mPreferenceScreen); + mController.onStart(); + + assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(4); + } + + public static class FakeProvider extends ContentProvider { + + private boolean hasDictionary = true; + + @Override + public boolean onCreate() { + return false; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + if (hasDictionary) { + final MatrixCursor cursor = new MatrixCursor( + new String[] {UserDictionary.Words.LOCALE}); + cursor.addRow(new Object[] {"en"}); + cursor.addRow(new Object[] {"es"}); + return cursor; + } else { + return null; + } + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + return 0; + } + } +} diff --git a/tests/robotests/src/com/android/settings/inputmethod/UserDictionaryListTest.java b/tests/robotests/src/com/android/settings/inputmethod/UserDictionaryListTest.java deleted file mode 100644 index eaf5b1d21e..0000000000 --- a/tests/robotests/src/com/android/settings/inputmethod/UserDictionaryListTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2017 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.google.common.truth.Truth.assertThat; - -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.net.Uri; -import android.provider.UserDictionary; - -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.shadows.ShadowContentResolver; - -@RunWith(SettingsRobolectricTestRunner.class) -public class UserDictionaryListTest { - - private FakeProvider mContentProvider; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContentProvider = new FakeProvider(); - ShadowContentResolver.registerProviderInternal(UserDictionary.AUTHORITY, mContentProvider); - } - - @Test - public void getUserDictionaryLocalesSet_noLocale_shouldReturnEmptySet() { - mContentProvider.hasDictionary = false; - - final Context context = RuntimeEnvironment.application; - assertThat(UserDictionaryList.getUserDictionaryLocalesSet(context)).isEmpty(); - } - - public static class FakeProvider extends ContentProvider { - - private boolean hasDictionary = true; - - @Override - public boolean onCreate() { - return false; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder) { - if (hasDictionary) { - final MatrixCursor cursor = new MatrixCursor( - new String[]{UserDictionary.Words.LOCALE}); - cursor.addRow(new Object[]{"en"}); - cursor.addRow(new Object[]{"es"}); - return cursor; - } else { - return null; - } - } - - @Override - public String getType(Uri uri) { - return null; - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - return null; - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - return 0; - } - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - return 0; - } - } -} |