Bug 1404460: Only show Pocket stories in specified locales. r=liuche
Ideally, we'd centralize all queries as to which options are user specified.
However, I wanted to do the smallest change so we can uplift so I filed
bug 1405161 for this centralization.
I opted not to include the "de" locale that is included on desktop because it
does not appear we ever get the "de" locale on Firefox for Android [1].
I tested this patch by changing the system locale between locales with Pocket
on my device (en-US, en-GB, de-DE) and locales without Pocket (ko-KR). The
locale switching system makes this refresh automatically without extra code.
I also intend to test via the in-app locale switcher but that will take time
because I can't do artifact builds with multi-locale so I'm pushing this for
review before I'm finished.
Follow-up changes:
- Add to telemetry
- Hiding the preference in the undesired locales.
- A test for isPocketEnabledByLocaleInner (useful to document how this is
intended to work for locales with variants, different scripts, etc.)
[1]: https://sql.telemetry.mozilla.org/queries/4613#table
MozReview-Commit-ID: 7AVQ8fWub8I
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStreamTelemetry.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStreamTelemetry.java
@@ -74,16 +74,17 @@ public class ActivityStreamTelemetry {
* Calculates the bit-packed value of the user's Activity Stream preferences (e.g. enabled/disabled sections).
*
* @param sharedPreferences SharedPreferences of this profile
* @return bit-packed value of the user's AS preferences, which is the sum of the values of the enabled preferences.
*/
public static int getASUserPreferencesValue(final SharedPreferences sharedPreferences, final Resources res) {
int bitPackedPrefValue = 0;
+ // todo: Add bit for isPocketAllowedByLocale.
if (sharedPreferences.getBoolean(ActivityStreamPanel.PREF_POCKET_ENABLED, res.getBoolean(R.bool.pref_activitystream_pocket_enabled_default))) {
bitPackedPrefValue += POCKET_ENABLED_VALUE;
}
if (sharedPreferences.getBoolean(ActivityStreamPanel.PREF_VISITED_ENABLED, res.getBoolean(R.bool.pref_activitystream_visited_enabled_default))) {
bitPackedPrefValue += VISITED_ENABLED_VALUE;
}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamConfiguration.java
@@ -0,0 +1,66 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko.activitystream.homepanel;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.support.annotation.VisibleForTesting;
+import org.mozilla.gecko.BrowserLocaleManager;
+import org.mozilla.gecko.Locales;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * Static functions for accessing user configuration information.
+ *
+ * TODO (bug 1405161): we should move all configuration accesses to this class to centralize them.
+ */
+public class ActivityStreamConfiguration {
+
+ private static final Set<Locale> enabledLocales;
+
+ static {
+ final String[] enabledLocaleTags = new String[] {
+ // Sorted alphabetically to preserve blame for additions/removals.
+ "de-AT",
+ "de-CH",
+ "de-DE",
+ "en-GB",
+ "en-US",
+ "en-ZA",
+ };
+
+ final Set<Locale> mutableEnabledLocales = new HashSet<>();
+ for (final String enabledLocaleTag : enabledLocaleTags) {
+ mutableEnabledLocales.add(Locales.parseLocaleCode(enabledLocaleTag));
+ }
+ enabledLocales = Collections.unmodifiableSet(mutableEnabledLocales);
+ }
+
+ private ActivityStreamConfiguration() {}
+
+ public static boolean isPocketEnabledByLocale(final Context context) {
+ // Unintuitively, `BrowserLocaleManager.getCurrentLocale` returns the current user overridden locale,
+ // or null if the user hasn't overidden the system default.
+ final Locale currentLocale;
+ final Locale userOverriddenLocale = BrowserLocaleManager.getInstance().getCurrentLocale(context);
+ if (userOverriddenLocale != null) {
+ currentLocale = userOverriddenLocale;
+ } else {
+ // `locale` was deprecated in API 24 but our target SDK is too low to use the new method.
+ currentLocale = context.getResources().getConfiguration().locale;
+ }
+
+ return isPocketEnabledByLocaleInner(currentLocale);
+ }
+
+ @VisibleForTesting static boolean isPocketEnabledByLocaleInner(final Locale locale) {
+ return enabledLocales.contains(locale);
+ }
+}
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamPanel.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/ActivityStreamPanel.java
@@ -106,17 +106,18 @@ public class ActivityStreamPanel extends
}
public void load(LoaderManager lm) {
lm.initLoader(LOADER_ID_TOPSITES, null, new TopSitesCallback());
if (sharedPreferences.getBoolean(PREF_BOOKMARKS_ENABLED, true) || sharedPreferences.getBoolean(PREF_VISITED_ENABLED, true)) {
lm.initLoader(LOADER_ID_HIGHLIGHTS, null, new HighlightsCallbacks());
}
- if (sharedPreferences.getBoolean(PREF_POCKET_ENABLED, true)) {
+ if (ActivityStreamConfiguration.isPocketEnabledByLocale(getContext()) &&
+ sharedPreferences.getBoolean(PREF_POCKET_ENABLED, true)) {
lm.initLoader(LOADER_ID_POCKET, null, new PocketStoriesCallbacks());
}
}
public void unload() {
adapter.swapHighlights(Collections.<Highlight>emptyList());
--- a/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/StreamRecyclerAdapter.java
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/homepanel/StreamRecyclerAdapter.java
@@ -192,17 +192,18 @@ public class StreamRecyclerAdapter exten
final SharedPreferences sharedPreferences = GeckoSharedPrefs.forProfile(context);
final boolean bookmarksEnabled = sharedPreferences.getBoolean(ActivityStreamPanel.PREF_BOOKMARKS_ENABLED,
context.getResources().getBoolean(R.bool.pref_activitystream_recentbookmarks_enabled_default));
final boolean visitedEnabled = sharedPreferences.getBoolean(ActivityStreamPanel.PREF_VISITED_ENABLED,
context.getResources().getBoolean(R.bool.pref_activitystream_visited_enabled_default));
setViewVisible(bookmarksEnabled || visitedEnabled, holder.itemView);
} else if (type == RowItemType.TOP_STORIES_TITLE.getViewType()) {
final Context context = holder.itemView.getContext();
- final boolean pocketEnabled = GeckoSharedPrefs.forProfile(context).getBoolean(ActivityStreamPanel.PREF_POCKET_ENABLED,
+ final boolean pocketEnabled = ActivityStreamConfiguration.isPocketEnabledByLocale(context) &&
+ GeckoSharedPrefs.forProfile(context).getBoolean(ActivityStreamPanel.PREF_POCKET_ENABLED,
context.getResources().getBoolean(R.bool.pref_activitystream_pocket_enabled_default));
setViewVisible(pocketEnabled, holder.itemView);
}
}
/**
* This sets a child view of the adapter visible or hidden.
*
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -501,16 +501,17 @@ gbjar.sources += ['java/org/mozilla/geck
'AboutPages.java',
'AccountsHelper.java',
'ActionBarTextSelection.java',
'ActionModeCompat.java',
'ActionModeCompatView.java',
'ActivityHandlerHelper.java',
'activitystream/ActivityStream.java',
'activitystream/ActivityStreamTelemetry.java',
+ 'activitystream/homepanel/ActivityStreamConfiguration.java',
'activitystream/homepanel/ActivityStreamHomeFragment.java',
'activitystream/homepanel/ActivityStreamHomeScreen.java',
'activitystream/homepanel/ActivityStreamPanel.java',
'activitystream/homepanel/HighlightsDividerItemDecoration.java',
'activitystream/homepanel/HighlightsLoader.java',
'activitystream/homepanel/menu/ActivityStreamContextMenu.java',
'activitystream/homepanel/menu/BottomSheetContextMenu.java',
'activitystream/homepanel/menu/PopupContextMenu.java',