Merge mozilla-central to mozilla-inbound. CLOSED TREE
authorCsoregi Natalia <ncsoregi@mozilla.com>
Wed, 17 Oct 2018 19:56:29 +0300
changeset 490029 d6ab96f62188cfb6b5121be03048e09f27ad8405
parent 490010 01368a04b48aeca172e2153cd0f8401e5162226a (current diff)
parent 490028 4c944453210c428f505bc2d81b3b7f1c99a262a6 (diff)
child 490030 373da42b11e7be5a5a85973cf41833033d744446
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
milestone64.0a1
Merge mozilla-central to mozilla-inbound. CLOSED TREE
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -989,16 +989,20 @@ window._gBrowser = {
           previousTab: oldTab,
         },
       });
       newTab.dispatchEvent(event);
 
       this._tabAttrModified(oldTab, ["selected"]);
       this._tabAttrModified(newTab, ["selected"]);
 
+      this._startMultiSelectChange();
+      this._multiSelectChangeSelected = true;
+      this.clearMultiSelectedTabs(true);
+
       if (oldBrowser != newBrowser &&
           oldBrowser.getInPermitUnload) {
         oldBrowser.getInPermitUnload(inPermitUnload => {
           if (!inPermitUnload) {
             return;
           }
           // Since the user is switching away from a tab that has
           // a beforeunload prompt active, we remove the prompt.
@@ -2109,22 +2113,22 @@ window._gBrowser = {
   discardBrowser(aBrowser, aForceDiscard) {
     "use strict";
 
     let tab = this.getTabForBrowser(aBrowser);
 
     let permitUnloadFlags = aForceDiscard ? aBrowser.dontPromptAndUnload : aBrowser.dontPromptAndDontUnload;
 
     if (!tab ||
-      tab.selected ||
-      tab.closing ||
-      this._windowIsClosing ||
-      !aBrowser.isConnected ||
-      !aBrowser.isRemoteBrowser ||
-      !aBrowser.permitUnload(permitUnloadFlags).permitUnload) {
+        tab.selected ||
+        tab.closing ||
+        this._windowIsClosing ||
+        !aBrowser.isConnected ||
+        !aBrowser.isRemoteBrowser ||
+        !aBrowser.permitUnload(permitUnloadFlags).permitUnload) {
       return;
     }
 
     // Reset webrtc sharing state.
     if (tab._sharingState) {
       this.setBrowserSharing(aBrowser, {});
     }
     webrtcUI.forgetStreamsFromBrowser(aBrowser);
@@ -4676,21 +4680,16 @@ window._gBrowser = {
       let browser = event.originalTarget;
       let tab = this.getTabForBrowser(browser);
       if (!tab) {
         return;
       }
 
       Services.obs.notifyObservers(tab, "AudibleAutoplayMediaOccurred");
     });
-
-    this.ownerGlobal.addEventListener("TabSelect", (event) => {
-      this._startMultiSelectChange();
-      this._multiSelectChangeSelected = true;
-    }, {passive: true});
   },
 };
 
 /**
  * A web progress listener object definition for a given tab.
  */
 class TabProgressListener {
   constructor(aTab, aBrowser, aStartsBlank, aWasPreloadedBrowser, aOrigStateFlags) {
@@ -5477,9 +5476,8 @@ var TabContextMenu = {
     }
     if (this.contextTab.muted) {
       if (!newTab.muted) {
         newTab.toggleMuteAudio(this.contextTab.muteReason);
       }
     }
   },
 };
-
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1184,17 +1184,16 @@
           }
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="TabSelect"><![CDATA[
         this._handleTabSelect();
-        gBrowser.clearMultiSelectedTabs(true);
       ]]></handler>
 
       <handler event="TabClose"><![CDATA[
         this._hiddenSoundPlayingStatusChanged(event.target, {closed: true});
       ]]></handler>
 
       <handler event="TabAttrModified"><![CDATA[
         if (event.detail.changed.includes("soundplaying") && event.target.hidden) {
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -522,17 +522,17 @@ class CopyCutController {
       let start = urlbar.selectionStart;
       let end = urlbar.selectionEnd;
       urlbar.inputField.value = urlbar.inputField.value.substring(0, start) +
                                 urlbar.inputField.value.substring(end);
       urlbar.selectionStart = urlbar.selectionEnd = start;
 
       let event = urlbar.document.createEvent("UIEvents");
       event.initUIEvent("input", true, false, this.window, 0);
-      urlbar.dispatchEvent(event);
+      urlbar.textbox.dispatchEvent(event);
 
       urlbar.window.SetPageProxyState("invalid");
     }
 
     ClipboardHelper.copyString(val);
   }
 
   /**
--- a/devtools/client/definitions.js
+++ b/devtools/client/definitions.js
@@ -28,17 +28,16 @@ loader.lazyGetter(this, "AccessibilityPa
 loader.lazyGetter(this, "ApplicationPanel", () => require("devtools/client/application/panel").ApplicationPanel);
 loader.lazyGetter(this, "reloadAndRecordTab", () => require("devtools/client/webreplay/menu.js").reloadAndRecordTab);
 loader.lazyGetter(this, "reloadAndStopRecordingTab", () => require("devtools/client/webreplay/menu.js").reloadAndStopRecordingTab);
 
 // Other dependencies
 loader.lazyRequireGetter(this, "AccessibilityStartup", "devtools/client/accessibility/accessibility-startup", true);
 loader.lazyRequireGetter(this, "ResponsiveUIManager", "devtools/client/responsive.html/manager", true);
 loader.lazyImporter(this, "ScratchpadManager", "resource://devtools/client/scratchpad/scratchpad-manager.jsm");
-loader.lazyRequireGetter(this, "getScreenshotFront", "resource://devtools/shared/fronts/screenshot", true);
 
 const {MultiLocalizationHelper} = require("devtools/shared/l10n");
 const L10N = new MultiLocalizationHelper(
   "devtools/client/locales/startup.properties",
   "devtools/startup/locales/key-shortcuts.properties"
 );
 
 var Tools = {};
@@ -586,17 +585,17 @@ exports.ToolboxButtons = [
     async onClick(event, toolbox) {
       // Special case for screenshot button to check for clipboard preference
       const clipboardEnabled = Services.prefs
         .getBoolPref("devtools.screenshot.clipboard.enabled");
       const args = { fullpage: true, file: true };
       if (clipboardEnabled) {
         args.clipboard = true;
       }
-      const screenshotFront = getScreenshotFront(toolbox.target);
+      const screenshotFront = toolbox.target.getFront("screenshot");
       await screenshotFront.captureAndSave(toolbox.win, args);
     }
   },
   createHighlightButton("RulersHighlighter", "rulers"),
   createHighlightButton("MeasuringToolHighlighter", "measure"),
 ];
 
 function createHighlightButton(highlighterName, id) {
--- a/devtools/client/framework/test/browser_toolbox_options_disable_js.js
+++ b/devtools/client/framework/test/browser_toolbox_options_disable_js.js
@@ -2,29 +2,22 @@
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that disabling JavaScript for a tab works as it should.
 
 const TEST_URI = URL_ROOT + "browser_toolbox_options_disable_js.html";
 
-function test() {
-  addTab(TEST_URI).then(async (tab) => {
-    const target = await TargetFactory.forTab(tab);
-    gDevTools.showToolbox(target).then(testSelectTool);
-  });
-}
+add_task(async function() {
+  const tab = await addTab(TEST_URI);
+  const target = await TargetFactory.forTab(tab);
+  const toolbox = await gDevTools.showToolbox(target);
 
-function testSelectTool(toolbox) {
-  toolbox.once("options-selected", () => testToggleJS(toolbox));
-  toolbox.selectTool("options");
-}
-
-const testToggleJS = async function(toolbox) {
+  await toolbox.selectTool("options");
   ok(true, "Toolbox selected via selectTool method");
 
   await testJSEnabled();
   await testJSEnabledIframe();
 
   // Disable JS.
   await toggleJS(toolbox);
 
@@ -32,18 +25,19 @@ const testToggleJS = async function(tool
   await testJSDisabledIframe();
 
   // Re-enable JS.
   await toggleJS(toolbox);
 
   await testJSEnabled();
   await testJSEnabledIframe();
 
-  finishUp(toolbox);
-};
+  await toolbox.destroy();
+  gBrowser.removeCurrentTab();
+});
 
 async function testJSEnabled() {
   info("Testing that JS is enabled");
 
   // We use waitForTick here because switching docShell.allowJavascript to true
   // takes a while to become live.
   await waitForTick();
 
@@ -74,19 +68,27 @@ async function toggleJS(toolbox) {
   const cbx = panel.panelDoc.getElementById("devtools-disable-javascript");
 
   if (cbx.checked) {
     info("Clearing checkbox to re-enable JS");
   } else {
     info("Checking checkbox to disable JS");
   }
 
+  let { javascriptEnabled } = toolbox.target.activeTab.configureOptions;
+  is(javascriptEnabled, !cbx.checked,
+    "BrowsingContextFront's configureOptions is correct before the toggle");
+
   const browserLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   cbx.click();
   await browserLoaded;
+
+  ({ javascriptEnabled } = toolbox.target.activeTab.configureOptions);
+  is(javascriptEnabled, !cbx.checked,
+    "BrowsingContextFront's configureOptions is correctly updated");
 }
 
 async function testJSDisabled() {
   info("Testing that JS is disabled");
 
   await ContentTask.spawn(gBrowser.selectedBrowser, {}, function() {
     const doc = content.document;
     const output = doc.getElementById("output");
@@ -105,15 +107,8 @@ async function testJSDisabledIframe() {
     const iframe = doc.querySelector("iframe");
     const iframeDoc = iframe.contentDocument;
     const output = iframeDoc.getElementById("output");
     iframeDoc.querySelector("#logJSDisabled").click();
     ok(output.textContent !== "JavaScript Disabled",
        'output is not "JavaScript Disabled" in iframe');
   });
 }
-
-function finishUp(toolbox) {
-  toolbox.destroy().then(function() {
-    gBrowser.removeCurrentTab();
-    finish();
-  });
-}
--- a/devtools/client/framework/toolbox-options.js
+++ b/devtools/client/framework/toolbox-options.js
@@ -455,19 +455,18 @@ OptionsPanel.prototype = {
       prefSelect.addEventListener("change", function(e) {
         const select = e.target;
         SetPref(select.getAttribute("data-pref"),
           select.options[select.selectedIndex].value);
       });
     }
 
     if (this.target.activeTab && !this.target.chrome) {
-      const response = await this.target.activeTab.attach();
-      this._origJavascriptEnabled = !response.javascriptEnabled;
-      this.disableJSNode.checked = this._origJavascriptEnabled;
+      this.disableJSNode.checked =
+        !this.target.activeTab.configureOptions.javascriptEnabled;
       this.disableJSNode.addEventListener("click", this._disableJSClicked);
     } else {
       // Hide the checkbox and label
       this.disableJSNode.parentNode.style.display = "none";
 
       const triggersPageRefreshLabel =
         this.panelDoc.getElementById("triggers-page-refresh-label");
       triggersPageRefreshLabel.style.display = "none";
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -29,17 +29,16 @@ loader.lazyRequireGetter(this, "ToolSide
 loader.lazyRequireGetter(this, "MarkupView", "devtools/client/inspector/markup/markup");
 loader.lazyRequireGetter(this, "HighlightersOverlay", "devtools/client/inspector/shared/highlighters-overlay");
 loader.lazyRequireGetter(this, "nodeConstants", "devtools/shared/dom-node-constants");
 loader.lazyRequireGetter(this, "Menu", "devtools/client/framework/menu");
 loader.lazyRequireGetter(this, "MenuItem", "devtools/client/framework/menu-item");
 loader.lazyRequireGetter(this, "ExtensionSidebar", "devtools/client/inspector/extensions/extension-sidebar");
 loader.lazyRequireGetter(this, "clipboardHelper", "devtools/shared/platform/clipboard");
 loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
-loader.lazyRequireGetter(this, "getScreenshotFront", "devtools/shared/fronts/screenshot", true);
 loader.lazyRequireGetter(this, "saveScreenshot", "devtools/shared/screenshot/save");
 loader.lazyRequireGetter(this, "ChangesManager",
 "devtools/client/inspector/changes/ChangesManager");
 
 loader.lazyImporter(this, "DeferredTask", "resource://gre/modules/DeferredTask.jsm");
 
 const {LocalizationHelper, localizeMarkup} = require("devtools/shared/l10n");
 const INSPECTOR_L10N =
@@ -2329,17 +2328,17 @@ Inspector.prototype = {
 
     const clipboardEnabled = Services.prefs
       .getBoolPref("devtools.screenshot.clipboard.enabled");
     const args = {
       file: true,
       selector: this.selectionCssSelector,
       clipboard: clipboardEnabled
     };
-    const screenshotFront = getScreenshotFront(this.target);
+    const screenshotFront = this.target.getFront("screenshot");
     const screenshot = await screenshotFront.capture(args);
     await saveScreenshot(this.panelWin, args, screenshot);
   },
 
   /**
    * Scroll the node into view.
    */
   scrollNodeIntoView: function() {
--- a/devtools/shared/fronts/screenshot.js
+++ b/devtools/shared/fronts/screenshot.js
@@ -15,24 +15,9 @@ const ScreenshotFront = protocol.FrontCl
   },
 
   async captureAndSave(window, args) {
     const screenshot = await this.capture(args);
     return saveScreenshot(window, args, screenshot);
   }
 });
 
-// A cache of created fronts: WeakMap<Client, Front>
-const knownFronts = new WeakMap();
-
-/**
- * Create a screenshot front only when needed
- */
-function getScreenshotFront(target) {
-  let front = knownFronts.get(target.client);
-  if (front == null && target.form.screenshotActor != null) {
-    front = new ScreenshotFront(target.client, target.form);
-    knownFronts.set(target.client, front);
-  }
-  return front;
-}
-
-exports.getScreenshotFront = getScreenshotFront;
+exports.ScreenshotFront = ScreenshotFront;
--- a/devtools/shared/fronts/targets/browsing-context.js
+++ b/devtools/shared/fronts/targets/browsing-context.js
@@ -10,16 +10,22 @@ const {custom} = protocol;
 loader.lazyRequireGetter(this, "ThreadClient", "devtools/shared/client/thread-client");
 
 const BrowsingContextFront = protocol.FrontClassWithSpec(browsingContextTargetSpec, {
   initialize: function(client, form) {
     protocol.Front.prototype.initialize.call(this, client, form);
 
     this.thread = null;
 
+    // Cache the value of some target properties that are being returned by `attach`
+    // request and then keep them up-to-date in `reconfigure` request.
+    this.configureOptions = {
+      javascriptEnabled: null,
+    };
+
     // TODO: remove once ThreadClient becomes a front
     this.client = client;
   },
 
   /**
    * Attach to a thread actor.
    *
    * @param object options
@@ -42,25 +48,36 @@ const BrowsingContextFront = protocol.Fr
       return [response, this.thread];
     });
   },
 
   attach: custom(async function() {
     const response = await this._attach();
 
     this._threadActor = response.threadActor;
-    this.javascriptEnabled = response.javascriptEnabled;
-    this.cacheDisabled = response.cacheDisabled;
+    this.configureOptions.javascriptEnabled = response.javascriptEnabled;
     this.traits = response.traits || {};
 
     return response;
   }, {
     impl: "_attach"
   }),
 
+  reconfigure: custom(async function({ options }) {
+    const response = await this._reconfigure({ options });
+
+    if (typeof options.javascriptEnabled != "undefined") {
+      this.configureOptions.javascriptEnabled = options.javascriptEnabled;
+    }
+
+    return response;
+  }, {
+    impl: "_reconfigure"
+  }),
+
   detach: custom(async function() {
     let response;
     try {
       response = await this._detach();
     } catch (e) {
       console.warn(
         `Error while detaching the browsing context target front: ${e.message}`);
     }
--- a/devtools/shared/specs/index.js
+++ b/devtools/shared/specs/index.js
@@ -177,16 +177,21 @@ const Types = exports.__TypesForTests = 
     spec: "devtools/shared/specs/property-iterator",
     front: null,
   },
   {
     types: ["reflow"],
     spec: "devtools/shared/specs/reflow",
     front: "devtools/shared/fronts/reflow",
   },
+  {
+    types: ["screenshot"],
+    spec: "devtools/shared/specs/screenshot",
+    front: "devtools/shared/fronts/screenshot",
+  },
   /* Script and source have old fashion client and no front */
   {
     types: ["context"],
     spec: "devtools/shared/specs/script",
     front: null,
   },
   {
     types: ["source"],
--- a/dom/cache/TypeUtils.cpp
+++ b/dom/cache/TypeUtils.cpp
@@ -514,33 +514,13 @@ TypeUtils::SerializeCacheStream(nsIInput
 
   cacheStream.controlChild() = nullptr;
   cacheStream.controlParent() = nullptr;
 
   UniquePtr<AutoIPCStream> autoStream(new AutoIPCStream(cacheStream.stream()));
   autoStream->Serialize(aStream, GetIPCManager());
 
   aStreamCleanupList.AppendElement(std::move(autoStream));
-
-  // This nested condition guards against silent failures in IPC code
-  // that would cause a crash when the message is sent. Specifically,
-  // if IPCStreamSource::Initialize fails to get a StrongWorkerRef
-  // (e.g. when the worker terminates), a nullptr is silently stored
-  // in IPCRemoteStreamType.
-  // This is a workaround, requested in bug 1484524, and a more
-  // reasonable solution should replace it.
-  if (cacheStream.stream().type() == OptionalIPCStream::TIPCStream) {
-    const auto& ipcStream = cacheStream.stream().get_IPCStream();
-    if (ipcStream.type() == IPCStream::TIPCRemoteStream) {
-      const auto& ipcRemoteStream = ipcStream.get_IPCRemoteStream();
-      using mozilla::ipc::IPCRemoteStreamType;
-      if (ipcRemoteStream.stream().type() == IPCRemoteStreamType::TPChildToParentStreamChild) {
-        if (!ipcRemoteStream.stream().get_PChildToParentStreamChild()) {
-          aRv.Throw(NS_ERROR_FAILURE);
-        }
-      }
-    }
-  }
 }
 
 } // namespace cache
 } // namespace dom
 } // namespace mozilla
--- a/netwerk/dns/TRR.cpp
+++ b/netwerk/dns/TRR.cpp
@@ -994,17 +994,18 @@ TRR::OnStopRequest(nsIRequest *aRequest,
 {
   // The dtor will be run after the function returns
   LOG(("TRR:OnStopRequest %p %s %d failed=%d code=%X\n",
        this, mHost.get(), mType, mFailed, (unsigned int)aStatusCode));
   nsCOMPtr<nsIChannel> channel;
   channel.swap(mChannel);
 
   // Bad content is still considered "okay" if the HTTP response is okay
-  gTRRService->TRRIsOkay(NS_SUCCEEDED(aStatusCode));
+  gTRRService->TRRIsOkay(NS_SUCCEEDED(aStatusCode) ? TRRService::OKAY_NORMAL :
+                         TRRService::OKAY_BAD);
 
   // if status was "fine", parse the response and pass on the answer
   if (!mFailed && NS_SUCCEEDED(aStatusCode)) {
     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
     if (!httpChannel) {
       return NS_ERROR_UNEXPECTED;
     }
     nsresult rv = NS_OK;
@@ -1132,17 +1133,17 @@ TRR::Cancel()
   if (!NS_IsMainThread()) {
     NS_DispatchToMainThread(new ProxyCancel(this));
     return;
   }
   if (mChannel) {
     LOG(("TRR: %p canceling Channel %p %s %d\n", this,
          mChannel.get(), mHost.get(), mType));
     mChannel->Cancel(NS_ERROR_ABORT);
-    gTRRService->TRRIsOkay(false);
+    gTRRService->TRRIsOkay(TRRService::OKAY_TIMEOUT);
   }
 }
 
 #undef LOG
 
 // namespace
 }
 }
--- a/netwerk/dns/TRRService.cpp
+++ b/netwerk/dns/TRRService.cpp
@@ -593,19 +593,24 @@ TRRService::Notify(nsITimer *aTimer)
     MOZ_CRASH("Unknown timer");
   }
 
   return NS_OK;
 }
 
 
 void
-TRRService::TRRIsOkay(bool aWorks)
+TRRService::TRRIsOkay(enum TrrOkay aReason)
 {
-  if (aWorks) {
+  Telemetry::AccumulateCategorical(aReason == OKAY_NORMAL ?
+                                   Telemetry::LABELS_DNS_TRR_SUCCESS::Fine :
+                                   (aReason == OKAY_TIMEOUT ?
+                                    Telemetry::LABELS_DNS_TRR_SUCCESS::Timeout :
+                                    Telemetry::LABELS_DNS_TRR_SUCCESS::Bad));
+  if (aReason == OKAY_NORMAL) {
     mTRRFailures = 0;
   } else if ((mMode == MODE_TRRFIRST) && (mConfirmationState == CONFIRM_OK)) {
     // only count failures while in OK state
     uint32_t fails = ++mTRRFailures;
     if (fails >= mDisableAfterFails) {
       LOG(("TRRService goes FAILED after %u failures in a row\n", fails));
       mConfirmationState = CONFIRM_FAILED;
       // Fire off a timer and start re-trying the NS domain again
--- a/netwerk/dns/TRRService.h
+++ b/netwerk/dns/TRRService.h
@@ -44,17 +44,22 @@ public:
   uint32_t GetRequestTimeout() { return mTRRTimeout; }
 
   LookupStatus CompleteLookup(nsHostRecord *, nsresult, mozilla::net::AddrInfo *, bool pb) override;
   LookupStatus CompleteLookupByType(nsHostRecord *, nsresult, const nsTArray<nsCString> *, uint32_t, bool pb) override;
   void TRRBlacklist(const nsACString &host, bool privateBrowsing, bool aParentsToo);
   bool IsTRRBlacklisted(const nsACString &host, bool privateBrowsing, bool fullhost);
 
   bool MaybeBootstrap(const nsACString &possible, nsACString &result);
-  void TRRIsOkay(bool aWorks);
+  enum TrrOkay {
+    OKAY_NORMAL = 0,
+    OKAY_TIMEOUT = 1,
+    OKAY_BAD = 2
+  };
+  void TRRIsOkay(enum TrrOkay aReason);
 
 private:
   virtual  ~TRRService();
   nsresult ReadPrefs(const char *name);
   void GetPrefBranch(nsIPrefBranch **result);
   void MaybeConfirm();
 
   bool                      mInitialized;
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -510,20 +510,27 @@ AddrHostRecord::ResolveComplete()
                               ((mNativeSuccess ? Telemetry::LABELS_DNS_TRR_COMPARE::NativeWorked :
                                 (mTRRSuccess ? Telemetry::LABELS_DNS_TRR_COMPARE::TRRWorked:
                                  Telemetry::LABELS_DNS_TRR_COMPARE::BothFailed))));
     } else if (mResolverMode == MODE_TRRFIRST) {
         if(flags & nsIDNSService::RESOLVE_DISABLE_TRR) {
             // TRR is disabled on request, which is a next-level back-off method.
             Telemetry::Accumulate(Telemetry::DNS_TRR_DISABLED, mNativeSuccess);
         } else {
-            AccumulateCategorical(mTRRSuccess?
-                                  Telemetry::LABELS_DNS_TRR_FIRST::TRRWorked :
-                                  ((mNativeSuccess ? Telemetry::LABELS_DNS_TRR_FIRST::NativeFallback :
-                                    Telemetry::LABELS_DNS_TRR_FIRST::BothFailed)));
+            if (mTRRSuccess) {
+                AccumulateCategorical(Telemetry::LABELS_DNS_TRR_FIRST2::TRR);
+            } else if(mNativeSuccess) {
+                if (mTRRUsed) {
+                    AccumulateCategorical(Telemetry::LABELS_DNS_TRR_FIRST2::NativeAfterTRR);
+                } else {
+                    AccumulateCategorical(Telemetry::LABELS_DNS_TRR_FIRST2::Native);
+                }
+            } else {
+                AccumulateCategorical(Telemetry::LABELS_DNS_TRR_FIRST2::BothFailed);
+            }
         }
     }
 
     switch(mResolverMode) {
     case MODE_NATIVEONLY:
     case MODE_TRROFF:
         AccumulateCategorical(Telemetry::LABELS_DNS_LOOKUP_ALGORITHM::nativeOnly);
         break;
--- a/testing/jsshell/benchmark.py
+++ b/testing/jsshell/benchmark.py
@@ -105,22 +105,29 @@ class Benchmark(object):
         if fetches_dir and os.path.isdir(fetches_dir):
             fetchdir = os.path.join(fetches_dir, self.name)
             if os.path.isdir(fetchdir):
                 shutil.copytree(fetchdir, self.path)
 
     def run(self):
         self.reset()
 
+        # Update the environment variables
+        env = os.environ.copy()
+
+        # disable "GC poisoning" Bug# 1499043
+        env['JSGC_DISABLE_POISONING'] = '1'
+
         process_args = {
             'cmd': self.command,
             'cwd': self.path,
             'onFinish': self.collect_results,
             'processOutputLine': self.process_line,
             'stream': sys.stdout,
+            'env': env,
         }
         proc = ProcessHandler(**process_args)
         proc.run()
         return proc.wait()
 
 
 class RunOnceBenchmark(Benchmark):
     def collect_results(self):
--- a/testing/mozharness/mozharness/mozilla/testing/raptor.py
+++ b/testing/mozharness/mozharness/mozilla/testing/raptor.py
@@ -435,16 +435,19 @@ class Raptor(TestingMixin, MercurialScri
             self.info("webrender is enabled so setting MOZ_WEBRENDER=1 and MOZ_ACCELERATED=1")
             env['MOZ_WEBRENDER'] = '1'
             env['MOZ_ACCELERATED'] = '1'
 
         # mitmproxy needs path to mozharness when installing the cert, and tooltool
         env['SCRIPTSPATH'] = scripts_path
         env['EXTERNALTOOLSPATH'] = external_tools_path
 
+        # disable "GC poisoning" Bug# 1499043
+        env['JSGC_DISABLE_POISONING'] = '1'
+
         if self.repo_path is not None:
             env['MOZ_DEVELOPER_REPO_DIR'] = self.repo_path
         if self.obj_path is not None:
             env['MOZ_DEVELOPER_OBJ_DIR'] = self.obj_path
 
         # sets a timeout for how long raptor should run without output
         output_timeout = self.config.get('raptor_output_timeout', 3600)
         # run raptor tests
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -3385,24 +3385,24 @@
     "record_in_processes": ["main"],
     "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
     "labels": ["BothWorked", "NativeWorked", "TRRWorked", "BothFailed"],
     "bug_numbers": [1460589],
     "description": "DNS: success distribution when both native and TRR were used"
   },
-  "DNS_TRR_FIRST": {
+  "DNS_TRR_FIRST2": {
     "record_in_processes": ["main"],
     "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
-    "labels": ["TRRWorked", "NativeFallback", "BothFailed"],
-    "bug_numbers": [1472659],
-    "description": "TRR-first mode distribution. 0=Worked, 1=fell back to native, 2=both failed"
+    "labels": ["TRR", "NativeAfterTRR", "Native", "BothFailed"],
+    "bug_numbers": [1497252],
+    "description": "TRR-first mode distribution. 0=Worked, 1=fell back fine after TRR fail, 2=native worked, 3=both failed"
   },
   "DNS_TRR_DISABLED": {
     "record_in_processes": ["main"],
     "expires_in_version": "never",
     "kind": "boolean",
     "description": "Resolve success rate when in TRR-first and called TRR-disabled (fall-back mode)",
     "bug_numbers": [1472659],
     "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"]
@@ -3428,16 +3428,25 @@
     "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"],
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 5000,
     "n_buckets": 100,
     "bug_numbers": [1470853],
     "description": "Number of DOH requests per connection"
   },
+  "DNS_TRR_SUCCESS": {
+    "record_in_processes": ["main"],
+    "expires_in_version": "never",
+    "kind": "categorical",
+    "labels": ["Fine", "Timeout", "Bad"],
+    "description": "How often TRR (Trusted Recursive Resolver) requests are fine, time-out or error.",
+    "bug_numbers": [1497438],
+    "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"]
+  },
   "DNS_LOOKUP_ALGORITHM": {
     "record_in_processes": ["main"],
     "alert_emails": ["necko@mozilla.com", "dstenberg@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
     "labels": ["nativeOnly", "trrRace", "trrFirst", "trrOnly", "trrShadow"],
     "bug_numbers": [1434852],
     "description": "DNS: lookup algorithm"