From e0c253fccbb9eff3c46e40fbd557ce8afa27ddaf Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Fri, 14 Oct 2016 10:23:38 -0700 Subject: [PATCH] Add summary provider for system tile. Refactored getLocaleNames() into a FeatureProvider interface so it's reusable and testable. Bug: 31801428 Test: RunSettingsRoboTests Change-Id: I2d31a66a4b32cfa7a364a4cfef1f6eea87084577 --- res/values/strings.xml | 2 + .../settings/dashboard/DashboardFragment.java | 4 +- .../InputMethodAndLanguageSettings.java | 25 +++--- .../localepicker/LocaleFeatureProvider.java | 25 ++++++ .../LocaleFeatureProviderImpl.java | 36 +++++++++ .../settings/overlay/FeatureFactory.java | 4 + .../settings/overlay/FeatureFactoryImpl.java | 10 +++ .../system/SystemDashboardFragment.java | 30 +++++++ .../system/SystemDashboardFragmentTest.java | 81 +++++++++++++++++++ .../testutils/FakeFeatureFactory.java | 8 ++ 10 files changed, 208 insertions(+), 17 deletions(-) create mode 100644 src/com/android/settings/localepicker/LocaleFeatureProvider.java create mode 100644 src/com/android/settings/localepicker/LocaleFeatureProviderImpl.java create mode 100644 tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 6c4f882bb1d..64f61e24f63 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5919,6 +5919,8 @@ Network & Internet Connected devices + + Language: %1$s diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java index 13c2cc3d1b9..a72717d3aee 100644 --- a/src/com/android/settings/dashboard/DashboardFragment.java +++ b/src/com/android/settings/dashboard/DashboardFragment.java @@ -234,8 +234,8 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment if (tile.icon != null) { pref.setIcon(tile.icon.loadDrawable(context)); } - final Intent intent = new Intent(tile.intent); - if (intent != null) { + if (tile.intent != null) { + final Intent intent = new Intent(tile.intent); pref.setOnPreferenceClickListener(preference -> { intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, true); getActivity().startActivityForResult(intent, 0); diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java index 515a80fa8c8..98c11d363df 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java +++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java @@ -32,7 +32,6 @@ import android.hardware.input.InputManager; import android.hardware.input.KeyboardLayout; import android.os.Bundle; import android.os.Handler; -import android.os.LocaleList; import android.provider.Settings; import android.provider.Settings.System; import android.speech.tts.TtsEngines; @@ -51,8 +50,6 @@ import android.view.inputmethod.InputMethodSubtype; import android.view.textservice.SpellCheckerInfo; import android.view.textservice.TextServicesManager; -import com.android.internal.app.LocaleHelper; -import com.android.internal.app.LocalePicker; import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.Settings.KeyboardLayoutPickerActivity; @@ -63,6 +60,8 @@ import com.android.settings.UserDictionarySettings; import com.android.settings.Utils; import com.android.settings.VoiceInputOutputSettings; import com.android.settings.dashboard.SummaryLoader; +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; @@ -74,7 +73,6 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.TreeSet; public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment @@ -275,7 +273,8 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment if (!mShowsOnlyFullImeAndKeyboardList) { if (mLanguagePref != null) { - String localeNames = getLocaleNames(getActivity()); + final String localeNames = FeatureFactory.getFactory(getContext()) + .getLocaleFeatureProvider().getLocaleNames(); mLanguagePref.setSummary(localeNames); } @@ -349,14 +348,7 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment return super.onPreferenceTreeClick(preference); } - private static String getLocaleNames(Context context) { - final LocaleList locales = LocalePicker.getLocales(); - final Locale displayLocale = Locale.getDefault(); - return LocaleHelper.toSentenceCase( - LocaleHelper.getDisplayLocaleList( - locales, displayLocale, 2 /* Show up to two locales from the list */), - displayLocale); - } + private void saveInputMethodSelectorVisibility(String value) { try { @@ -667,16 +659,18 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment 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(); } @Override public void setListening(boolean listening) { if (listening) { - String localeNames = getLocaleNames(mContext); + String localeNames = mLocaleFeatureProvider.getLocaleNames(); mSummaryLoader.setSummary(this, localeNames); } } @@ -701,7 +695,8 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment // Locale picker. if (context.getAssets().getLocales().length > 1) { - String localeNames = getLocaleNames(context); + String localeNames = FeatureFactory.getFactory(context).getLocaleFeatureProvider() + .getLocaleNames(); SearchIndexableRaw indexable = new SearchIndexableRaw(context); indexable.key = KEY_PHONE_LANGUAGE; indexable.title = context.getString(R.string.phone_language); diff --git a/src/com/android/settings/localepicker/LocaleFeatureProvider.java b/src/com/android/settings/localepicker/LocaleFeatureProvider.java new file mode 100644 index 00000000000..7201bc1afee --- /dev/null +++ b/src/com/android/settings/localepicker/LocaleFeatureProvider.java @@ -0,0 +1,25 @@ +/* + * 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.localepicker; + +public interface LocaleFeatureProvider { + + /** + * Returns displayable string of device locales. + */ + String getLocaleNames(); +} diff --git a/src/com/android/settings/localepicker/LocaleFeatureProviderImpl.java b/src/com/android/settings/localepicker/LocaleFeatureProviderImpl.java new file mode 100644 index 00000000000..64a01a3530e --- /dev/null +++ b/src/com/android/settings/localepicker/LocaleFeatureProviderImpl.java @@ -0,0 +1,36 @@ +/* + * 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.localepicker; + +import android.os.LocaleList; + +import com.android.internal.app.LocaleHelper; +import com.android.internal.app.LocalePicker; + +import java.util.Locale; + +public class LocaleFeatureProviderImpl implements LocaleFeatureProvider { + @Override + public String getLocaleNames() { + final LocaleList locales = LocalePicker.getLocales(); + final Locale displayLocale = Locale.getDefault(); + return LocaleHelper.toSentenceCase( + LocaleHelper.getDisplayLocaleList( + locales, displayLocale, 2 /* Show up to two locales from the list */), + displayLocale); + } +} diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java index 485abd08bdf..35ec40f3a65 100644 --- a/src/com/android/settings/overlay/FeatureFactory.java +++ b/src/com/android/settings/overlay/FeatureFactory.java @@ -24,6 +24,7 @@ import com.android.settings.R; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.fuelgauge.PowerUsageFeatureProvider; +import com.android.settings.localepicker.LocaleFeatureProvider; /** * Abstract class for creating feature controllers. Allows OEM implementations to define their own @@ -70,6 +71,9 @@ public abstract class FeatureFactory { public abstract DashboardFeatureProvider getDashboardFeatureProvider(Context context); + public abstract LocaleFeatureProvider getLocaleFeatureProvider(); + + public static final class FactoryNotFoundException extends RuntimeException { public FactoryNotFoundException(Throwable throwable) { super("Unable to create factory. Did you misconfigure Proguard?", throwable); diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java index 65015c32e4c..976ee3c0bc4 100644 --- a/src/com/android/settings/overlay/FeatureFactoryImpl.java +++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java @@ -24,6 +24,8 @@ import com.android.settings.core.instrumentation.MetricsFeatureProviderImpl; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProviderImpl; import com.android.settings.fuelgauge.PowerUsageFeatureProvider; +import com.android.settings.localepicker.LocaleFeatureProvider; +import com.android.settings.localepicker.LocaleFeatureProviderImpl; /** * {@link FeatureFactory} implementation for AOSP Settings. @@ -33,6 +35,7 @@ public final class FeatureFactoryImpl extends FeatureFactory { private MetricsFeatureProvider mMetricsFeatureProvider; private DashboardFeatureProviderImpl mDashboardFeatureProvider; + private LocaleFeatureProvider mLocaleFeatureProvider; @Override public SupportFeatureProvider getSupportFeatureProvider(Context context) { @@ -60,4 +63,11 @@ public final class FeatureFactoryImpl extends FeatureFactory { return mDashboardFeatureProvider; } + @Override + public LocaleFeatureProvider getLocaleFeatureProvider() { + if (mLocaleFeatureProvider == null) { + mLocaleFeatureProvider = new LocaleFeatureProviderImpl(); + } + return mLocaleFeatureProvider; + } } diff --git a/src/com/android/settings/system/SystemDashboardFragment.java b/src/com/android/settings/system/SystemDashboardFragment.java index 6f1e6f6cc1b..5e0a2024483 100644 --- a/src/com/android/settings/system/SystemDashboardFragment.java +++ b/src/com/android/settings/system/SystemDashboardFragment.java @@ -22,8 +22,10 @@ import android.provider.SearchIndexableResource; import com.android.settings.R; import com.android.settings.core.PreferenceController; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.dashboard.SummaryLoader; import com.android.settings.deviceinfo.AdditionalSystemUpdatePreferenceController; import com.android.settings.deviceinfo.SystemUpdatePreferenceController; +import com.android.settings.localepicker.LocaleFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; @@ -66,6 +68,34 @@ public class SystemDashboardFragment extends DashboardFragment { return controllers; } + /** + * For Summary + */ + private static class SummaryProvider implements SummaryLoader.SummaryProvider { + + private final Context mContext; + private final SummaryLoader mSummaryLoader; + private final LocaleFeatureProvider mLocaleFeatureProvider; + + public SummaryProvider(Context context, SummaryLoader summaryLoader) { + mContext = context; + mSummaryLoader = summaryLoader; + mLocaleFeatureProvider = FeatureFactory.getFactory(context).getLocaleFeatureProvider(); + } + + @Override + public void setListening(boolean listening) { + if (listening) { + final String language = mContext.getString( + R.string.system_dashboard_summary, mLocaleFeatureProvider.getLocaleNames()); + mSummaryLoader.setSummary(this, language); + } + } + } + + public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY = + (context, summaryLoader) -> new SummaryProvider(context, summaryLoader); + /** * For Search. */ diff --git a/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java new file mode 100644 index 00000000000..eb8b43bfe77 --- /dev/null +++ b/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java @@ -0,0 +1,81 @@ +/* + * 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.system; + + +import android.app.Activity; + +import com.android.settings.TestConfig; +import com.android.settings.dashboard.SummaryLoader; +import com.android.settings.testutils.FakeFeatureFactory; + +import com.google.common.truth.Truth; + +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.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import static com.android.settings.system.SystemDashboardFragment.SUMMARY_PROVIDER_FACTORY; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +@RunWith(RobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class SystemDashboardFragmentTest { + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Activity mActivity; + @Mock + private SummaryLoader mSummaryLoader; + + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + FakeFeatureFactory.setupForTest(mActivity); + } + + @Test + public void hasSummaryProvider() { + Truth.assertThat(SUMMARY_PROVIDER_FACTORY).isNotNull(); + } + + @Test + public void updateSummary_isListening_shouldNotifySummaryLoader() { + final SummaryLoader.SummaryProvider summaryProvider = + SUMMARY_PROVIDER_FACTORY.createSummaryProvider(mActivity, mSummaryLoader); + summaryProvider.setListening(true); + + verify(mSummaryLoader).setSummary(eq(summaryProvider), anyString()); + } + + @Test + public void updateSummary_notListening_shouldNotNotifySummaryLoader() { + final SummaryLoader.SummaryProvider summaryProvider = + SUMMARY_PROVIDER_FACTORY.createSummaryProvider(mActivity, mSummaryLoader); + summaryProvider.setListening(false); + + verify(mSummaryLoader, never()).setSummary(eq(summaryProvider), anyString()); + } +} diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java index 0aaec5a547c..d872f7c85db 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -20,6 +20,7 @@ import android.content.Context; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.fuelgauge.PowerUsageFeatureProvider; +import com.android.settings.localepicker.LocaleFeatureProvider; import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.SupportFeatureProvider; @@ -37,6 +38,7 @@ public class FakeFeatureFactory extends FeatureFactory { public final MetricsFeatureProvider metricsFeatureProvider; public final PowerUsageFeatureProvider powerUsageFeatureProvider; public final DashboardFeatureProvider dashboardFeatureProvider; + public final LocaleFeatureProvider localeFeatureProvider; /** * Call this in {@code @Before} method of the test class to use fake factory. @@ -63,6 +65,7 @@ public class FakeFeatureFactory extends FeatureFactory { metricsFeatureProvider = mock(MetricsFeatureProvider.class); powerUsageFeatureProvider = mock(PowerUsageFeatureProvider.class); dashboardFeatureProvider = mock(DashboardFeatureProvider.class); + localeFeatureProvider = mock(LocaleFeatureProvider.class); } @Override @@ -84,4 +87,9 @@ public class FakeFeatureFactory extends FeatureFactory { public DashboardFeatureProvider getDashboardFeatureProvider(Context context) { return dashboardFeatureProvider; } + + @Override + public LocaleFeatureProvider getLocaleFeatureProvider() { + return localeFeatureProvider; + } }