Merge fx-team to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 14 Apr 2015 16:22:54 -0400
changeset 239097 de27ac2ab94ff46ee5ef7c7bf708bde742086944
parent 239084 c3e4ff7d62c61ca3c454c9acfbdb1a6c67be0abf (current diff)
parent 239096 349ec1e6b2471ad1905b68c18b19a760cf7b21f2 (diff)
child 239106 06016c1dc314c33b1e0b91bbb35a274e1b7bb282
child 239133 bba36d7d59d20db5fac10bf0fa1d049fbdd9486f
child 239170 4b214b4a0d3878a3470769b922ce77c41940ca19
push id28581
push userryanvm@gmail.com
push dateTue, 14 Apr 2015 20:22:58 +0000
treeherdermozilla-central@de27ac2ab94f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone40.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
Merge fx-team to m-c. a=merge
toolkit/components/telemetry/tests/unit/head.js
toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
toolkit/components/telemetry/tests/unit/test_TelemetryPingBuildID.js
toolkit/components/telemetry/tests/unit/test_TelemetrySendOldPings.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1698,19 +1698,19 @@ pref("loop.ping.timeout", 10000);
 pref("loop.feedback.baseUrl", "https://input.mozilla.org/api/v1/feedback");
 pref("loop.feedback.product", "Loop");
 pref("loop.debug.loglevel", "Error");
 pref("loop.debug.dispatcher", false);
 pref("loop.debug.websocket", false);
 pref("loop.debug.sdk", false);
 pref("loop.debug.twoWayMediaTelemetry", false);
 #ifdef DEBUG
-pref("loop.CSP", "default-src 'self' about: file: chrome: http://localhost:*; img-src *; font-src 'none'; connect-src wss://*.tokbox.com https://*.opentok.com https://*.tokbox.com wss://*.mozilla.com https://*.mozilla.org wss://*.mozaws.net http://localhost:* ws://localhost:*; media-src blob:");
+pref("loop.CSP", "default-src 'self' about: file: chrome: http://localhost:*; img-src * data:; font-src 'none'; connect-src wss://*.tokbox.com https://*.opentok.com https://*.tokbox.com wss://*.mozilla.com https://*.mozilla.org wss://*.mozaws.net http://localhost:* ws://localhost:*; media-src blob:");
 #else
-pref("loop.CSP", "default-src 'self' about: file: chrome:; img-src *; font-src 'none'; connect-src wss://*.tokbox.com https://*.opentok.com https://*.tokbox.com wss://*.mozilla.com https://*.mozilla.org wss://*.mozaws.net; media-src blob:");
+pref("loop.CSP", "default-src 'self' about: file: chrome:; img-src * data:; font-src 'none'; connect-src wss://*.tokbox.com https://*.opentok.com https://*.tokbox.com wss://*.mozilla.com https://*.mozilla.org wss://*.mozaws.net; media-src blob:");
 #endif
 pref("loop.oauth.google.redirect_uri", "urn:ietf:wg:oauth:2.0:oob:auto");
 pref("loop.oauth.google.scope", "https://www.google.com/m8/feeds");
 pref("loop.fxa_oauth.tokendata", "");
 pref("loop.fxa_oauth.profile", "");
 pref("loop.support_url", "https://support.mozilla.org/kb/group-conversations-firefox-hello-webrtc");
 pref("loop.contacts.gravatars.show", false);
 pref("loop.contacts.gravatars.promo", true);
--- a/browser/components/loop/content/shared/css/conversation.css
+++ b/browser/components/loop/content/shared/css/conversation.css
@@ -714,21 +714,24 @@ html, .fx-embedded, #main,
   }
 
   /* Nested video elements */
   .conversation .media.nested {
     position: relative;
     height: 100%;
   }
 
+  .standalone .media.nested {
+    margin-left: 10px;
+  }
+
   .standalone .remote_wrapper {
     position: relative;
-    width: calc(100% - 10px);
+    width: 100%;
     height: 100%;
-    margin-left: 10px;
   }
 
   .standalone {
     margin: 0 auto;
   }
 }
 
 @media screen and (max-width:640px) {
@@ -971,17 +974,17 @@ body[dir=rtl] .share-service-dropdown .s
   height: calc(100% - 50px - 60px);
 }
 
 .standalone .room-conversation-wrapper .room-inner-info-area {
   position: absolute;
   /* `top` is chosen to vertically position the area near the center
      of the media element. */
   top: calc(50% - 140px);
-  left: calc(25% + 62.5px + 10px);
+  left: 25%;
   z-index: 1000;
   /* `width` here is specified by the design spec. */
   width: 250px;
   color: #fff;
   box-sizing: content-box;
 }
 
 .standalone .prompt-media-message {
@@ -1044,17 +1047,17 @@ body[dir=rtl] .share-service-dropdown .s
 }
 
 .standalone .room-conversation .media {
   background: #000;
 }
 
 .standalone .room-conversation .video_wrapper.remote_wrapper {
   background-color: #4e4e4e;
-  width: calc(75% - 10px); /* Take the left margin into account. */
+  width: 75%;
 }
 
 .standalone .room-conversation .conversation-toolbar {
   background: #000;
   border: none;
 }
 
 .standalone .room-conversation .conversation-toolbar .btn-hangup-entry {
@@ -1074,16 +1077,17 @@ body[dir=rtl] .share-service-dropdown .s
   }
   .room-conversation-wrapper header {
     width: 100%;
   }
   .standalone .room-conversation-wrapper .room-inner-info-area {
     right: 0;
     margin: auto;
     width: 100%;
+    left: 0;
   }
   .standalone .room-conversation-wrapper .video-layout-wrapper {
     /* 50px: header's height; 25px: footer's height */
     height: calc(100% - 50px - 25px);
   }
   .standalone .room-conversation .video_wrapper.remote_wrapper {
     width: 100%;
   }
--- a/browser/components/migration/IEProfileMigrator.js
+++ b/browser/components/migration/IEProfileMigrator.js
@@ -18,16 +18,18 @@ Cu.import("resource:///modules/Migration
 
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ctypes",
                                   "resource://gre/modules/ctypes.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "WindowsRegistry",
                                   "resource://gre/modules/WindowsRegistry.jsm");
 
+Cu.importGlobalProperties(["File"]);
+
 ////////////////////////////////////////////////////////////////////////////////
 //// Helpers.
 
 let CtypesHelpers = {
   _structs: {},
   _functions: {},
   _libs: {},
 
@@ -405,17 +407,17 @@ Cookies.prototype = {
         this._parseCookieBuffer(fileReader.result);
       } catch (ex) {
         Components.utils.reportError("Unable to migrate cookie: " + ex);
         success = false;
       } finally {
         aCallback(success);
       }
     }).bind(this), false);
-    fileReader.readAsText(File(aFile));
+    fileReader.readAsText(new File(aFile));
   },
 
   /**
    * Parses a cookie file buffer and returns an array of the contained cookies.
    *
    * The cookie file format is a newline-separated-values with a "*" used as
    * delimeter between multiple records.
    * Each cookie has the following fields:
@@ -439,28 +441,28 @@ Cookies.prototype = {
            expireTimeLo, expireTimeHi] = record.split("\n");
 
       // IE stores deleted cookies with a zero-length value, skip them.
       if (value.length == 0)
         continue;
 
       let hostLen = hostpath.indexOf("/");
       let host = hostpath.substr(0, hostLen);
+      let path = hostpath.substr(hostLen);
 
       // For a non-null domain, assume it's what Mozilla considers
       // a domain cookie.  See bug 222343.
       if (host.length > 0) {
         // Fist delete any possible extant matching host cookie.
         Services.cookies.remove(host, name, path, false);
         // Now make it a domain cookie.
         if (host[0] != "." && !hostIsIPAddress(host))
           host = "." + host;
       }
 
-      let path = hostpath.substr(hostLen);
       let expireTime = CtypesHelpers.fileTimeToDate(Number(expireTimeHi),
                                                     Number(expireTimeLo));
       Services.cookies.add(host,
                            path,
                            name,
                            value,
                            Number(flags) & 0x1, // secure
                            false, // httpOnly
--- a/browser/themes/windows/browser-aero.css
+++ b/browser/themes/windows/browser-aero.css
@@ -341,47 +341,8 @@
   -moz-image-region: rect(32px, 49px, 48px, 32px);
 }
 
 #minimize-button:-moz-locale-dir(rtl),
 #restore-button:-moz-locale-dir(rtl),
 #close-button:-moz-locale-dir(rtl) {
   transform: scaleX(-1);
 }
-
-/* ::::: private browsing indicator ::::: */
-
-@media (-moz-os-version: windows-vista),
-       (-moz-os-version: windows-win7) {
-  #TabsToolbar > .private-browsing-indicator {
-    background-image: url("chrome://browser/skin/privatebrowsing-mask-tabstrip-XPVista7.png");
-  }
-
-  /* We're intentionally using the titlebar asset here for fullscreen mode.
-   * See bug 1008183.
-   */
-  #private-browsing-indicator-titlebar > .private-browsing-indicator,
-  #main-window[inFullscreen] #TabsToolbar > .private-browsing-indicator {
-    background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7.png");
-  }
-}
-
-@media (-moz-windows-glass) {
-  #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
-    top: 1px;
-  }
-  #main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
-    top: -1px;
-  }
-}
-
-/**
- * This next block targets Aero Basic, which has different positioning for the
- * window caption buttons, and therefore needs to be special-cased.
- */
-@media (-moz-windows-default-theme) {
-  @media not all and (-moz-windows-compositor) {
-    #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
-      background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7-tall.png");
-      height: 28px;
-    }
-  }
-}
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2658,61 +2658,84 @@ chatbox {
 #main-window[inFullscreen] #TabsToolbar > .private-browsing-indicator {
   background: url("chrome://browser/skin/privatebrowsing-mask-titlebar.png") no-repeat center 0px;
   -moz-margin-end: 4px;
   width: 40px;
   height: 20px;
   position: relative;
 }
 
-@media (-moz-os-version: windows-xp) {
+@media (-moz-os-version: windows-xp),
+       (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
   #TabsToolbar > .private-browsing-indicator {
     background-image: url("chrome://browser/skin/privatebrowsing-mask-tabstrip-XPVista7.png");
   }
 
+  /* We're intentionally using the titlebar asset here for fullscreen mode.
+   * See bug 1008183.
+   */
+  #private-browsing-indicator-titlebar > .private-browsing-indicator,
+  #main-window[inFullscreen] #TabsToolbar > .private-browsing-indicator {
+    background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7.png");
+  }
+}
+
+@media (-moz-os-version: windows-xp) {
   @media not all and (-moz-windows-classic) {
     #private-browsing-indicator-titlebar > .private-browsing-indicator {
       background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7-tall.png");
       height: 28px;
     }
 
-    /* We're intentionally using the titlebar asset here for fullscreen mode.
-     * See bug 1008183.
-     */
-    #main-window[inFullscreen] #TabsToolbar > .private-browsing-indicator {
-      background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7.png");
-    }
-
     #main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
       top: -5px;
     }
     #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
       top: -1px;
     }
   }
 }
 
 @media (-moz-windows-classic) {
-  /* We're intentionally using the titlebar asset here for fullscreen mode.
-   * See bug 1008183.
-   */
-  #private-browsing-indicator-titlebar > .private-browsing-indicator,
-  #main-window[inFullscreen] #TabsToolbar > .private-browsing-indicator {
-    background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7.png");
-  }
   /**
    * We have to use top instead of background-position in this case, otherwise
    * the bottom of the indicator would get cut off by the bounds of the
    * private-browsing-indicator element.
    */
   #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
     top: 4px;
   }
 }
 
+@media (-moz-os-version: windows-vista),
+       (-moz-os-version: windows-win7) {
+  @media (-moz-windows-glass) {
+    #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
+      top: 1px;
+    }
+    #main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
+      top: -1px;
+    }
+  }
+
+  /**
+   * This next block targets Aero Basic, which has different positioning for the
+   * window caption buttons, and therefore needs to be special-cased.
+   */
+  @media (-moz-windows-default-theme) {
+    @media not all and (-moz-windows-compositor) {
+      #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox-container > #private-browsing-indicator-titlebar > .private-browsing-indicator {
+        background-image: url("chrome://browser/skin/privatebrowsing-mask-titlebar-XPVista7-tall.png");
+        height: 28px;
+      }
+    }
+  }
+}
+
 /* End private browsing indicators */
 
 %include ../shared/UITour.inc.css
 
 #UITourTooltipButtons {
   margin: 24px -4px -4px;
 }
 
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -3389,23 +3389,33 @@ public class BrowserApp extends GeckoApp
 
         // Only solicit feedback when the app has been launched from the icon shortcut.
         if (GuestSession.NOTIFICATION_INTENT.equals(action)) {
             GuestSession.handleIntent(this, intent);
         }
 
         // If the user has clicked the tab queue notification then load the tabs.
         if(AppConstants.NIGHTLY_BUILD  && AppConstants.MOZ_ANDROID_TAB_QUEUE && mInitialized && isTabQueueAction) {
-            int queuedTabCount = TabQueueHelper.getTabQueueLength(this);
-            TabQueueHelper.openQueuedUrls(this, mProfile, TabQueueHelper.FILE_NAME, false);
-
-            // If there's more than one tab then also show the tabs panel.
-            if (queuedTabCount > 1) {
-                showNormalTabs();
-            }
+            ThreadUtils.postToBackgroundThread(new Runnable() {
+                @Override
+                public void run() {
+                    int queuedTabCount = TabQueueHelper.getTabQueueLength(BrowserApp.this);
+                    TabQueueHelper.openQueuedUrls(BrowserApp.this, mProfile, TabQueueHelper.FILE_NAME, false);
+
+                    // If there's more than one tab then also show the tabs panel.
+                    if (queuedTabCount > 1) {
+                        ThreadUtils.postToUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                showNormalTabs();
+                            }
+                        });
+                    }
+                }
+            });
         }
 
         if (!mInitialized || !Intent.ACTION_MAIN.equals(action)) {
             return;
         }
 
         // Check to see how many times the app has been launched.
         final String keyName = getPackageName() + ".feedback_launch_count";
--- a/storage/src/mozStorageConnection.cpp
+++ b/storage/src/mozStorageConnection.cpp
@@ -360,16 +360,20 @@ public:
   {
 #ifdef DEBUG
     // This code is executed on the background thread
     bool onAsyncThread = false;
     (void)mAsyncExecutionThread->IsOnCurrentThread(&onAsyncThread);
     MOZ_ASSERT(onAsyncThread);
 #endif // DEBUG
 
+    nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethodWithArg<nsCOMPtr<nsIThread>>
+      (mConnection, &Connection::shutdownAsyncThread, mAsyncExecutionThread);
+    (void)NS_DispatchToMainThread(event);
+
     // Internal close.
     (void)mConnection->internalClose(mNativeConnection);
 
     // Callback
     if (mCallbackEvent) {
       nsCOMPtr<nsIThread> thread;
       (void)NS_GetMainThread(getter_AddRefs(thread));
       (void)thread->Dispatch(mCallbackEvent, NS_DISPATCH_NORMAL);
@@ -481,32 +485,35 @@ private:
 Connection::Connection(Service *aService,
                        int aFlags,
                        bool aAsyncOnly)
 : sharedAsyncExecutionMutex("Connection::sharedAsyncExecutionMutex")
 , sharedDBMutex("Connection::sharedDBMutex")
 , threadOpenedOn(do_GetCurrentThread())
 , mDBConn(nullptr)
 , mAsyncExecutionThreadShuttingDown(false)
+, mAsyncExecutionThreadIsAlive(false)
 , mConnectionClosed(false)
 , mTransactionInProgress(false)
 , mProgressHandler(nullptr)
 , mFlags(aFlags)
 , mStorageService(aService)
 , mAsyncOnly(aAsyncOnly)
 {
   mStorageService->registerConnection(this);
 }
 
 Connection::~Connection()
 {
   (void)Close();
 
   MOZ_ASSERT(!mAsyncExecutionThread,
              "AsyncClose has not been invoked on this connection!");
+  MOZ_ASSERT(!mAsyncExecutionThreadIsAlive,
+             "The async execution thread should have been shutdown!");
 }
 
 NS_IMPL_ADDREF(Connection)
 
 NS_INTERFACE_MAP_BEGIN(Connection)
   NS_INTERFACE_MAP_ENTRY(mozIStorageAsyncConnection)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(mozIStorageConnection, !mAsyncOnly)
@@ -564,16 +571,17 @@ Connection::getAsyncExecutionTarget()
       NS_WARNING("Failed to create async thread.");
       return nullptr;
     }
     static nsThreadPoolNaming naming;
     naming.SetThreadPoolName(NS_LITERAL_CSTRING("mozStorage"),
                              mAsyncExecutionThread);
   }
 
+  mAsyncExecutionThreadIsAlive = true;
   return mAsyncExecutionThread;
 }
 
 nsresult
 Connection::initialize()
 {
   NS_ASSERTION (!mDBConn, "Initialize called on already opened database!");
   PROFILER_LABEL("mozStorageConnection", "initialize",
@@ -863,16 +871,27 @@ Connection::isClosing()
 
 bool
 Connection::isClosed()
 {
   MutexAutoLock lockedScope(sharedAsyncExecutionMutex);
   return mConnectionClosed;
 }
 
+void
+Connection::shutdownAsyncThread(nsIThread *aThread) {
+  MOZ_ASSERT(!mAsyncExecutionThread);
+  MOZ_ASSERT(mAsyncExecutionThreadIsAlive);
+  MOZ_ASSERT(mAsyncExecutionThreadShuttingDown);
+
+  DebugOnly<nsresult> rv = aThread->Shutdown();
+  MOZ_ASSERT(NS_SUCCEEDED(rv));
+  mAsyncExecutionThreadIsAlive = false;
+}
+
 nsresult
 Connection::internalClose(sqlite3 *aNativeConnection)
 {
   // Sanity checks to make sure we are in the proper state before calling this.
   // aNativeConnection can be null if OpenAsyncDatabase failed and is now just
   // cleaning up the async thread.
   MOZ_ASSERT(!isClosed());
 
--- a/storage/src/mozStorageConnection.h
+++ b/storage/src/mozStorageConnection.h
@@ -163,16 +163,21 @@ public:
   const nsCOMPtr<nsIThread> threadOpenedOn;
 
   /**
    * Closes the SQLite database, and warns about any non-finalized statements.
    */
   nsresult internalClose(sqlite3 *aDBConn);
 
   /**
+   * Shuts down the passed-in async thread.
+   */
+  void shutdownAsyncThread(nsIThread *aAsyncThread);
+
+  /**
    * Obtains the filename of the connection.  Useful for logging.
    */
   nsCString getFilename();
 
   /**
    * Creates an sqlite3 prepared statement object from an SQL string.
    *
    * @param aNativeConnection
@@ -302,16 +307,22 @@ private:
    * returns null.
    *
    * This variable should be accessed while holding the
    * sharedAsyncExecutionMutex.
    */
   bool mAsyncExecutionThreadShuttingDown;
 
   /**
+   * Tracks whether the async thread has been initialized and Shutdown() has
+   * not yet been invoked on it.
+   */
+  DebugOnly<bool> mAsyncExecutionThreadIsAlive;
+
+  /**
    * Set to true just prior to calling sqlite3_close on the
    * connection.
    *
    * This variable should be accessed while holding the
    * sharedAsyncExecutionMutex.
    */
   bool mConnectionClosed;
 
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -1421,16 +1421,17 @@ try {
 // We need to avoid hitting the network with certain components.
 try {
   if (runningInParent) {
     let prefs = Components.classes["@mozilla.org/preferences-service;1"]
       .getService(Components.interfaces.nsIPrefBranch);
 
     prefs.setCharPref("media.gmp-manager.url.override", "http://%(server)s/dummy-gmp-manager.xml");
     prefs.setCharPref("browser.selfsupport.url", "https://%(server)s/selfsupport-dummy/");
+    prefs.setCharPref("toolkit.telemetry.server", "https://%(server)s/telemetry-dummy");
   }
 } catch (e) { }
 
 // Make tests run consistently on DevEdition (which has a lightweight theme
 // selected by default).
 try {
   if (runningInParent) {
     let prefs = Components.classes["@mozilla.org/preferences-service;1"]
--- a/toolkit/components/telemetry/tests/unit/head.js
+++ b/toolkit/components/telemetry/tests/unit/head.js
@@ -1,24 +1,26 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Components.utils.import("resource://gre/modules/TelemetryPing.jsm", this);
-Components.utils.import("resource://gre/modules/Services.jsm", this);
+const { classes: Cc, utils: Cu, interfaces: Ci, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
+Cu.import("resource://gre/modules/Services.jsm", this);
 
-const gIsWindows = ("@mozilla.org/windows-registry-key;1" in Components.classes);
-const gIsMac = ("@mozilla.org/xpcom/mac-utils;1" in Components.classes);
-const gIsAndroid =  ("@mozilla.org/android/bridge;1" in Components.classes);
-const gIsGonk = ("@mozilla.org/cellbroadcast/gonkservice;1" in Components.classes);
+const gIsWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
+const gIsMac = ("@mozilla.org/xpcom/mac-utils;1" in Cc);
+const gIsAndroid =  ("@mozilla.org/android/bridge;1" in Cc);
+const gIsGonk = ("@mozilla.org/cellbroadcast/gonkservice;1" in Cc);
 
 const MILLISECONDS_PER_MINUTE = 60 * 1000;
 const MILLISECONDS_PER_HOUR = 60 * MILLISECONDS_PER_MINUTE;
 const MILLISECONDS_PER_DAY = 24 * MILLISECONDS_PER_HOUR;
 
-const HAS_DATAREPORTINGSERVICE = "@mozilla.org/datareporting/service;1" in Components.classes;
+const HAS_DATAREPORTINGSERVICE = "@mozilla.org/datareporting/service;1" in Cc;
 
 let gOldAppInfo = null;
 let gGlobalScope = this;
 
 /**
  * Decode the payload of an HTTP request into a ping.
  * @param {Object} request The data representing an HTTP request (nsIHttpRequest).
  * @return {Object} The decoded ping payload.
@@ -70,18 +72,17 @@ function loadAddonManager(id, name, vers
   startupManager();
 }
 
 function createAppInfo(id, name, version, platformVersion) {
   const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
   const XULAPPINFO_CID = Components.ID("{c763b610-9d49-455a-bbd2-ede71682a1ac}");
   let gAppInfo;
   if (!gOldAppInfo) {
-    gOldAppInfo = Components.classes[XULAPPINFO_CONTRACTID]
-                            .getService(Components.interfaces.nsIXULRuntime);
+    gOldAppInfo = Cc[XULAPPINFO_CONTRACTID].getService(Ci.nsIXULRuntime);
   }
 
   gAppInfo = {
     // nsIXULAppInfo
     vendor: "Mozilla",
     name: name,
     ID: id,
     version: version,
@@ -111,48 +112,57 @@ function createAppInfo(id, name, version
                                            Ci.nsISupports])
   };
 
   Object.setPrototypeOf(gAppInfo, gOldAppInfo);
 
   var XULAppInfoFactory = {
     createInstance: function (outer, iid) {
       if (outer != null)
-        throw Components.results.NS_ERROR_NO_AGGREGATION;
+        throw Cr.NS_ERROR_NO_AGGREGATION;
       return gAppInfo.QueryInterface(iid);
     }
   };
   var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
   registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo",
                             XULAPPINFO_CONTRACTID, XULAppInfoFactory);
 }
 
 // Fake the timeout functions for the TelemetryScheduler.
 function fakeSchedulerTimer(set, clear) {
-  let session = Components.utils.import("resource://gre/modules/TelemetrySession.jsm");
+  let session = Cu.import("resource://gre/modules/TelemetrySession.jsm");
   session.Policy.setSchedulerTickTimeout = set;
   session.Policy.clearSchedulerTickTimeout = clear;
 }
 
-// Fake the current date.
-function fakeNow(date) {
+/**
+ * Fake the current date.
+ * This passes all received arguments to a new Date constructor and
+ * uses the resulting date to fake the time in Telemetry modules.
+ *
+ * @return Date The new faked date.
+ */
+function fakeNow(...arguments) {
+  const date = new Date(...arguments);
+
   let session = Cu.import("resource://gre/modules/TelemetrySession.jsm");
   session.Policy.now = () => date;
   let environment = Cu.import("resource://gre/modules/TelemetryEnvironment.jsm");
   environment.Policy.now = () => date;
+
+  return new Date(date);
 }
 
 // Return a date that is |offset| ms in the future from |date|.
 function futureDate(date, offset) {
   return new Date(date.getTime() + offset);
 }
 
 function truncateToDays(aMsec) {
   return Math.floor(aMsec / MILLISECONDS_PER_DAY);
 }
 
 // Set logging preferences for all the tests.
 Services.prefs.setCharPref("toolkit.telemetry.log.level", "Trace");
-Services.prefs.setBoolPref("toolkit.telemetry.log.dump", true);
 TelemetryPing.initLogging();
 
 // Avoid timers interrupting test behavior.
 fakeSchedulerTimer(() => {}, () => {});
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
@@ -1,13 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
 Cu.import("resource://gre/modules/AddonManager.jsm");
 Cu.import("resource://gre/modules/TelemetryEnvironment.jsm", this);
 Cu.import("resource://gre/modules/Preferences.jsm", this);
 Cu.import("resource://gre/modules/PromiseUtils.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://testing-common/AddonManagerTesting.jsm");
 Cu.import("resource://testing-common/httpd.js");
 Cu.import("resource://testing-common/MockRegistrar.jsm", this);
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryLateWrites.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryLateWrites.js
@@ -1,18 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ 
 */
 /* A testcase to make sure reading late writes stacks works.  */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
 Cu.import("resource://gre/modules/Services.jsm", this);
 
 const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
 
 // Constants from prio.h for nsIFileOutputStream.init
 const PR_WRONLY = 0x2;
 const PR_CREATE_FILE = 0x8;
 const PR_TRUNCATE = 0x20;
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryLockCount.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryLockCount.js
@@ -1,18 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ 
 */
 /* A testcase to make sure reading the failed profile lock count works.  */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
 Cu.import("resource://gre/modules/Services.jsm", this);
 
 const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
 
 const LOCK_FILE_NAME = "Telemetry.FailedProfileLocks.txt";
 const N_FAILED_LOCKS = 10;
 
 // Constants from prio.h for nsIFileOutputStream.init
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryLog.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryLog.js
@@ -1,11 +1,10 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
 
 Cu.import("resource://gre/modules/TelemetryLog.jsm", this);
 Cu.import("resource://gre/modules/TelemetrySession.jsm", this);
 
 const TEST_PREFIX = "TEST-";
 const TEST_REGEX = new RegExp("^" + TEST_PREFIX);
 
 function check_event(event, id, data)
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
@@ -3,21 +3,16 @@
 */
 /* This testcase triggers two telemetry pings.
  *
  * Telemetry code keeps histograms of past telemetry pings. The first
  * ping populates these histograms. One of those histograms is then
  * checked in the second request.
  */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
 Cu.import("resource://testing-common/httpd.js", this);
 Cu.import("resource://gre/modules/ClientID.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
 Cu.import("resource://gre/modules/TelemetryFile.jsm", this);
 Cu.import("resource://gre/modules/Task.jsm", this);
 Cu.import("resource://gre/modules/Promise.jsm", this);
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryPingBuildID.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPingBuildID.js
@@ -8,19 +8,17 @@
  * 1) Run with no "previousBuildID" stored in prefs:
  *     -> no previousBuildID in telemetry system info, new value set in prefs.
  * 2) previousBuildID in prefs, equal to current build ID:
  *     -> no previousBuildID in telemetry, prefs not updated.
  * 3) previousBuildID in prefs, not equal to current build ID:
  *     -> previousBuildID in telemetry, new value set in prefs.
  */
 
-"use strict"
-
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+"use strict";
 
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/TelemetrySession.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "gDatareportingService",
   () => Cc["@mozilla.org/datareporting/service;1"]
           .getService(Ci.nsISupports)
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryPingShutdown.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPingShutdown.js
@@ -1,18 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test that TelemetryPing sends close to shutdown don't lead
 // to AsyncShutdown timeouts.
 
 "use strict";
 
-const { utils: Cu, interfaces: Ci, classes: Cc } = Components;
-
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
 Cu.import("resource://gre/modules/Timer.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/AsyncShutdown.jsm", this);
 Cu.import("resource://testing-common/httpd.js", this);
 
 const PREF_BRANCH = "toolkit.telemetry.";
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing_idle.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing_idle.js
@@ -1,15 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Check that TelemetrySession notifies correctly on idle-daily.
 
-const { utils: Cu, interfaces: Ci, classes: Cc } = Components;
-
 Cu.import("resource://testing-common/httpd.js", this);
 Cu.import("resource://gre/modules/PromiseUtils.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/Task.jsm", this);
 Cu.import("resource://gre/modules/TelemetryFile.jsm", this);
 Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
 Cu.import("resource://gre/modules/TelemetrySession.jsm", this);
 
--- a/toolkit/components/telemetry/tests/unit/test_TelemetrySendOldPings.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySendOldPings.js
@@ -7,21 +7,16 @@
  *
  * 1) Pings that are considered "expired" are deleted and never sent.
  * 2) Pings that are considered "overdue" trigger a send of all
  *    overdue and recent pings.
  */
 
 "use strict"
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
-
 Cu.import("resource://gre/modules/osfile.jsm", this);
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://testing-common/httpd.js", this);
 Cu.import("resource://gre/modules/Promise.jsm", this);
 Cu.import("resource://gre/modules/TelemetryFile.jsm", this);
 Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
 Cu.import("resource://gre/modules/Task.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
--- a/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
@@ -3,21 +3,16 @@
 */
 /* This testcase triggers two telemetry pings.
  *
  * Telemetry code keeps histograms of past telemetry pings. The first
  * ping populates these histograms. One of those histograms is then
  * checked in the second request.
  */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
 Cu.import("resource://testing-common/httpd.js", this);
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://gre/modules/ClientID.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/LightweightThemeManager.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
 Cu.import("resource://gre/modules/TelemetrySession.jsm", this);
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryStopwatch.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryStopwatch.js
@@ -1,15 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
 const Telemetry = Cc["@mozilla.org/base/telemetry;1"]
                   .getService(Ci.nsITelemetry);
 
 let tmpScope = {};
 Cu.import("resource://gre/modules/TelemetryStopwatch.jsm", tmpScope);
 let TelemetryStopwatch = tmpScope.TelemetryStopwatch;
 
 // We can't create a histogram here since the ones created with
--- a/toolkit/components/telemetry/tests/unit/test_ThirdPartyCookieProbe.js
+++ b/toolkit/components/telemetry/tests/unit/test_ThirdPartyCookieProbe.js
@@ -1,15 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-let Cu = Components.utils;
-let Cc = Components.classes;
-let Ci = Components.interfaces;
-
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 Cu.import("resource://gre/modules/ThirdPartyCookieProbe.jsm", this);
 Cu.import("resource://gre/modules/Promise.jsm", this);
 Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
 
 let TOPIC_ACCEPTED = "third-party-cookie-accepted";
 let TOPIC_REJECTED = "third-party-cookie-rejected";
--- a/toolkit/components/telemetry/tests/unit/test_ThreadHangStats.js
+++ b/toolkit/components/telemetry/tests/unit/test_ThreadHangStats.js
@@ -1,11 +1,10 @@
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cu = Components.utils;
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 function getMainThreadHangStats() {
   let threads = Services.telemetry.threadHangStats;
   return threads.find((thread) => (thread.name === "Gecko"));
 }
 
--- a/toolkit/components/telemetry/tests/unit/test_nsITelemetry.js
+++ b/toolkit/components/telemetry/tests/unit/test_nsITelemetry.js
@@ -1,14 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
 const INT_MAX = 0x7FFFFFFF;
 
 const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
 Cu.import("resource://gre/modules/Services.jsm", this);
 
 function test_expired_histogram() {
   var histogram_id = "FOOBAR";
   var test_expired_id = "TELEMETRY_TEST_EXPIRED";