Bug 1290012 - Introduce setting to enable experimental activity stream feature. r?ahunt
If the app is build with MOZ_ANDROID_ACTIVITY_STREAM enabled then a preference for
activity stream will appear in the 'advanced' section. All upcoming activity stream
features should check ActivityStream.isEnabled() at runtime.
MozReview-Commit-ID: Hibh1j0lqFo
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -7,16 +7,17 @@ package org.mozilla.gecko;
import android.Manifest;
import android.app.DownloadManager;
import android.os.Environment;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import org.json.JSONArray;
+import org.mozilla.gecko.activitystream.ActivityStream;
import org.mozilla.gecko.adjust.AdjustHelperInterface;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.DynamicToolbar.VisibilityTransition;
import org.mozilla.gecko.Tabs.TabEvents;
import org.mozilla.gecko.animation.PropertyAnimator;
import org.mozilla.gecko.animation.ViewHelper;
import org.mozilla.gecko.cleanup.FileCleanupController;
@@ -2686,17 +2687,17 @@ public class BrowserApp extends GeckoApp
// Show the toolbar before hiding about:home so the
// onMetricsChanged callback still works.
if (mDynamicToolbar.isEnabled()) {
mDynamicToolbar.setVisible(true, VisibilityTransition.IMMEDIATE);
}
if (mHomeScreen == null) {
- if (AppConstants.MOZ_ANDROID_ACTIVITY_STREAM) {
+ if (ActivityStream.isEnabled(this)) {
final ViewStub asStub = (ViewStub) findViewById(R.id.activity_stream_stub);
mHomeScreen = (HomeScreen) asStub.inflate();
} else {
final ViewStub homePagerStub = (ViewStub) findViewById(R.id.home_pager_stub);
mHomeScreen = (HomeScreen) homePagerStub.inflate();
// For now these listeners are HomePager specific. In future we might want
// to have a more abstracted data storage, with one Bundle containing all
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java
@@ -887,17 +887,17 @@ public class GeckoAppShell
@WrapForJNI
public static void moveTaskToBack() {
if (getGeckoInterface() != null)
getGeckoInterface().getActivity().moveTaskToBack(true);
}
@WrapForJNI
- static void scheduleRestart() {
+ public static void scheduleRestart() {
getGeckoInterface().doRestart();
}
// Creates a homescreen shortcut for a web page.
// This is the entry point from nsIShellService.
@WrapForJNI
public static void createShortcut(final String aTitle, final String aURI) {
final GeckoInterface geckoInterface = getGeckoInterface();
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStream.java
@@ -0,0 +1,23 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
+ * 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;
+
+import android.content.Context;
+
+import org.mozilla.gecko.AppConstants;
+import org.mozilla.gecko.GeckoSharedPrefs;
+import org.mozilla.gecko.preferences.GeckoPreferences;
+
+public class ActivityStream {
+ public static boolean isEnabled(Context context) {
+ if (!AppConstants.MOZ_ANDROID_ACTIVITY_STREAM) {
+ return false;
+ }
+
+ return GeckoSharedPrefs.forApp(context)
+ .getBoolean(GeckoPreferences.PREFS_ACTIVITY_STREAM, false);
+ }
+}
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
@@ -161,16 +161,18 @@ OnSharedPreferenceChangeListener
private static final String PREFS_FEEDBACK_LINK = NON_PREF_PREFIX + "feedback.link";
public static final String PREFS_NOTIFICATIONS_CONTENT = NON_PREF_PREFIX + "notifications.content";
public static final String PREFS_NOTIFICATIONS_CONTENT_LEARN_MORE = NON_PREF_PREFIX + "notifications.content.learn_more";
public static final String PREFS_NOTIFICATIONS_WHATS_NEW = NON_PREF_PREFIX + "notifications.whats_new";
public static final String PREFS_APP_UPDATE_LAST_BUILD_ID = "app.update.last_build_id";
public static final String PREFS_READ_PARTNER_CUSTOMIZATIONS_PROVIDER = NON_PREF_PREFIX + "distribution.read_partner_customizations_provider";
public static final String PREFS_READ_PARTNER_BOOKMARKS_PROVIDER = NON_PREF_PREFIX + "distribution.read_partner_bookmarks_provider";
public static final String PREFS_CUSTOM_TABS = NON_PREF_PREFIX + "customtabs";
+ public static final String PREFS_ACTIVITY_STREAM = NON_PREF_PREFIX + "activitystream";
+ public static final String PREFS_CATEGORY_EXPERIMENTAL_FEATURES = NON_PREF_PREFIX + "category_experimental";
private static final String ACTION_STUMBLER_UPLOAD_PREF = "STUMBLER_PREF";
// This isn't a Gecko pref, even if it looks like one.
private static final String PREFS_BROWSER_LOCALE = "locale";
public static final String PREFS_RESTORE_SESSION = NON_PREF_PREFIX + "restoreSession3";
@@ -690,16 +692,22 @@ OnSharedPreferenceChangeListener
i--;
continue;
}
} else if (PREFS_SCREEN_ADVANCED.equals(key) &&
!Restrictions.isAllowed(this, Restrictable.ADVANCED_SETTINGS)) {
preferences.removePreference(pref);
i--;
continue;
+ } else if (PREFS_CATEGORY_EXPERIMENTAL_FEATURES.equals(key)
+ && !AppConstants.MOZ_ANDROID_ACTIVITY_STREAM
+ && !AppConstants.MOZ_ANDROID_CUSTOM_TABS) {
+ preferences.removePreference(pref);
+ i--;
+ continue;
}
setupPreferences((PreferenceGroup) pref, prefs);
} else {
if (HANDLERS.containsKey(key)) {
PrefHandler handler = HANDLERS.get(key);
if (!handler.setupPref(this, pref)) {
preferences.removePreference(pref);
i--;
@@ -886,16 +894,20 @@ OnSharedPreferenceChangeListener
preferences.removePreference(pref);
i--;
continue;
}
} else if (PREFS_CUSTOM_TABS.equals(key) && !AppConstants.MOZ_ANDROID_CUSTOM_TABS) {
preferences.removePreference(pref);
i--;
continue;
+ } else if (PREFS_ACTIVITY_STREAM.equals(key) && !AppConstants.MOZ_ANDROID_ACTIVITY_STREAM) {
+ preferences.removePreference(pref);
+ i--;
+ continue;
}
// Some Preference UI elements are not actually preferences,
// but they require a key to work correctly. For example,
// "Clear private data" requires a key for its state to be
// saved when the orientation changes. It uses the
// "android.not_a_preference.privacy.clear" key - which doesn't
// exist in Gecko - to satisfy this requirement.
@@ -1196,16 +1208,23 @@ OnSharedPreferenceChangeListener
} else if (PREFS_TAB_QUEUE.equals(prefName)) {
if ((Boolean) newValue && !TabQueueHelper.canDrawOverlays(this)) {
Intent promptIntent = new Intent(this, TabQueuePrompt.class);
startActivityForResult(promptIntent, REQUEST_CODE_TAB_QUEUE);
return false;
}
} else if (PREFS_NOTIFICATIONS_CONTENT.equals(prefName)) {
FeedService.setup(this);
+ } else if (PREFS_ACTIVITY_STREAM.equals(prefName)) {
+ ThreadUtils.postDelayedToUiThread(new Runnable() {
+ @Override
+ public void run() {
+ GeckoAppShell.scheduleRestart();
+ }
+ }, 1000);
} else if (HANDLERS.containsKey(prefName)) {
PrefHandler handler = HANDLERS.get(prefName);
handler.onChange(this, preference, newValue);
}
// Send Gecko-side pref changes to Gecko
if (isGeckoPref(prefName)) {
PrefsHelper.setPref(prefName, newValue, true /* flush */);
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -267,22 +267,30 @@
<!ENTITY pref_tracking_protection_enabled "Enabled">
<!ENTITY pref_tracking_protection_enabled_pb "Enabled in Private Browsing">
<!ENTITY pref_tracking_protection_disabled "Disabled">
<!ENTITY pref_whats_new_notification "What\'s new in &brandShortName;">
<!ENTITY pref_whats_new_notification_summary "Learn about new features after an update">
+<!-- Localization note (pref_category_experimental): Title of a sub category in the 'advanced' category
+ for experimental features. -->
+<!ENTITY pref_category_experimental "Experimental features">
+
<!-- Custom Tabs is an Android API for allowing third-party apps to open URLs in a customized UI.
Instead of switching to the browser it appears as if the user stays in the third-party app.
For more see: https://developer.chrome.com/multidevice/android/customtabs -->
<!ENTITY pref_custom_tabs "Custom Tabs">
<!ENTITY pref_custom_tabs_summary "Allow third-party apps to open URLs with a customized look and feel.">
+<!-- Localization note (pref_activity_stream): Experimental feature, see https://testpilot.firefox.com/experiments/activity-stream -->
+<!ENTITY pref_activity_stream "Activity Stream">
+<!ENTITY pref_activity_stream_summary "A rich visual history feed and a reimagined home page make it easier than ever to find exactly what you\'re looking for in &brandShortName;.">
+
<!ENTITY tracking_protection_prompt_title "Now with Tracking Protection">
<!ENTITY tracking_protection_prompt_text "Actively block tracking elements so you don\'t have to worry.">
<!ENTITY tracking_protection_prompt_tip_text "Visit Privacy settings to learn more">
<!ENTITY tracking_protection_prompt_action_button "Got it!">
<!ENTITY tab_queue_toast_message3 "Tab saved in &brandShortName;">
<!ENTITY tab_queue_toast_action "Open now">
<!ENTITY tab_queue_prompt_title "Opening multiple links?">
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -200,16 +200,17 @@ if CONFIG['MOZ_WEBRTC']:
gbjar = add_java_jar('gecko-browser')
gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
'AboutPages.java',
'AccountsHelper.java',
'ActionBarTextSelection.java',
'ActionModeCompat.java',
'ActionModeCompatView.java',
'ActivityHandlerHelper.java',
+ 'activitystream/ActivityStream.java',
'AlarmReceiver.java',
'AndroidGamepadManager.java',
'animation/AnimationUtils.java',
'animation/HeightChangeAnimation.java',
'animation/PropertyAnimator.java',
'animation/Rotate3DAnimation.java',
'animation/ViewHelper.java',
'ANRReporter.java',
--- a/mobile/android/base/resources/xml/preferences_advanced.xml
+++ b/mobile/android/base/resources/xml/preferences_advanced.xml
@@ -33,21 +33,16 @@
android:persistent="true" />
<ListPreference android:key="browser.menu.showCharacterEncoding"
android:title="@string/pref_char_encoding"
android:entries="@array/pref_char_encoding_entries"
android:entryValues="@array/pref_char_encoding_values"
android:persistent="false" />
- <SwitchPreference android:key="android.not_a_preference.customtabs"
- android:title="@string/pref_custom_tabs"
- android:summary="@string/pref_custom_tabs_summary"
- android:defaultValue="false" />
-
<PreferenceCategory android:title="@string/pref_category_data_saver">
<ListPreference android:key="browser.image_blocking"
android:title="@string/pref_tap_to_load_images_title2"
android:entries="@array/pref_browser_image_blocking_entries"
android:entryValues="@array/pref_browser_image_blocking_values"
android:persistent="false" />
@@ -80,9 +75,26 @@
android:title="@string/pref_developer_remotedebugging_wifi" />
<org.mozilla.gecko.preferences.AlignRightLinkPreference android:key="android.not_a_preference.remote_debugging.link"
android:title="@string/pref_learn_more"
android:persistent="false"
url="https://developer.mozilla.org/docs/Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE" />
</PreferenceCategory>
+ <PreferenceCategory
+ android:key="android.not_a_preference.category_experimental"
+ android:title="@string/pref_category_experimental">
+
+ <SwitchPreference android:key="android.not_a_preference.activitystream"
+ android:title="@string/pref_activity_stream"
+ android:summary="@string/pref_activity_stream_summary"
+ android:defaultValue="false" />
+
+
+ <SwitchPreference android:key="android.not_a_preference.customtabs"
+ android:title="@string/pref_custom_tabs"
+ android:summary="@string/pref_custom_tabs_summary"
+ android:defaultValue="false" />
+
+ </PreferenceCategory>
+
</PreferenceScreen>
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -229,19 +229,24 @@
<string name="pref_tracking_protection_enabled">&pref_tracking_protection_enabled;</string>
<string name="pref_tracking_protection_enabled_pb">&pref_tracking_protection_enabled_pb;</string>
<string name="pref_tracking_protection_disabled">&pref_tracking_protection_disabled;</string>
<string name="pref_whats_new_notification">&pref_whats_new_notification;</string>
<string name="pref_whats_new_notification_summary">&pref_whats_new_notification_summary;</string>
+ <string name="pref_category_experimental">&pref_category_experimental;</string>
+
<string name="pref_custom_tabs">&pref_custom_tabs;</string>
<string name="pref_custom_tabs_summary">&pref_custom_tabs_summary;</string>
+ <string name="pref_activity_stream">&pref_activity_stream;</string>
+ <string name="pref_activity_stream_summary">&pref_activity_stream_summary;</string>
+
<string name="pref_char_encoding">&pref_char_encoding;</string>
<string name="pref_char_encoding_on">&pref_char_encoding_on;</string>
<string name="pref_char_encoding_off">&pref_char_encoding_off;</string>
<string name="pref_clear_private_data_now">&pref_clear_private_data2;</string>
<string name="pref_clear_private_data_now_tablet">&pref_clear_private_data_now_tablet;</string>
<string name="pref_clear_on_exit_title">&pref_clear_on_exit_title3;</string>
<string name="pref_clear_on_exit_summary2">&pref_clear_on_exit_summary2;</string>
<string name="pref_clear_on_exit_dialog_title">&pref_clear_on_exit_dialog_title;</string>