Bug 1290012 - Introduce setting to enable experimental activity stream feature. r=ahunt
authorSebastian Kaspari <s.kaspari@gmail.com>
Thu, 28 Jul 2016 21:12:58 +0200
changeset 349504 9aa406751838844273a8794c58efdea837dcc10a
parent 349503 d65a4acc9227e75c8dc1ab664108fa2d84c1c400
child 349505 dd8e8efffcb33224c661ea51323ceaffc81bf914
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersahunt
bugs1290012
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java
mobile/android/base/java/org/mozilla/gecko/activitystream/ActivityStream.java
mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
mobile/android/base/locales/en-US/android_strings.dtd
mobile/android/base/moz.build
mobile/android/base/resources/xml/preferences_advanced.xml
mobile/android/base/strings.xml.in
--- 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>