Bug 912763 - Disable background thumbnails on Beta. r=markh
authorDrew Willcoxon <adw@mozilla.com>
Mon, 09 Sep 2013 19:58:57 -0700
changeset 159235 67329f8dfe7a138a20dda21c931cb3d6fcd95ec2
parent 159234 87f7da1e96632d6099c127bf5859417dd6a59865
child 159236 a66653f84ac7de34db4f94c72b5db93a11517c30
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmarkh
bugs912763
milestone26.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 912763 - Disable background thumbnails on Beta. r=markh
browser/base/content/newtab/newTab.js
browser/base/content/newtab/sites.js
toolkit/components/thumbnails/BackgroundPageThumbs.jsm
toolkit/components/thumbnails/PageThumbs.jsm
toolkit/components/thumbnails/jar.mn
toolkit/components/thumbnails/moz.build
toolkit/components/thumbnails/test/Makefile.in
toolkit/components/thumbnails/test/browser_thumbnails_update.js
--- a/browser/base/content/newtab/newTab.js
+++ b/browser/base/content/newtab/newTab.js
@@ -5,16 +5,19 @@
 "use strict";
 
 let Cu = Components.utils;
 let Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PageThumbs.jsm");
+#ifndef RELEASE_BUILD
+Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm");
+#endif
 Cu.import("resource://gre/modules/NewTabUtils.jsm");
 Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Rect",
   "resource://gre/modules/Geometry.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
--- a/browser/base/content/newtab/sites.js
+++ b/browser/base/content/newtab/sites.js
@@ -126,20 +126,22 @@ Site.prototype = {
 
     let link = this._querySelector(".newtab-link");
     link.setAttribute("title", tooltip);
     link.setAttribute("href", url);
     this._querySelector(".newtab-title").textContent = title;
 
     if (this.isPinned())
       this._updateAttributes(true);
+#ifndef RELEASE_BUILD
     // request a staleness check for the thumbnail, which will cause page.js
     // to be notified and call our refreshThumbnail() method.
-    PageThumbs.captureIfStale(this.url);
+    BackgroundPageThumbs.captureIfStale(this.url);
     // but still display whatever thumbnail might be available now.
+#endif
     this.refreshThumbnail();
   },
 
   /**
    * Refreshes the thumbnail for the site.
    */
   refreshThumbnail: function Site_refreshThumbnail() {
     let thumbnailURL = PageThumbs.getThumbnailURL(this.url);
--- a/toolkit/components/thumbnails/BackgroundPageThumbs.jsm
+++ b/toolkit/components/thumbnails/BackgroundPageThumbs.jsm
@@ -1,20 +1,32 @@
 /* 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/. */
 
+/**
+ * WARNING: BackgroundPageThumbs.jsm is currently excluded from release builds.
+ * If you use it, you must also exclude your caller when RELEASE_BUILD is
+ * defined, as described here:
+ * https://wiki.mozilla.org/Platform/Channel-specific_build_defines
+ */
+
 const EXPORTED_SYMBOLS = [
   "BackgroundPageThumbs",
 ];
 
 const DEFAULT_CAPTURE_TIMEOUT = 30000; // ms
 const DESTROY_BROWSER_TIMEOUT = 60000; // ms
 const FRAME_SCRIPT_URL = "chrome://global/content/backgroundPageThumbsContent.js";
 
+// If a request for a thumbnail comes in and we find one that is "stale"
+// (or don't find one at all) we automatically queue a request to generate a
+// new one.
+const MAX_THUMBNAIL_AGE_SECS = 172800; // 2 days == 60*60*24*2 == 172800 secs.
+
 const TELEMETRY_HISTOGRAM_ID_PREFIX = "FX_THUMBNAILS_BG_";
 
 // possible FX_THUMBNAILS_BG_CAPTURE_DONE_REASON telemetry values
 const TEL_CAPTURE_DONE_OK = 0;
 const TEL_CAPTURE_DONE_TIMEOUT = 1;
 // 2 and 3 were used when we had special handling for private-browsing.
 
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@@ -27,16 +39,21 @@ Cu.import("resource://gre/modules/Servic
 
 const BackgroundPageThumbs = {
 
   /**
    * Asynchronously captures a thumbnail of the given URL.
    *
    * The page is loaded anonymously, and plug-ins are disabled.
    *
+   * WARNING: BackgroundPageThumbs.jsm is currently excluded from release
+   * builds.  If you use it, you must also exclude your caller when
+   * RELEASE_BUILD is defined, as described here:
+   * https://wiki.mozilla.org/Platform/Channel-specific_build_defines
+   *
    * @param url      The URL to capture.
    * @param options  An optional object that configures the capture.  Its
    *                 properties are the following, and all are optional:
    * @opt onDone     A function that will be asynchronously called when the
    *                 capture is complete or times out.  It's called as
    *                   onDone(url),
    *                 where `url` is the captured URL.
    * @opt timeout    The capture will time out after this many milliseconds have
@@ -89,16 +106,47 @@ const BackgroundPageThumbs = {
         // else: we must have been idle and not currently doing a capture (eg,
         // maybe a GC or similar crashed) - so there's no need to attempt a
         // queue restart - the next capture request will set everything up.
       }
     }
   },
 
   /**
+   * Checks if an existing thumbnail for the specified URL is either missing
+   * or stale, and if so, queues a background request to capture it.  That
+   * capture process will send a notification via the observer service on
+   * capture, so consumers should watch for such observations if they want to
+   * be notified of an updated thumbnail.
+   *
+   * WARNING: BackgroundPageThumbs.jsm is currently excluded from release
+   * builds.  If you use it, you must also exclude your caller when
+   * RELEASE_BUILD is defined, as described here:
+   * https://wiki.mozilla.org/Platform/Channel-specific_build_defines
+   *
+   * @param url      The URL to capture.
+   * @param options  An optional object that configures the capture.  See
+   *                 capture() for description.
+   */
+  captureIfStale: function PageThumbs_captureIfStale(url, options={}) {
+    PageThumbsStorage.isFileRecentForURL(url, MAX_THUMBNAIL_AGE_SECS).then(
+      result => {
+        if (result.ok) {
+          if (options.onDone)
+            options.onDone(url);
+          return;
+        }
+        this.capture(url, options);
+      }, err => {
+        if (options.onDone)
+          options.onDone(url);
+      });
+  },
+
+  /**
    * Ensures that initialization of the thumbnail browser's parent window has
    * begun.
    *
    * @return  True if the parent window is completely initialized and can be
    *          used, and false if initialization has started but not completed.
    */
   _ensureParentWindowReady: function () {
     if (this._parentWin)
--- a/toolkit/components/thumbnails/PageThumbs.jsm
+++ b/toolkit/components/thumbnails/PageThumbs.jsm
@@ -12,21 +12,16 @@ const Ci = Components.interfaces;
 
 const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
 const PREF_STORAGE_VERSION = "browser.pagethumbnails.storage_version";
 const LATEST_STORAGE_VERSION = 3;
 
 const EXPIRATION_MIN_CHUNK_SIZE = 50;
 const EXPIRATION_INTERVAL_SECS = 3600;
 
-// If a request for a thumbnail comes in and we find one that is "stale"
-// (or don't find one at all) we automatically queue a request to generate a
-// new one.
-const MAX_THUMBNAIL_AGE_SECS = 172800; // 2 days == 60*60*24*2 == 172800 secs.
-
 /**
  * Name of the directory in the profile that contains the thumbnails.
  */
 const THUMBNAIL_DIRECTORY = "thumbnails";
 
 /**
  * The default background color for page thumbnails.
  */
@@ -193,42 +188,16 @@ this.PageThumbs = {
     * @param aUrl The web page's url.
     * @return The path of the thumbnail file.
     */
    getThumbnailPath: function PageThumbs_getThumbnailPath(aUrl) {
      return PageThumbsStorage.getFilePathForURL(aUrl);
    },
 
   /**
-   * Checks if an existing thumbnail for the specified URL is either missing
-   * or stale, and if so, queues a background request to capture it.  That
-   * capture process will send a notification via the observer service on
-   * capture, so consumers should watch for such observations if they want to
-   * be notified of an updated thumbnail.
-   *
-   * @return {Promise} that's resolved on completion.
-   */
-  captureIfStale: function PageThumbs_captureIfStale(aUrl) {
-    let deferredResult = Promise.defer();
-    let filePath = PageThumbsStorage.getFilePathForURL(aUrl);
-    PageThumbsWorker.post(
-      "isFileRecent",
-      [filePath, MAX_THUMBNAIL_AGE_SECS]
-    ).then(result => {
-      if (!result.ok) {
-        // Sadly there is currently a circular dependency between this module
-        // and BackgroundPageThumbs, so do the import locally.
-        let BPT = Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm", {}).BackgroundPageThumbs;
-        BPT.capture(aUrl, {onDone: deferredResult.resolve});
-      }
-    });
-    return deferredResult.promise;
-  },
-
-  /**
    * Captures a thumbnail for the given window.
    * @param aWindow The DOM window to capture a thumbnail from.
    * @param aCallback The function to be called when the thumbnail has been
    *                  captured. The first argument will be the data stream
    *                  containing the image data.
    */
   capture: function PageThumbs_capture(aWindow, aCallback) {
     if (!this._prefEnabled()) {
@@ -621,16 +590,21 @@ this.PageThumbsStorage = {
    * false.
    *
    * @return {Promise}
    */
   touchIfExists: function Storage_touchIfExists(aURL) {
     return PageThumbsWorker.post("touchIfExists", [this.getFilePathForURL(aURL)]);
   },
 
+  isFileRecentForURL: function Storage_isFileRecentForURL(aURL, aMaxSecs) {
+    return PageThumbsWorker.post("isFileRecent",
+                                 [this.getFilePathForURL(aURL), aMaxSecs]);
+  },
+
   _calculateMD5Hash: function Storage_calculateMD5Hash(aValue) {
     let hash = gCryptoHash;
     let value = gUnicodeConverter.convertToByteArray(aValue);
 
     hash.init(hash.MD5);
     hash.update(value, value.length);
     return this._convertToHexString(hash.finish(false));
   },
--- a/toolkit/components/thumbnails/jar.mn
+++ b/toolkit/components/thumbnails/jar.mn
@@ -1,6 +1,8 @@
 # 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/.
 
 toolkit.jar:
+#ifndef RELEASE_BUILD
 + content/global/backgroundPageThumbsContent.js (content/backgroundPageThumbsContent.js)
+#endif
--- a/toolkit/components/thumbnails/moz.build
+++ b/toolkit/components/thumbnails/moz.build
@@ -7,13 +7,14 @@
 TEST_DIRS += ['test']
 
 EXTRA_COMPONENTS += [
     'BrowserPageThumbs.manifest',
     'PageThumbsProtocol.js',
 ]
 
 EXTRA_JS_MODULES += [
-    'BackgroundPageThumbs.jsm',
     'PageThumbs.jsm',
     'PageThumbsWorker.js',
 ]
 
+if not CONFIG['RELEASE_BUILD']:
+    EXTRA_JS_MODULES += ['BackgroundPageThumbs.jsm']
--- a/toolkit/components/thumbnails/test/Makefile.in
+++ b/toolkit/components/thumbnails/test/Makefile.in
@@ -1,26 +1,31 @@
 # 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/.
 
 MOCHITEST_BROWSER_FILES := \
-	browser_thumbnails_background.js \
-	browser_thumbnails_background_crash.js \
 	browser_thumbnails_capture.js \
 	browser_thumbnails_expiration.js \
 	browser_thumbnails_privacy.js \
 	browser_thumbnails_redirect.js \
 	browser_thumbnails_storage.js \
 	browser_thumbnails_storage_migrate3.js \
 	browser_thumbnails_bug726727.js \
 	browser_thumbnails_bug727765.js \
 	browser_thumbnails_bug818225.js \
-	browser_thumbnails_update.js \
 	head.js \
 	background_red.html \
 	background_red_scroll.html \
 	background_red_redirect.sjs \
 	privacy_cache_control.sjs \
+	$(NULL)
+
+ifndef RELEASE_BUILD
+MOCHITEST_BROWSER_FILES += \
+	browser_thumbnails_background.js \
+	browser_thumbnails_background_crash.js \
+	browser_thumbnails_update.js \
 	thumbnails_background.sjs \
 	thumbnails_crash_content_helper.js \
 	thumbnails_update.sjs \
 	$(NULL)
+endif
--- a/toolkit/components/thumbnails/test/browser_thumbnails_update.js
+++ b/toolkit/components/thumbnails/test/browser_thumbnails_update.js
@@ -1,15 +1,22 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
- * These tests check the auto-update facility of the thumbnail service.
+ * These tests check the auto-update facility of the background thumbnail
+ * service.
  */
 
+const imports = {};
+Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm", imports);
+registerCleanupFunction(function () {
+  imports.BackgroundPageThumbs._destroy();
+});
+
 function runTests() {
   // A "trampoline" - a generator that iterates over sub-iterators
   let tests = [
     simpleCaptureTest,
     errorResponseUpdateTest,
     goodResponseUpdateTest,
     foregroundErrorResponseUpdateTest,
     foregroundGoodResponseUpdateTest
@@ -63,22 +70,22 @@ function simpleCaptureTest() {
   // Capture the screenshot.
   PageThumbs.captureAndStore(browser, function () {
     // done with the tab.
     gBrowser.removeTab(gBrowser.selectedTab);
     // We've got a capture so should have seen the observer.
     is(numNotifications, 1, "got notification of item being created.");
     // The capture is now "fresh" - so requesting the URL should not cause
     // a new capture.
-    PageThumbs.captureIfStale(URL);
+    imports.BackgroundPageThumbs.captureIfStale(URL);
     is(numNotifications, 1, "still only 1 notification of item being created.");
 
     ensureThumbnailStale(URL);
     // Ask for it to be updated.
-    PageThumbs.captureIfStale(URL);
+    imports.BackgroundPageThumbs.captureIfStale(URL);
     // But it's async, so wait - our observer above will call next() when
     // the notification comes.
   });
   yield undefined // wait for callbacks to call 'next'...
 }
 
 /* Check functionality of a background capture when there is an error response
    from the server.
@@ -94,23 +101,23 @@ function errorResponseUpdateTest() {
   // The b/g service should (a) not save the thumbnail and (b) update the file
   // to have an mtime of "now" - so we (a) check the thumbnail remains green
   // and (b) check the mtime of the file is >= now.
   ensureThumbnailStale(URL);
   // now() returns a higher-precision value than the modified time of a file.
   // As we set the thumbnail very stale, allowing 1 second of "slop" here
   // works around this while still keeping the test valid.
   let now = Date.now() - 1000 ;
-  PageThumbs.captureIfStale(URL).then(() => {
+  imports.BackgroundPageThumbs.captureIfStale(URL, { onDone: () => {
     ok(getThumbnailModifiedTime(URL) >= now, "modified time should be >= now");
     retrieveImageDataForURL(URL, function ([r, g, b]) {
       is("" + [r,g,b], "" + [0, 255, 0], "thumbnail is still green");
       next();
     });
-  }).then(null, err => {ok(false, "Error in captureIfStale: " + err)});
+  }});
   yield undefined; // wait for callback to call 'next'...
 }
 
 /* Check functionality of a background capture when there is a non-error
    response from the server.  This test is somewhat redundant - although it is
    using a http:// URL instead of a data: url like most others.
  */
 function goodResponseUpdateTest() {
@@ -122,25 +129,25 @@ function goodResponseUpdateTest() {
   // update the thumbnail to be stale, then re-request it.  The server will
   // return a 200 response and a red thumbnail - so that new thumbnail should
   // end up captured.
   ensureThumbnailStale(URL);
   // now() returns a higher-precision value than the modified time of a file.
   // As we set the thumbnail very stale, allowing 1 second of "slop" here
   // works around this while still keeping the test valid.
   let now = Date.now() - 1000 ;
-  PageThumbs.captureIfStale(URL).then(() => {
+  imports.BackgroundPageThumbs.captureIfStale(URL, { onDone: () => {
     ok(getThumbnailModifiedTime(URL) >= now, "modified time should be >= now");
     // the captureIfStale request saw a 200 response with the red body, so we
     // expect to see the red version here.
     retrieveImageDataForURL(URL, function ([r, g, b]) {
       is("" + [r,g,b], "" + [255, 0, 0], "thumbnail is now red");
       next();
     });
-  }).then(null, err => {ok(false, "Error in captureIfStale: " + err)});
+  }});
   yield undefined; // wait for callback to call 'next'...
 }
 
 /* Check functionality of a foreground capture when there is an error response
    from the server.
  */
 function foregroundErrorResponseUpdateTest() {
   const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?fail";