Bug 1398819 - Turn on prerendered version of activity stream in aboutNewTabService draft bug1398819
authork88hudson <khudson@mozilla.com>
Mon, 11 Sep 2017 13:22:44 -0400
changeset 663084 2da27fd5c3e1758a0ab7be0f32d3282b6b14d593
parent 662980 b0e945eed81db8bf076daf64e381c514f70144f0
child 731083 2795a8876407f949e2059ed4668c785c48d45bb7
push id79309
push userkhudson@mozilla.com
push dateTue, 12 Sep 2017 15:31:15 +0000
bugs1398819
milestone57.0a1
Bug 1398819 - Turn on prerendered version of activity stream in aboutNewTabService MozReview-Commit-ID: 3v9UR0A9K1z
browser/app/profile/firefox.js
browser/base/content/test/static/browser_all_files_referenced.js
browser/components/newtab/aboutNewTabService.js
browser/components/newtab/nsIAboutNewTabService.idl
browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1261,16 +1261,17 @@ pref("browser.newtabpage.rows", 3);
 // number of columns of newtab grid
 pref("browser.newtabpage.columns", 5);
 
 // directory tiles download URL
 pref("browser.newtabpage.directory.source", "https://tiles.services.mozilla.com/v3/links/fetch/%LOCALE%/%CHANNEL%");
 
 // activates Activity Stream
 pref("browser.newtabpage.activity-stream.enabled", true);
+pref("browser.newtabpage.activity-stream.prerender", true);
 pref("browser.newtabpage.activity-stream.aboutHome.enabled", false);
 
 // Enable the DOM fullscreen API.
 pref("full-screen-api.enabled", true);
 
 // Startup Crash Tracking
 // number of startup crashes that can occur before starting into safe mode automatically
 // (this pref has no effect if more than 6 hours have passed since the last crash)
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -82,20 +82,16 @@ var whitelist = [
 
   // Add-on API introduced in bug 1118285
   {file: "resource://app/modules/NewTabURL.jsm"},
 
   // browser/components/newtab bug 1355166
   {file: "resource://app/modules/NewTabSearchProvider.jsm"},
   {file: "resource://app/modules/NewTabWebChannel.jsm"},
 
-  // browser/extensions/activity-stream/data/content/activity-stream-prerendered.html
-  // This will used when Bug 1397875 lands
-  {file: "resource://activity-stream/data/content/activity-stream-prerendered.html"},
-
   // layout/mathml/nsMathMLChar.cpp
   {file: "resource://gre/res/fonts/mathfontSTIXGeneral.properties"},
   {file: "resource://gre/res/fonts/mathfontUnicode.properties"},
 
   // toolkit/components/places/ColorAnalyzer_worker.js
   {file: "resource://gre/modules/ClusterLib.js"},
   {file: "resource://gre/modules/ColorConversion.js"},
 
--- a/browser/components/newtab/aboutNewTabService.js
+++ b/browser/components/newtab/aboutNewTabService.js
@@ -12,26 +12,30 @@ Cu.import("resource://gre/modules/XPCOMU
 Cu.import("resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "AboutNewTab",
                                   "resource:///modules/AboutNewTab.jsm");
 
 const LOCAL_NEWTAB_URL = "chrome://browser/content/newtab/newTab.xhtml";
 
 const ACTIVITY_STREAM_URL = "resource://activity-stream/data/content/activity-stream.html";
 
+const ACTIVITY_STREAM_PRERENDER_URL = "resource://activity-stream/data/content/activity-stream-prerendered.html";
+
 const ABOUT_URL = "about:newtab";
 
 const IS_MAIN_PROCESS = Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_DEFAULT;
 
 // Pref that tells if activity stream is enabled
 const PREF_ACTIVITY_STREAM_ENABLED = "browser.newtabpage.activity-stream.enabled";
+const PREF_ACTIVITY_STREAM_PRERENDER_ENABLED = "browser.newtabpage.activity-stream.prerender";
 
 function AboutNewTabService() {
   Services.obs.addObserver(this, "quit-application-granted");
   Services.prefs.addObserver(PREF_ACTIVITY_STREAM_ENABLED, this);
+  Services.prefs.addObserver(PREF_ACTIVITY_STREAM_PRERENDER_ENABLED, this);
   this.toggleActivityStream();
   if (IS_MAIN_PROCESS) {
     AboutNewTab.init();
   }
 }
 
 /*
  * A service that allows for the overriding, at runtime, of the newtab page's url.
@@ -66,37 +70,44 @@ function AboutNewTabService() {
  * Loading a chrome resource, or an about: URL in the redirector with either the
  * LOAD_NORMAL or LOAD_REPLACE flags yield unexpected behaviors, so a roundtrip
  * to the redirector from browser chrome is avoided.
  */
 AboutNewTabService.prototype = {
 
   _newTabURL: ABOUT_URL,
   _activityStreamEnabled: false,
+  _activityStreamPrerender: true,
   _overridden: false,
 
   classID: Components.ID("{dfcd2adc-7867-4d3a-ba70-17501f208142}"),
   QueryInterface: XPCOMUtils.generateQI([
     Ci.nsIAboutNewTabService,
     Ci.nsIObserver
   ]),
   _xpcom_categories: [{
     service: true
   }],
 
   observe(subject, topic, data) {
     switch (topic) {
       case "nsPref:changed":
-        if (this.toggleActivityStream()) {
+        if (data === PREF_ACTIVITY_STREAM_ENABLED) {
+          if (this.toggleActivityStream()) {
+            Services.obs.notifyObservers(null, "newtab-url-changed", ABOUT_URL);
+          }
+        } else if (data === PREF_ACTIVITY_STREAM_PRERENDER_ENABLED) {
+          this._activityStreamPrerender = Services.prefs.getBoolPref(PREF_ACTIVITY_STREAM_PRERENDER_ENABLED);
           Services.obs.notifyObservers(null, "newtab-url-changed", ABOUT_URL);
         }
         break;
       case "quit-application-granted":
         Services.obs.removeObserver(this, "quit-application-granted");
         Services.prefs.removeObserver(PREF_ACTIVITY_STREAM_ENABLED, this);
+        Services.prefs.removeObserver(PREF_ACTIVITY_STREAM_PRERENDER_ENABLED, this);
         if (IS_MAIN_PROCESS) {
           AboutNewTab.uninit();
         }
         break;
     }
   },
 
   /**
@@ -134,17 +145,17 @@ AboutNewTabService.prototype = {
    *
    * This URL only depends on the browser.newtabpage.activity-stream.enabled pref. Overriding
    * the newtab page has no effect on the result of this function.
    *
    * @returns {String} the default newtab URL, activity-stream or regular depending on browser.newtabpage.activity-stream.enabled
    */
   get defaultURL() {
     if (this.activityStreamEnabled) {
-      return this.activityStreamURL;
+      return this.activityStreamPrerender ? this.activityStreamPrerenderURL : this.activityStreamURL;
     }
     return LOCAL_NEWTAB_URL;
   },
 
   get newTabURL() {
     return this._newTabURL;
   },
 
@@ -167,20 +178,28 @@ AboutNewTabService.prototype = {
   get overridden() {
     return this._overridden;
   },
 
   get activityStreamEnabled() {
     return this._activityStreamEnabled;
   },
 
+  get activityStreamPrerender() {
+    return this._activityStreamPrerender;
+  },
+
   get activityStreamURL() {
     return ACTIVITY_STREAM_URL;
   },
 
+  get activityStreamPrerenderURL() {
+    return ACTIVITY_STREAM_PRERENDER_URL;
+  },
+
   resetNewTabURL() {
     this._overridden = false;
     this._newTabURL = ABOUT_URL;
     this.toggleActivityStream(undefined, true);
     Services.obs.notifyObservers(null, "newtab-url-changed", this._newTabURL);
   }
 };
 
--- a/browser/components/newtab/nsIAboutNewTabService.idl
+++ b/browser/components/newtab/nsIAboutNewTabService.idl
@@ -30,18 +30,28 @@ interface nsIAboutNewTabService : nsISup
 
   /**
    * Returns true if the default resource is activity stream and isn't
    * overridden
    */
   readonly attribute bool activityStreamEnabled;
 
   /**
+   * Returns true if the the prerendering pref for activity stream is true
+   */
+  readonly attribute bool activityStreamPrerender;
+
+  /**
    * Returns the activity stream resource URL for the newtab page
    */
   readonly attribute ACString activityStreamURL;
 
   /**
+   * Returns the prerendered activity stream resource URL for the newtab page
+   */
+  readonly attribute ACString activityStreamPrerenderURL;
+
+  /**
    * Resets to the default resource and also resets the
    * overridden attribute to false.
    */
   void resetNewTabURL();
 };
--- a/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
+++ b/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
@@ -3,38 +3,41 @@
  */
 
 "use strict";
 
 const {utils: Cu} = Components;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Preferences.jsm");
-
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
-const DEFAULT_HREF = aboutNewTabService.activityStreamURL;
+const ACTIVITY_STREAM_PRERENDER_URL = aboutNewTabService.activityStreamPrerenderURL;
+
 const DEFAULT_CHROME_URL = "chrome://browser/content/newtab/newTab.xhtml";
 const DOWNLOADS_URL = "chrome://browser/content/downloads/contentAreaDownloadsView.xul";
+const ACTIVITY_STREAM_PREF = "browser.newtabpage.activity-stream.enabled";
+const ACTIVITY_STREAM_PRERENDER_PREF = "browser.newtabpage.activity-stream.prerender";
 
 function cleanup() {
-  Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", false);
+  Services.prefs.clearUserPref(ACTIVITY_STREAM_PREF);
+  Services.prefs.clearUserPref(ACTIVITY_STREAM_PRERENDER_PREF);
   aboutNewTabService.resetNewTabURL();
 }
 
 do_register_cleanup(cleanup);
 
 /**
  * Test the overriding of the default URL
  */
 add_task(async function test_override_activity_stream_disabled() {
   let notificationPromise;
-  Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", false);
+  Services.prefs.setBoolPref(ACTIVITY_STREAM_PREF, false);
 
   // tests default is the local newtab resource
   Assert.equal(aboutNewTabService.defaultURL, DEFAULT_CHROME_URL,
                `Default newtab URL should be ${DEFAULT_CHROME_URL}`);
 
   // override with some remote URL
   let url = "http://example.com/";
   notificationPromise = nextChangeNotificationPromise(url);
@@ -57,65 +60,81 @@ add_task(async function test_override_ac
   await notificationPromise;
   Assert.ok(aboutNewTabService.overridden, "Newtab URL should be overridden");
   Assert.equal(aboutNewTabService.newTabURL, DOWNLOADS_URL, "Newtab URL should be the custom URL");
 
   cleanup();
 });
 
 add_task(async function test_override_activity_stream_enabled() {
-  let notificationPromise;
-  // change newtab page to activity stream
-  notificationPromise = nextChangeNotificationPromise("about:newtab");
-  Services.prefs.setBoolPref("browser.newtabpage.activity-stream.enabled", true);
-  await notificationPromise;
-  let activityStreamURL = aboutNewTabService.activityStreamURL;
-  Assert.equal(aboutNewTabService.defaultURL, activityStreamURL, "Newtab URL should be the default activity stream URL");
+  let notificationPromise = await setupASPrerendered();
+
+  Assert.equal(aboutNewTabService.defaultURL, ACTIVITY_STREAM_PRERENDER_URL, "Newtab URL should be the default activity stream prerendered URL");
   Assert.ok(!aboutNewTabService.overridden, "Newtab URL should not be overridden");
   Assert.ok(aboutNewTabService.activityStreamEnabled, "Activity Stream should be enabled");
+  Assert.ok(aboutNewTabService.activityStreamPrerender, "Activity Stream should be prerendered");
 
   // change to local newtab page while activity stream is enabled
   notificationPromise = nextChangeNotificationPromise(DEFAULT_CHROME_URL);
   aboutNewTabService.newTabURL = DEFAULT_CHROME_URL;
   await notificationPromise;
   Assert.equal(aboutNewTabService.newTabURL, DEFAULT_CHROME_URL,
                "Newtab URL set to chrome url");
   Assert.equal(aboutNewTabService.defaultURL, DEFAULT_CHROME_URL,
                "Newtab URL defaultURL set to the default chrome URL");
   Assert.ok(aboutNewTabService.overridden, "Newtab URL should be overridden");
   Assert.ok(!aboutNewTabService.activityStreamEnabled, "Activity Stream should not be enabled");
 
   cleanup();
 });
 
+add_task(async function test_default_url() {
+  await setupASPrerendered();
+  Assert.equal(aboutNewTabService.defaultURL, ACTIVITY_STREAM_PRERENDER_URL,
+               "Newtab defaultURL initially set to prerendered AS url");
+
+  // Change activity-stream.prerendered to false and wait for the required event to fire
+  const notificationPromise = nextChangeNotificationPromise(
+    "about:newtab", "a notification occurs after changing prerender pref");
+  Services.prefs.setBoolPref(ACTIVITY_STREAM_PRERENDER_PREF, false);
+
+  await notificationPromise;
+
+  Assert.equal(aboutNewTabService.defaultURL, aboutNewTabService.activityStreamURL,
+               "Newtab defaultURL set to un-prerendered AS url after the pref has been changed");
+
+  cleanup();
+});
+
 /**
  * Tests reponse to updates to prefs
  */
 add_task(async function test_updates() {
   /*
    * Simulates a "cold-boot" situation, with some pref already set before testing a series
    * of changes.
    */
-  Preferences.set("browser.newtabpage.activity-stream.enabled", true);
+  await setupASPrerendered();
+
   aboutNewTabService.resetNewTabURL(); // need to set manually because pref notifs are off
   let notificationPromise;
 
   // test update fires on override and reset
   let testURL = "https://example.com/";
   notificationPromise = nextChangeNotificationPromise(
     testURL, "a notification occurs on override");
   aboutNewTabService.newTabURL = testURL;
   await notificationPromise;
 
   // from overridden to default
   notificationPromise = nextChangeNotificationPromise(
     "about:newtab", "a notification occurs on reset");
   aboutNewTabService.resetNewTabURL();
   Assert.ok(aboutNewTabService.activityStreamEnabled, "Activity Stream should be enabled");
-  Assert.equal(aboutNewTabService.defaultURL, DEFAULT_HREF, "Default URL should be the activity stream page");
+  Assert.equal(aboutNewTabService.defaultURL, ACTIVITY_STREAM_PRERENDER_URL, "Default URL should be the activity stream page");
   await notificationPromise;
 
   // reset twice, only one notification for default URL
   notificationPromise = nextChangeNotificationPromise(
     "about:newtab", "reset occurs");
   aboutNewTabService.resetNewTabURL();
   await notificationPromise;
 
@@ -126,8 +145,22 @@ function nextChangeNotificationPromise(a
   return new Promise(resolve => {
     Services.obs.addObserver(function observer(aSubject, aTopic, aData) {  // jshint unused:false
       Services.obs.removeObserver(observer, aTopic);
       Assert.equal(aData, aNewURL, testMessage);
       resolve();
     }, "newtab-url-changed");
   });
 }
+
+function setupASPrerendered() {
+  if (Services.prefs.getBoolPref(ACTIVITY_STREAM_PREF) &&
+    Services.prefs.getBoolPref(ACTIVITY_STREAM_PRERENDER_PREF)) {
+    return Promise.resolve();
+  }
+
+  let notificationPromise;
+  // change newtab page to activity stream
+  notificationPromise = nextChangeNotificationPromise("about:newtab");
+  Services.prefs.setBoolPref(ACTIVITY_STREAM_PREF, true);
+  Services.prefs.setBoolPref(ACTIVITY_STREAM_PRERENDER_PREF, true);
+  return notificationPromise;
+}