Merge autoland to mozilla-central. a=merge
authorGurzau Raul <rgurzau@mozilla.com>
Mon, 15 Oct 2018 01:17:04 +0300
changeset 496907 f8560f7a88a899e10cc103a25099b3c9fc088247
parent 496889 4b02380c0bbb5151f1a1f4606c29f2a1cbb70225 (current diff)
parent 496906 1feb8b3f06e7f93d1cd67d59011074add931b086 (diff)
child 496914 3aca49b2df240e86d5b164feb18575681c818c63
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.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 autoland to mozilla-central. a=merge
toolkit/mozapps/extensions/test/browser/browser_bug562854.js
--- a/browser/app/moz.build
+++ b/browser/app/moz.build
@@ -79,21 +79,16 @@ if CONFIG['OS_ARCH'] == 'WINNT':
     LOCAL_INCLUDES += [
         '/browser/app/winlauncher',
     ]
     DELAYLOAD_DLLS += [
         'oleaut32.dll',
         'ole32.dll',
     ]
 
-if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'Darwin':
-    USE_LIBS += [
-        'mozsandbox',
-    ]
-
 if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
     # For sandbox includes and the include dependencies those have
     LOCAL_INCLUDES += [
         '/security/sandbox/chromium',
         '/security/sandbox/chromium-shim',
     ]
 
     USE_LIBS += [
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -38,20 +38,16 @@
 #include "mozilla/Sprintf.h"
 #include "mozilla/StartupTimeline.h"
 #include "mozilla/WindowsDllBlocklist.h"
 
 #ifdef LIBFUZZER
 #include "FuzzerDefs.h"
 #endif
 
-#ifdef XP_MACOSX
-#include "mozilla/Sandbox.h"
-#endif
-
 #ifdef MOZ_LINUX_32_SSE2_STARTUP_ERROR
 #include <cpuid.h>
 #include "mozilla/Unused.h"
 
 static bool
 IsSSE2Available()
 {
   // The rest of the app has been compiled to assume that SSE2 is present
@@ -262,26 +258,16 @@ InitXPCOMGlue()
 // NB: This must be extern, as this value is checked elsewhere
 uint32_t gBlocklistInitFlags = eDllBlocklistInitFlagDefault;
 #endif
 
 int main(int argc, char* argv[], char* envp[])
 {
   mozilla::TimeStamp start = mozilla::TimeStamp::Now();
 
-#ifdef XP_MACOSX
-  if (argc > 1 && IsArg(argv[1], "contentproc")) {
-    std::string err;
-    if (!mozilla::EarlyStartMacSandboxIfEnabled(argc, argv, err)) {
-      Output("Sandbox error: %s\n", err.c_str());
-      MOZ_CRASH("Sandbox initialization failed");
-    }
-  }
-#endif
-
 #ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
   // We are launching as a content process, delegate to the appropriate
   // main
   if (argc > 1 && IsArg(argv[1], "contentproc")) {
 #ifdef HAS_DLL_BLOCKLIST
     DllBlocklist_Initialize(eDllBlocklistInitFlagIsChildProcess);
 #endif
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1021,22 +1021,16 @@ pref("security.sandbox.gpu.level", 0);
 
 // Controls whether we disable win32k for the GMP processes.
 // true means that win32k system calls are not permitted.
 // Note: win32k is currently _not_ disabled due to intermittent test failures,
 // where the GMP process fails very early. See bug 1449348.
 pref("security.sandbox.gmp.win32k-disable", false);
 #endif
 
-#if defined(NIGHTLY_BUILD) && defined(XP_MACOSX) && defined(MOZ_SANDBOX)
-// Start the Mac sandbox immediately during child process startup instead
-// of when messaged by the parent after the message loop is running.
-pref("security.sandbox.content.mac.earlyinit", true);
-#endif
-
 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
 // This pref is discussed in bug 1083344, the naming is inspired from its
 // Windows counterpart, but on Mac it's an integer which means:
 // 0 -> "no sandbox" (nightly only)
 // 1 -> "preliminary content sandboxing enabled: write access to
 //       home directory is prevented"
 // 2 -> "preliminary content sandboxing enabled with profile protection:
 //       write access to home directory is prevented, read and write access
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -102,17 +102,16 @@ devtools.jar:
     skin/dark-theme.css (themes/dark-theme.css)
     skin/light-theme.css (themes/light-theme.css)
     skin/toolbars.css (themes/toolbars.css)
     skin/toolbox.css (themes/toolbox.css)
     skin/tooltips.css (themes/tooltips.css)
     skin/images/accessibility.svg (themes/images/accessibility.svg)
     skin/images/add.svg (themes/images/add.svg)
     skin/images/arrowhead-left.svg (themes/images/arrowhead-left.svg)
-    skin/images/arrowhead-right.svg (themes/images/arrowhead-right.svg)
     skin/images/arrowhead-down.svg (themes/images/arrowhead-down.svg)
     skin/images/arrowhead-up.svg (themes/images/arrowhead-up.svg)
     skin/images/breadcrumbs-divider.svg (themes/images/breadcrumbs-divider.svg)
     skin/images/filters.svg (themes/images/filters.svg)
     skin/images/filter-swatch.svg (themes/images/filter-swatch.svg)
     skin/images/aboutdebugging-collapse-icon.svg (themes/images/aboutdebugging-collapse-icon.svg)
     skin/images/aboutdebugging-connect-icon.svg (themes/images/aboutdebugging-connect-icon.svg)
     skin/images/aboutdebugging-firefox-aurora.svg (themes/images/aboutdebugging-firefox-aurora.svg)
--- a/devtools/client/themes/layout.css
+++ b/devtools/client/themes/layout.css
@@ -212,67 +212,96 @@
 
 .flex-outline-final,
 .flex-outline-basis,
 .flex-outline-delta {
   grid-row: 1;
 }
 
 .flex-outline-final {
-  border: 1px solid currentColor;
+  border: 2px solid currentColor;
   position: relative;
   grid-column: final-start / final-end;
 }
 
 .flex-outline-final.clamped::after {
   content: "";
-  background-color: var(--theme-body-background);
   background-image: url(chrome://devtools/skin/images/lock.svg);
   background-size: 16px;
   background-repeat: no-repeat;
   background-position: center 1px;
   fill: currentColor;
   -moz-context-properties: fill;
   width: 20px;
   height: 20px;
   position: absolute;
   right: -10px;
   top: 6px;
-  border-radius: 50%;
+  /* Making sure the icon is visible against any background by creating a plain background
+     around its shape, using a drop-shadow filter. */
+  filter:
+    drop-shadow(1px 0px 0px var(--theme-body-background))
+    drop-shadow(0px 1px 0px var(--theme-body-background))
+    drop-shadow(-1px 0px 0px var(--theme-body-background))
+    drop-shadow(0px -1px 0px var(--theme-body-background));
 }
 
 .flex-outline.column .flex-outline-final.clamped::after {
   transform: rotate(-.25turn);
 }
 
 .flex-outline-basis {
   border-style: dotted;
   border-width: 3px;
-  margin: 1px 0;
+  margin: 1px;
   grid-column: basis-start / basis-end;
 }
 
 .flex-outline-basis.zero-basis {
   border-width: 0 0 0 3px;
 }
 
 .flex-outline-delta {
-  background-repeat: round;
-  fill: currentColor;
-  -moz-context-properties: fill;
   grid-column: delta-start / delta-end;
-  margin: 4px;
+  margin: 3px 0;
+  opacity: .5;
+  position: relative;
+}
+
+.flex-outline-delta::before {
+  content: "";
+  position: absolute;
+  left: 2px;
+  right: 2px;
+  top: calc(50% - .5px);
+  height: 1px;
+  background: currentColor;
 }
 
-.flex-outline.growing .flex-outline-delta {
-  background-image: url(chrome://devtools/skin/images/arrowhead-right.svg);
+.flex-outline-delta::after {
+  content: "";
+  position: absolute;
+  width: 5px;
+  height: 5px;
+  top: 50%;
+  border: 1px solid currentColor;
 }
 
-.flex-outline.shrinking .flex-outline-delta {
-  background-image: url(chrome://devtools/skin/images/arrowhead-left.svg);
+.flex-outline.growing .flex-outline-delta:after {
+  right: 2px;
+  border-width: 1px 1px 0 0;
+  transform-origin: top right;
+  transform: rotate(.125turn);
+}
+
+.flex-outline.shrinking .flex-outline-delta:after {
+  left: 2px;
+  border-width: 1px 0 0 1px;
+  transform-origin: top left;
+  transform: rotate(-.125turn);
 }
 
 .flex-outline-point {
   position: relative;
   -moz-user-select: none;
 }
 
 .flex-outline-point {
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -189,17 +189,16 @@
 #ifdef XP_WIN
 #include <process.h>
 #define getpid _getpid
 #include "mozilla/widget/AudioSession.h"
 #include "mozilla/audio/AudioNotificationReceiver.h"
 #endif
 
 #if defined(XP_MACOSX)
-#include "nsMacUtilsImpl.h"
 #include <CoreServices/CoreServices.h>
 // Info.plist key associated with the developer repo path
 #define MAC_DEV_REPO_KEY "MozillaDeveloperRepoPath"
 // Info.plist key associated with the developer repo object directory
 #define MAC_DEV_OBJ_KEY "MozillaDeveloperObjPath"
 #endif /* XP_MACOSX */
 
 #ifdef MOZ_X11
@@ -1519,16 +1518,120 @@ ContentChild::RecvReinitRenderingForDevi
     if (tabChild->GetLayersId().IsValid()) {
       tabChild->ReinitRenderingForDeviceReset();
     }
   }
   return IPC_OK();
 }
 
 #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
+
+#include <stdlib.h>
+
+static bool
+GetAppPaths(nsCString &aAppPath, nsCString &aAppBinaryPath, nsCString &aAppDir)
+{
+  nsAutoCString appPath;
+  nsAutoCString appBinaryPath(
+    (CommandLine::ForCurrentProcess()->argv()[0]).c_str());
+
+  nsAutoCString::const_iterator start, end;
+  appBinaryPath.BeginReading(start);
+  appBinaryPath.EndReading(end);
+  if (RFindInReadable(NS_LITERAL_CSTRING(".app/Contents/MacOS/"), start, end)) {
+    end = start;
+    ++end; ++end; ++end; ++end;
+    appBinaryPath.BeginReading(start);
+    appPath.Assign(Substring(start, end));
+  } else {
+    return false;
+  }
+
+  nsCOMPtr<nsIFile> app, appBinary;
+  nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(appPath),
+                                true, getter_AddRefs(app));
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+  rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(appBinaryPath),
+                       true, getter_AddRefs(appBinary));
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+
+  nsCOMPtr<nsIFile> appDir;
+  nsCOMPtr<nsIProperties> dirSvc =
+    do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
+  if (!dirSvc) {
+    return false;
+  }
+  rv = dirSvc->Get(NS_GRE_DIR,
+                   NS_GET_IID(nsIFile), getter_AddRefs(appDir));
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+  bool exists;
+  rv = appDir->Exists(&exists);
+  if (NS_FAILED(rv) || !exists) {
+    return false;
+  }
+
+  // appDir points to .app/Contents/Resources, for our purposes we want
+  // .app/Contents.
+  nsCOMPtr<nsIFile> appDirParent;
+  rv = appDir->GetParent(getter_AddRefs(appDirParent));
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+
+  rv = app->Normalize();
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+  app->GetNativePath(aAppPath);
+
+  rv = appBinary->Normalize();
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+  appBinary->GetNativePath(aAppBinaryPath);
+
+  rv = appDirParent->Normalize();
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+  appDirParent->GetNativePath(aAppDir);
+
+  return true;
+}
+
+// This function is only used in an |#ifdef DEBUG| path.
+#ifdef DEBUG
+// Given a path to a file, return the directory which contains it.
+static nsAutoCString
+GetDirectoryPath(const char *aPath) {
+  nsCOMPtr<nsIFile> file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
+  if (!file ||
+      NS_FAILED(file->InitWithNativePath(nsDependentCString(aPath)))) {
+    MOZ_CRASH("Failed to create or init an nsIFile");
+  }
+  nsCOMPtr<nsIFile> directoryFile;
+  if (NS_FAILED(file->GetParent(getter_AddRefs(directoryFile))) ||
+      !directoryFile) {
+    MOZ_CRASH("Failed to get parent for an nsIFile");
+  }
+  directoryFile->Normalize();
+  nsAutoCString directoryPath;
+  if (NS_FAILED(directoryFile->GetNativePath(directoryPath))) {
+    MOZ_CRASH("Failed to get path for an nsIFile");
+  }
+  return directoryPath;
+}
+#endif // DEBUG
+
 extern "C" {
 CGError
 CGSSetDenyWindowServerConnections(bool);
 void CGSShutdownServerConnections();
 };
 
 static bool
 StartMacOSContentSandbox()
@@ -1550,19 +1653,19 @@ StartMacOSContentSandbox()
         "security.sandbox.content.mac.disconnect-windowserver")) {
     CGError result = CGSSetDenyWindowServerConnections(true);
     MOZ_DIAGNOSTIC_ASSERT(result == kCGErrorSuccess);
 #if !MOZ_DIAGNOSTIC_ASSERT_ENABLED
     Unused << result;
 #endif
   }
 
-  nsAutoCString appPath;
-  if (!nsMacUtilsImpl::GetAppPath(appPath)) {
-    MOZ_CRASH("Error resolving child process app path");
+  nsAutoCString appPath, appBinaryPath, appDir;
+  if (!GetAppPaths(appPath, appBinaryPath, appDir)) {
+    MOZ_CRASH("Error resolving child process path");
   }
 
   ContentChild* cc = ContentChild::GetSingleton();
 
   nsresult rv;
   nsCOMPtr<nsIFile> profileDir;
   cc->GetProfileDir(getter_AddRefs(profileDir));
   nsCString profileDirPath;
@@ -1578,19 +1681,19 @@ StartMacOSContentSandbox()
 
   MacSandboxInfo info;
   info.type = MacSandboxType_Content;
   info.level = sandboxLevel;
   info.hasFilePrivileges = isFileProcess;
   info.shouldLog = Preferences::GetBool("security.sandbox.logging.enabled") ||
                    PR_GetEnv("MOZ_SANDBOX_LOGGING");
   info.appPath.assign(appPath.get());
+  info.appBinaryPath.assign(appBinaryPath.get());
+  info.appDir.assign(appDir.get());
   info.hasAudio = !Preferences::GetBool("media.cubeb.sandbox");
-  info.hasWindowServer = !Preferences::GetBool(
-      "security.sandbox.content.mac.disconnect-windowserver");
 
   // These paths are used to whitelist certain directories used by the testing
   // system. They should not be considered a public API, and are only intended
   // for use in automation.
   nsAutoCString testingReadPath1;
   Preferences::GetCString("security.sandbox.content.mac.testing_read_path1",
                           testingReadPath1);
   if (!testingReadPath1.IsEmpty()) {
@@ -1634,18 +1737,17 @@ StartMacOSContentSandbox()
 #ifdef DEBUG
   // When a content process dies intentionally (|NoteIntentionalCrash|), for
   // tests it wants to log that it did this. Allow writing to this location
   // that the testrunner wants.
   char *bloatLog = PR_GetEnv("XPCOM_MEM_BLOAT_LOG");
   if (bloatLog != nullptr) {
     // |bloatLog| points to a specific file, but we actually write to a sibling
     // of that path.
-    nsAutoCString bloatDirectoryPath =
-      nsMacUtilsImpl::GetDirectoryPath(bloatLog);
+    nsAutoCString bloatDirectoryPath = GetDirectoryPath(bloatLog);
     info.debugWriteDir.assign(bloatDirectoryPath.get());
   }
 #endif // DEBUG
 
   std::string err;
   if (!mozilla::StartMacSandbox(info, err)) {
     NS_WARNING(err.c_str());
     MOZ_CRASH("sandbox_init() failed");
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -105,27 +105,25 @@
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TelemetryIPC.h"
 #include "mozilla/WebBrowserPersistDocumentParent.h"
 #include "mozilla/widget/ScreenManager.h"
 #include "mozilla/Unused.h"
 #include "mozilla/HangDetails.h"
 #include "nsAnonymousTemporaryFile.h"
-#include "nsAppDirectoryServiceDefs.h"
 #include "nsAppRunner.h"
 #include "nsCDefaultURIFixup.h"
 #include "nsCExternalHandlerService.h"
 #include "nsCOMPtr.h"
 #include "nsChromeRegistryChrome.h"
 #include "nsConsoleMessage.h"
 #include "nsConsoleService.h"
 #include "nsContentUtils.h"
 #include "nsDebugImpl.h"
-#include "nsDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsEmbedCID.h"
 #include "nsFrameLoader.h"
 #include "nsFrameMessageManager.h"
 #include "nsHashPropertyBag.h"
 #include "nsIAlertsService.h"
 #include "nsIClipboard.h"
 #include "nsICookie.h"
@@ -211,20 +209,16 @@
 #include "nsLayoutStylesheetCache.h"
 
 #include "mozilla/Sprintf.h"
 
 #ifdef MOZ_WEBRTC
 #include "signaling/src/peerconnection/WebrtcGlobalParent.h"
 #endif
 
-#if defined(XP_MACOSX)
-#include "nsMacUtilsImpl.h"
-#endif
-
 #if defined(ANDROID) || defined(LINUX)
 #include "nsSystemInfo.h"
 #endif
 
 #if defined(XP_LINUX)
 #include "mozilla/Hal.h"
 #endif
 
@@ -610,20 +604,16 @@ static const char* sObserverTopics[] = {
   "cacheservice:empty-cache",
   "intl:app-locales-changed",
   "intl:requested-locales-changed",
   "cookie-changed",
   "private-cookie-changed",
   "clear-site-data-reload-needed",
 };
 
-#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
-bool ContentParent::sEarlySandboxInit = false;
-#endif
-
 // PreallocateProcess is called by the PreallocatedProcessManager.
 // ContentParent then takes this process back within GetNewOrUsedBrowserProcess.
 /*static*/ already_AddRefed<ContentParent>
 ContentParent::PreallocateProcess()
 {
   RefPtr<ContentParent> process =
     new ContentParent(/* aOpener = */ nullptr,
                       NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
@@ -2135,130 +2125,16 @@ ContentParent::DestroyTestShell(TestShel
 
 TestShellParent*
 ContentParent::GetTestShellSingleton()
 {
   PTestShellParent* p = LoneManagedOrNullAsserts(ManagedPTestShellParent());
   return static_cast<TestShellParent*>(p);
 }
 
-#ifdef XP_MACOSX
-void
-ContentParent::AppendSandboxParams(std::vector<std::string> &aArgs)
-{
-  nsCOMPtr<nsIProperties>
-    directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
-  if (!directoryService) {
-    MOZ_CRASH("Failed to get the directory service");
-  }
-
-  // Indicates the child should startup the sandbox
-  aArgs.push_back("-sbStartup");
-
-  // The content sandbox level
-  int contentSandboxLevel =
-    Preferences::GetInt("security.sandbox.content.level");
-  std::ostringstream os;
-  os << contentSandboxLevel;
-  std::string contentSandboxLevelString = os.str();
-  aArgs.push_back("-sbLevel");
-  aArgs.push_back(contentSandboxLevelString);
-
-  // Sandbox logging
-  if (Preferences::GetBool("security.sandbox.logging.enabled") ||
-      PR_GetEnv("MOZ_SANDBOX_LOGGING")) {
-    aArgs.push_back("-sbLogging");
-  }
-
-  // For file content processes
-  if (GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE)) {
-    aArgs.push_back("-sbAllowFileAccess");
-  }
-
-  // Audio access
-  if (!Preferences::GetBool("media.cubeb.sandbox")) {
-    aArgs.push_back("-sbAllowAudio");
-  }
-
-  // Windowserver access
-  if (!Preferences::GetBool("security.sandbox.content.mac.disconnect-windowserver")) {
-    aArgs.push_back("-sbAllowWindowServer");
-  }
-
-  // .app path (normalized)
-  nsAutoCString appPath;
-  if (!nsMacUtilsImpl::GetAppPath(appPath)) {
-    MOZ_CRASH("Failed to get app dir paths");
-  }
-  aArgs.push_back("-sbAppPath");
-  aArgs.push_back(appPath.get());
-
-  // TESTING_READ_PATH1
-  nsAutoCString testingReadPath1;
-  Preferences::GetCString("security.sandbox.content.mac.testing_read_path1",
-                          testingReadPath1);
-  if (!testingReadPath1.IsEmpty()) {
-    aArgs.push_back("-sbTestingReadPath");
-    aArgs.push_back(testingReadPath1.get());
-  }
-
-  // TESTING_READ_PATH2
-  nsAutoCString testingReadPath2;
-  Preferences::GetCString("security.sandbox.content.mac.testing_read_path2",
-                          testingReadPath2);
-  if (!testingReadPath2.IsEmpty()) {
-    aArgs.push_back("-sbTestingReadPath");
-    aArgs.push_back(testingReadPath2.get());
-  }
-
-  // TESTING_READ_PATH3, TESTING_READ_PATH4. In development builds,
-  // these are used to whitelist the repo dir and object dir respectively.
-  nsresult rv;
-  if (mozilla::IsDevelopmentBuild()) {
-    // Repo dir
-    nsCOMPtr<nsIFile> repoDir;
-    rv = mozilla::GetRepoDir(getter_AddRefs(repoDir));
-    if (NS_FAILED(rv)) {
-      MOZ_CRASH("Failed to get path to repo dir");
-    }
-    nsCString repoDirPath;
-    Unused << repoDir->GetNativePath(repoDirPath);
-    aArgs.push_back("-sbTestingReadPath");
-    aArgs.push_back(repoDirPath.get());
-
-    // Object dir
-    nsCOMPtr<nsIFile> objDir;
-    rv = mozilla::GetObjDir(getter_AddRefs(objDir));
-    if (NS_FAILED(rv)) {
-      MOZ_CRASH("Failed to get path to build object dir");
-    }
-    nsCString objDirPath;
-    Unused << objDir->GetNativePath(objDirPath);
-    aArgs.push_back("-sbTestingReadPath");
-    aArgs.push_back(objDirPath.get());
-  }
-
-  // DEBUG_WRITE_DIR
-#ifdef DEBUG
-  // When a content process dies intentionally (|NoteIntentionalCrash|), for
-  // tests it wants to log that it did this. Allow writing to this location
-  // that the testrunner wants.
-  char *bloatLog = PR_GetEnv("XPCOM_MEM_BLOAT_LOG");
-  if (bloatLog != nullptr) {
-    // |bloatLog| points to a specific file, but we actually write to a sibling
-    // of that path.
-    nsAutoCString bloatDirectoryPath =
-      nsMacUtilsImpl::GetDirectoryPath(bloatLog);
-    aArgs.push_back("-sbDebugWriteDir");
-    aArgs.push_back(bloatDirectoryPath.get());
-  }
-#endif // DEBUG
-}
-#endif // XP_MACOSX
-
 bool
 ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */)
 {
   AUTO_PROFILER_LABEL("ContentParent::LaunchSubprocess", OTHER);
 
   if (!ContentProcessManager::GetSingleton()) {
     // Shutdown has begun, we shouldn't spawn any more child processes.
     return false;
@@ -2337,25 +2213,16 @@ ContentParent::LaunchSubprocess(ProcessP
   nsPrintfCString schedulerPrefs = Scheduler::GetPrefs();
   extraArgs.push_back("-schedulerPrefs");
   extraArgs.push_back(schedulerPrefs.get());
 
   if (gSafeMode) {
     extraArgs.push_back("-safeMode");
   }
 
-#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
-  // If we're launching a middleman process for a
-  // recording or replay, start the sandbox later.
-  if (sEarlySandboxInit && IsContentSandboxEnabled() &&
-      !IsRecordingOrReplaying()) {
-    AppendSandboxParams(extraArgs);
-  }
-#endif
-
   nsCString parentBuildID(mozilla::PlatformBuildID());
   extraArgs.push_back("-parentBuildID");
   extraArgs.push_back(parentBuildID.get());
 
   // Specify whether the process is recording or replaying an execution.
   if (mRecordReplayState != eNotRecordingOrReplaying) {
     nsPrintfCString buf("%d", mRecordReplayState == eRecording
                               ? (int) recordreplay::ProcessKind::MiddlemanRecording
@@ -2465,27 +2332,16 @@ ContentParent::ContentParent(ContentPare
   // channel. Generally only applies to the situation where we get caught in
   // a deadlock with the plugin process when sending CPOWs.
   GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
 #endif
 
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   bool isFile = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE);
   mSubprocess = new ContentProcessHost(this, isFile);
-
-#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
-  // sEarlySandboxInit is statically initialized to false.
-  // Once we've set it to true due to the pref, avoid checking the
-  // pref on subsequent calls. As a result, changing the earlyinit
-  // pref requires restarting the browser to take effect.
-  if (!ContentParent::sEarlySandboxInit) {
-    ContentParent::sEarlySandboxInit =
-      Preferences::GetBool("security.sandbox.content.mac.earlyinit");
-  }
-#endif
 }
 
 ContentParent::~ContentParent()
 {
   if (mForceKillTimer) {
     mForceKillTimer->Cancel();
   }
 
@@ -2746,25 +2602,16 @@ ContentParent::InitInternal(ProcessPrior
   MaybeFileDesc brokerFd = void_t();
   // XXX: Checking the pref here makes it possible to enable/disable sandboxing
   // during an active session. Currently the pref is only used for testing
   // purpose. If the decision is made to permanently rely on the pref, this
   // should be changed so that it is required to restart firefox for the change
   // of value to take effect.
   shouldSandbox = IsContentSandboxEnabled();
 
-#ifdef XP_MACOSX
-  // If the sandbox was initialized during content process
-  // startup, we must not send the SetProcessSandbox message.
-  // If early startup was pref'd off or the process is a
-  // middleman process, send SetProcessSandbox now.
-  shouldSandbox = shouldSandbox &&
-    (!sEarlySandboxInit || IsRecordingOrReplaying());
-#endif
-
 #ifdef XP_LINUX
   if (shouldSandbox) {
     MOZ_ASSERT(!mSandboxBroker);
     bool isFileProcess = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE);
     UniquePtr<SandboxBroker::Policy> policy =
       sSandboxBrokerPolicyFactory->GetContentPolicy(Pid(), isFileProcess);
     if (policy) {
       brokerFd = FileDescriptor();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -1257,18 +1257,16 @@ public:
 
   virtual mozilla::ipc::IPCResult
   RecvStoreUserInteractionAsPermission(const Principal& aPrincipal) override;
 
   // Notify the ContentChild to enable the input event prioritization when
   // initializing.
   void MaybeEnableRemoteInputEventQueue();
 
-  void AppendSandboxParams(std::vector<std::string>& aArgs);
-
 public:
   void SendGetFilesResponseAndForget(const nsID& aID,
                                      const GetFilesResponseResult& aResult);
 
   bool SendRequestMemoryReport(const uint32_t& aGeneration,
                                const bool& aAnonymize,
                                const bool& aMinimizeMemoryUsage,
                                const MaybeFileDesc& aDMDFile) override;
@@ -1384,23 +1382,16 @@ private:
   nsTHashtable<nsCStringHashKey> mActivePermissionKeys;
 
   nsTArray<nsCString> mBlobURLs;
 
   UniquePtr<mozilla::ipc::CrashReporterHost> mCrashReporter;
 
   static uint64_t sNextTabParentId;
   static nsDataHashtable<nsUint64HashKey, TabParent*> sNextTabParents;
-
-#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
-  // When set to true, indicates that content processes should
-  // initialize their sandbox during startup instead of waiting
-  // for the SetProcessSandbox IPDL message.
-  static bool sEarlySandboxInit;
-#endif
 };
 
 } // namespace dom
 } // namespace mozilla
 
 class ParentIdleListener : public nsIObserver
 {
   friend class mozilla::dom::ContentParent;
--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -9,17 +9,16 @@
 #include "ContentProcess.h"
 #include "base/shared_memory.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Scheduler.h"
 #include "mozilla/recordreplay/ParentIPC.h"
 
 #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
 #include <stdlib.h>
-#include "mozilla/Sandbox.h"
 #endif
 
 #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
 #include "mozilla/SandboxSettings.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #endif
@@ -292,26 +291,17 @@ ContentProcess::Init(int aArgc, char* aA
                 *parentBuildID,
                 IOThreadChild::channel(),
                 *childID,
                 *isForBrowser);
 
   mXREEmbed.Start();
 #if (defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
   mContent.SetProfileDir(profileDir);
-#if defined(DEBUG)
-  // For WebReplay middleman processes, the sandbox is
-  // started after receiving the SetProcessSandbox message.
-  if (IsContentSandboxEnabled() &&
-      Preferences::GetBool("security.sandbox.content.mac.earlyinit") &&
-      !recordreplay::IsMiddleman()) {
-    AssertMacSandboxEnabled();
-  }
-#endif /* DEBUG */
-#endif /* XP_MACOSX && MOZ_CONTENT_SANDBOX */
+#endif
 
 #if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
   SetUpSandboxEnvironment();
 #endif
 
   return true;
 }
 
--- a/dom/media/tests/mochitest/identity/test_fingerprints.html
+++ b/dom/media/tests/mochitest/identity/test_fingerprints.html
@@ -1,122 +1,91 @@
 <html>
 <head>
 <meta charset="utf-8" />
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript">var scriptRelativePath = "../";</script>
+<script type="application/javascript" src="../pc.js"></script>
 </head>
 <body>
-  <script class="testbody" type="application/javascript">
-'use strict';
+<script class="testbody" type="application/javascript">
+createHTML({ title: "Test multiple identity fingerprints",  bug: "1005152" });
 
 // here we call the identity provider directly
-function getIdentityAssertion(fpArray) {
-  var Cu = SpecialPowers.Cu;
-  var rtcid = Cu.import('resource://gre/modules/media/IdpSandbox.jsm');
-  var sandbox = new rtcid.IdpSandbox('example.com', 'idp.js', window);
-  return sandbox.start()
-    .then(idp => SpecialPowers.wrap(idp)
-                   .generateAssertion(JSON.stringify({ fingerprint: fpArray }),
-                                      'https://example.com',
-                                      {}))
-    .then(assertion => {
-      assertion = SpecialPowers.wrap(assertion);
-      var assertionString = btoa(JSON.stringify(assertion));
-      sandbox.stop();
-      return assertionString;
-    });
+async function getIdentityAssertion(fingerprint) {
+  const {Cu} = SpecialPowers;
+  const rtcid = Cu.import('resource://gre/modules/media/IdpSandbox.jsm');
+  const sandbox = new rtcid.IdpSandbox('example.com', 'idp.js', window);
+  const idp = SpecialPowers.wrap(await sandbox.start());
+  const assertion = SpecialPowers.wrap(await
+      idp.generateAssertion(JSON.stringify({ fingerprint }),
+                            'https://example.com',
+                            {}));
+  const assertionString = btoa(JSON.stringify(assertion));
+  sandbox.stop();
+  return assertionString;
 }
 
 // This takes a real fingerprint and makes some extra bad ones.
-function makeFingerprints(algo, digest) {
-  var fingerprints = [];
-  fingerprints.push({ algorithm: algo, digest: digest });
+function makeFingerprints(algorithm, digest) {
+  const fingerprints = [];
+  fingerprints.push({ algorithm, digest });
   for (var i = 0; i < 3; ++i) {
     fingerprints.push({
-      algorithm: algo,
+      algorithm,
       digest: digest.replace(/:./g, ':' + i.toString(16))
     });
   }
   return fingerprints;
 }
 
-var fingerprintRegex = /^a=fingerprint:(\S+) (\S+)/m;
-var identityRegex = /^a=identity:(\S+)/m;
+const fingerprintRegex = /^a=fingerprint:(\S+) (\S+)/m;
+const identityRegex = /^a=identity:(\S+)/m;
 
 function fingerprintSdp(fingerprints) {
   return fingerprints.map(fp => 'a=fInGeRpRiNt:' + fp.algorithm +
                                 ' ' + fp.digest + '\n').join('');
 }
 
 // Firefox only uses a single fingerprint.
 // That doesn't mean we have it create SDP that describes two.
 // This function synthesizes that SDP and tries to set it.
-function testMultipleFingerprints() {
+
+runNetworkTest(async () => {
   // this one fails setRemoteDescription if the identity is not good
-  var pcStrict = new RTCPeerConnection({ peerIdentity: 'someone@example.com'});
+  const pcStrict = new RTCPeerConnection({ peerIdentity: 'someone@example.com'});
   // this one will be manually tweaked to have two fingerprints
-  var pcDouble = new RTCPeerConnection({});
-
-  var offer, match, fingerprints;
-
-  var fail = msg =>
-      (e => ok(false, 'error in ' + msg + ': ' +
-               (e.message ? (e.message + '\n' + e.stack) : e)));
-
-  navigator.mediaDevices.getUserMedia({ video: true })
-    .then(stream => {
-      ok(stream, 'Got test stream');
-      pcDouble.addStream(stream);
-      return pcDouble.createOffer();
-    })
-    .then(o => {
-      offer = o;
-      ok(offer, 'Got offer');
-
-      match = offer.sdp.match(fingerprintRegex);
-      if (!match) {
-        throw new Error('No fingerprint in offer SDP');
-      }
-      fingerprints = makeFingerprints(match[1], match[2]);
-      return getIdentityAssertion(fingerprints);
-    })
-    .then(assertion => {
-      ok(assertion, 'Should have assertion');
+  const pcDouble = new RTCPeerConnection({});
 
-      var sdp = offer.sdp.slice(0, match.index) +
-          'a=identity:' + assertion + '\n' +
-          fingerprintSdp(fingerprints.slice(1)) +
-          offer.sdp.slice(match.index);
+  const stream = await getUserMedia({ video: true });
+  ok(stream, 'Got test stream');
+  const [track] = stream.getTracks();
+  pcDouble.addTrack(track, stream);
+  try {
+    const offer = await pcDouble.createOffer();
+    ok(offer, 'Got offer');
+    const match = offer.sdp.match(fingerprintRegex);
+    if (!match) {
+      throw new Error('No fingerprint in offer SDP');
+    }
+    const fingerprints = makeFingerprints(match[1], match[2]);
+    const assertion = await getIdentityAssertion(fingerprints);
+    ok(assertion, 'Should have assertion');
 
-      return pcStrict.setRemoteDescription({ type: 'offer', sdp });
-    })
-    .then(() => {
-      ok(true, 'Modified fingerprints were accepted');
-    }, error => {
-      var e = SpecialPowers.wrap(error);
-      ok(false, 'error in test: ' +
-         (e.message ? (e.message + '\n' + e.stack) : e));
-    })
-    .then(() => {
-      pcStrict.close();
-      pcDouble.close();
-      SimpleTest.finish();
-    });
-}
+    const sdp = offer.sdp.slice(0, match.index) +
+        'a=identity:' + assertion + '\n' +
+        fingerprintSdp(fingerprints.slice(1)) +
+        offer.sdp.slice(match.index);
 
-SimpleTest.waitForExplicitFinish();
-SpecialPowers.pushPrefEnv({
-  set: [
-    [ 'media.peerconnection.identity.enabled', true ],
-    // Disable permission to skip prompt when on platforms the use loopback
-    // test devices (these would normally trigger a prompt).
-    [ 'media.navigator.permission.disabled', true ],
-    // Since this test doesn't include head.js or pc.js, we need to set the fake
-    // device pref manually. On platforms where loopback devices are used they
-    // should still take precedence, however on some platforms no prefs would
-    // be set and the test would fail.
-    [ 'media.navigator.streams.fake', true ]
-  ]
-}, testMultipleFingerprints);
+    await pcStrict.setRemoteDescription({ type: 'offer', sdp });
+    ok(true, 'Modified fingerprints were accepted');
+  } catch (error) {
+    const e = SpecialPowers.wrap(error);
+    ok(false, 'error in test: ' +
+       (e.message ? (e.message + '\n' + e.stack) : e));
+  }
+  pcStrict.close();
+  pcDouble.close();
+  track.stop();
+  networkTestFinished();
+});
 </script>
-  </body>
+</body>
 </html>
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -342,16 +342,18 @@ skip-if = (android_version == '18') # an
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_threeUnbundledConnections.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_selftest.html]
 # Bug 1227781: Crash with bogus TURN server.
 [test_peerConnection_bug1227781.html]
 [test_peerConnection_stats.html]
 skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator, Bug 1373858)
+[test_peerConnection_stats_relayProtocol.html]
+skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator, Bug 1373858)
 [test_peerConnection_sender_and_receiver_stats.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_trackless_sender_stats.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_verifyDescriptions.html]
 skip-if = (android_version == '18')
 [test_fingerprinting_resistance.html]
 [test_getUserMedia_nonDefaultRate.html]
--- a/dom/media/tests/mochitest/test_peerConnection_stats.html
+++ b/dom/media/tests/mochitest/test_peerConnection_stats.html
@@ -576,19 +576,18 @@ var PC_LOCAL_TEST_LOCAL_STATS = test => 
 
 var PC_REMOTE_TEST_REMOTE_STATS = test => {
   return waitForSyncedRtcp(test.pcRemote).then(stats => {
     checkExpectedFields(stats);
     pedanticChecks(stats);
   });
 }
 
-var test;
 runNetworkTest(function (options) {
-  test = new PeerConnectionTest(options);
+  const test = new PeerConnectionTest(options);
 
   test.chain.insertAfter("PC_LOCAL_WAIT_FOR_MEDIA_FLOW",
     [PC_LOCAL_TEST_LOCAL_STATS]);
 
   test.chain.insertAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW",
     [PC_REMOTE_TEST_REMOTE_STATS]);
 
   test.setMediaConstraints([{audio: true}, {video: true}],
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_stats_relayProtocol.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="nonTrickleIce.js"></script>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1435789",
+    title: "WebRTC local-candidate relayProtocol stats attribute"
+  });
+var PC_LOCAL_TEST_LOCAL_STATS_RELAYCANDIDATE = test => {
+  return test.pcLocal.getStats().then(stats => {
+    let haveRelayProtocol = {};
+    for (let [k, v] of stats) {
+      if (v.type == "local-candidate") {
+        haveRelayProtocol[v.candidateType + "-" + v.relayProtocol] = v.relayProtocol;
+      }
+    }
+    is(haveRelayProtocol["host-undefined"], undefined, "relayProtocol not set for host candidates");
+    is(haveRelayProtocol["serverreflexive-undefined"], undefined, "relayProtocol not set for serverreflexive candidates");
+    ok(haveRelayProtocol["relayed-udp"], "Has UDP relay candidate");
+    ok(haveRelayProtocol["relayed-tcp"], "Has TCP relay candidate");
+    // TURN/TLS does not work, see https://bugzilla.mozilla.org/show_bug.cgi?id=1323439
+    // With TURN/TLS working, we should have exactly five entries in haveRelayProtocol.
+    todo(haveRelayProtocol["relayed-tls"], "Has TLS relay candidate. See https://bugzilla.mozilla.org/show_bug.cgi?id=1323439");
+    is(Object.keys(haveRelayProtocol).length, 4, "All candidate types are accounted for");
+  });
+}
+
+runNetworkTest(options => {
+  // uses NAT simulator in order to get srflx candidates.
+  SpecialPowers.pushPrefEnv(
+    {
+      'set': [
+        ['media.peerconnection.nat_simulator.filtering_type', 'ENDPOINT_INDEPENDENT'],
+        ['media.peerconnection.nat_simulator.mapping_type', 'ENDPOINT_INDEPENDENT']
+      ]
+    }, function (options) {
+      const test = new PeerConnectionTest(options);
+      makeOffererNonTrickle(test.chain);
+      makeAnswererNonTrickle(test.chain);
+
+      test.chain.removeAfter("PC_LOCAL_WAIT_FOR_MEDIA_FLOW");
+      test.chain.append([PC_LOCAL_TEST_LOCAL_STATS_RELAYCANDIDATE]);
+
+      test.setMediaConstraints([{ audio: true }], [{ audio: true }]);
+      test.run();
+    })
+}, { useIceServer: true });
+</script>
+</pre>
+</body>
+</html>
--- a/dom/media/webrtc/WebrtcGlobal.h
+++ b/dom/media/webrtc/WebrtcGlobal.h
@@ -223,28 +223,30 @@ struct ParamTraits<mozilla::dom::RTCIceC
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mCandidateId);
     WriteParam(aMsg, aParam.mCandidateType);
     WriteParam(aMsg, aParam.mComponentId);
     WriteParam(aMsg, aParam.mIpAddress);
     WriteParam(aMsg, aParam.mMozLocalTransport);
+    WriteParam(aMsg, aParam.mRelayProtocol);
     WriteParam(aMsg, aParam.mPortNumber);
     WriteParam(aMsg, aParam.mTransport);
     WriteRTCStats(aMsg, aParam);
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mCandidateId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mCandidateType)) ||
         !ReadParam(aMsg, aIter, &(aResult->mComponentId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIpAddress)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMozLocalTransport)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mRelayProtocol)) ||
         !ReadParam(aMsg, aIter, &(aResult->mPortNumber)) ||
         !ReadParam(aMsg, aIter, &(aResult->mTransport)) ||
         !ReadRTCStats(aMsg, aIter, aResult)) {
       return false;
     }
 
     return true;
  }
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -150,17 +150,18 @@ enum RTCStatsIceCandidateType {
   "relayed"
 };
 
 dictionary RTCIceCandidateStats : RTCStats {
   DOMString componentId;
   DOMString candidateId;
   DOMString ipAddress;
   DOMString transport;
-  DOMString mozLocalTransport; // needs standardization
+  DOMString mozLocalTransport; // obsoleted by relayProtocol
+  DOMString relayProtocol;
   long portNumber;
   RTCStatsIceCandidateType candidateType;
 };
 
 dictionary RTCCodecStats : RTCStats {
   unsigned long payloadType;       // As used in RTP encoding.
   DOMString codec;                 // video/vp8 or equivalent
   unsigned long clockRate;
--- a/ipc/app/MozillaRuntimeMain.cpp
+++ b/ipc/app/MozillaRuntimeMain.cpp
@@ -4,33 +4,21 @@
  * 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/. */
 
 #include "../contentproc/plugin-container.cpp"
 
 #include "mozilla/Bootstrap.h"
 #include "mozilla/WindowsDllBlocklist.h"
 
-#ifdef XP_MACOSX
-#include "mozilla/Sandbox.h"
-#endif
-
 using namespace mozilla;
 
 int
 main(int argc, char *argv[])
 {
-#ifdef XP_MACOSX
-  std::string err;
-  if (!mozilla::EarlyStartMacSandboxIfEnabled(argc, argv, err)) {
-    fprintf(stderr, "Sandbox error: %s\n", err.c_str());
-    MOZ_CRASH("Sandbox initialization failed");
-  }
-#endif
-
 #ifdef HAS_DLL_BLOCKLIST
   DllBlocklist_Initialize(eDllBlocklistInitFlagIsChildProcess);
 #endif
 
   Bootstrap::UniquePtr bootstrap = GetBootstrap();
   if (!bootstrap) {
     return 2;
   }
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -544,22 +544,16 @@ AddAppDirToCommandLine(std::vector<std::
 
 #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
       // Full path to the profile dir
       nsCOMPtr<nsIFile> profileDir;
       rv = directoryService->Get(NS_APP_USER_PROFILE_50_DIR,
                                  NS_GET_IID(nsIFile),
                                  getter_AddRefs(profileDir));
       if (NS_SUCCEEDED(rv)) {
-        // If the profile doesn't exist, normalization will
-        // fail. But we don't return an error here because some
-        // tests require startup with a missing profile dir.
-        // For users, almost universally, the profile will be in
-        // the home directory and normalization isn't required.
-        mozilla::Unused << profileDir->Normalize();
         nsAutoCString path;
         MOZ_ALWAYS_SUCCEEDS(profileDir->GetNativePath(path));
         aCmdLine.push_back("-profile");
         aCmdLine.push_back(path.get());
       }
 #endif
     }
   }
--- a/js/src/vm/JSContext-inl.h
+++ b/js/src/vm/JSContext-inl.h
@@ -40,25 +40,25 @@ class ContextChecks
     {
     }
 
     /*
      * Set a breakpoint here (break js::ContextChecks::fail) to debug
      * realm/compartment/zone mismatches.
      */
     static void fail(JS::Realm* r1, JS::Realm* r2, int argIndex) {
-        MOZ_CRASH_UNSAFE_PRINTF("*** Realm mismatch %p vs. %p at argument %d\n",
+        MOZ_CRASH_UNSAFE_PRINTF("*** Realm mismatch %p vs. %p at argument %d",
                                 r1, r2, argIndex);
     }
     static void fail(JS::Compartment* c1, JS::Compartment* c2, int argIndex) {
-        MOZ_CRASH_UNSAFE_PRINTF("*** Compartment mismatch %p vs. %p at argument %d\n",
+        MOZ_CRASH_UNSAFE_PRINTF("*** Compartment mismatch %p vs. %p at argument %d",
                                 c1, c2, argIndex);
     }
     static void fail(JS::Zone* z1, JS::Zone* z2, int argIndex) {
-        MOZ_CRASH_UNSAFE_PRINTF("*** Zone mismatch %p vs. %p at argument %d\n",
+        MOZ_CRASH_UNSAFE_PRINTF("*** Zone mismatch %p vs. %p at argument %d",
                                 z1, z2, argIndex);
     }
 
     void check(JS::Realm* r, int argIndex) {
         if (r && r != realm()) {
             fail(realm(), r, argIndex);
         }
     }
@@ -89,17 +89,17 @@ class ContextChecks
                       mozilla::IsSame<T, JS::Symbol>::value,
                       "Should only be called with JSAtom* or JS::Symbol* argument");
 
 #ifdef DEBUG
         // Atoms which move across zone boundaries need to be marked in the new
         // zone, see JS_MarkCrossZoneId.
         if (zone()) {
             if (!cx->runtime()->gc.atomMarking.atomIsMarked(zone(), thing)) {
-                MOZ_CRASH_UNSAFE_PRINTF("*** Atom not marked for zone %p at argument %d\n",
+                MOZ_CRASH_UNSAFE_PRINTF("*** Atom not marked for zone %p at argument %d",
                                         zone(), argIndex);
             }
         }
 #endif
     }
 
     void check(JSString* str, int argIndex) {
         MOZ_ASSERT(JS::CellIsNotGray(str));
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2670,23 +2670,22 @@ WrapSeparatorTransform(nsDisplayListBuil
   }
 }
 
 // Try to compute a clip rect to bound the contents of the mask item
 // that will be built for |aMaskedFrame|. If we're not able to compute
 // one, return an empty Maybe.
 // The returned clip rect, if there is one, is relative to |aMaskedFrame|.
 static Maybe<nsRect>
-ComputeClipForMaskItem(nsDisplayListBuilder* aBuilder, nsIFrame* aMaskedFrame,
-                       bool aHandleOpacity)
+ComputeClipForMaskItem(nsDisplayListBuilder* aBuilder, nsIFrame* aMaskedFrame)
 {
   const nsStyleSVGReset* svgReset = aMaskedFrame->StyleSVGReset();
 
   nsSVGUtils::MaskUsage maskUsage;
-  nsSVGUtils::DetermineMaskUsage(aMaskedFrame, aHandleOpacity, maskUsage);
+  nsSVGUtils::DetermineMaskUsage(aMaskedFrame, false, maskUsage);
 
   nsPoint offsetToUserSpace = nsLayoutUtils::ComputeOffsetToUserSpace(aBuilder, aMaskedFrame);
   int32_t devPixelRatio = aMaskedFrame->PresContext()->AppUnitsPerDevPixel();
   gfxPoint devPixelOffsetToUserSpace = nsLayoutUtils::PointToGfxPoint(
       offsetToUserSpace, devPixelRatio);
   gfxMatrix cssToDevMatrix = nsSVGUtils::GetCSSPxToDevPxMatrix(aMaskedFrame);
 
   nsPoint toReferenceFrame;
@@ -2930,26 +2929,28 @@ nsIFrame::BuildDisplayListForStackingCon
   if (usingSVGEffects) {
     dirtyRect =
       nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, dirtyRect);
     visibleRect =
       nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, visibleRect);
     aBuilder->EnterSVGEffectsContents(&hoistedScrollInfoItemsStorage);
   }
 
-
-  bool needsActiveOpacityLayer = false;
-  // We build an opacity item if it's not going to be drawn by SVG content, or
-  // SVG effects. SVG effects won't handle the opacity if we want an active
-  // layer (for async animations), see
-  // nsSVGIntegrationsUtils::PaintMaskAndClipPath or
-  // nsSVGIntegrationsUtils::PaintFilter.
-  bool useOpacity = HasVisualOpacity(effectSet) &&
-                    !nsSVGUtils::CanOptimizeOpacity(this) &&
-                    ((needsActiveOpacityLayer = nsDisplayOpacity::NeedsActiveLayer(aBuilder, this)) || !usingSVGEffects);
+  // We build an opacity item if it's not going to be drawn by SVG content.
+  // We could in principle skip creating an nsDisplayOpacity item if
+  // nsDisplayOpacity::NeedsActiveLayer returns false and usingSVGEffects is
+  // true (the nsDisplayFilter/nsDisplayMasksAndClipPaths could handle the
+  // opacity). Since SVG has perf issues where we sometimes spend a lot of
+  // time creating display list items that might be helpful.  We'd need to
+  // restore our mechanism to do that (changed in bug 1482403), and we'd
+  // need to invalidate the frame if the value that would be return from
+  // NeedsActiveLayer was to change, which we don't currently do.
+  bool useOpacity =
+    HasVisualOpacity(effectSet) && !nsSVGUtils::CanOptimizeOpacity(this);
+
   bool useBlendMode = effects->mMixBlendMode != NS_STYLE_BLEND_NORMAL;
   bool useStickyPosition = disp->mPosition == NS_STYLE_POSITION_STICKY &&
     IsScrollFrameActive(aBuilder,
                         nsLayoutUtils::GetNearestScrollableFrame(GetParent(),
                         nsLayoutUtils::SCROLLABLE_SAME_DOC |
                         nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN));
   bool useFixedPosition = disp->mPosition == NS_STYLE_POSITION_FIXED &&
     (nsLayoutUtils::IsFixedPosFrameInDisplayPort(this) || BuilderHasScrolledClip(aBuilder));
@@ -3011,17 +3012,17 @@ nsIFrame::BuildDisplayListForStackingCon
   }
 
   if (clipCapturedBy != ContainerItemType::eNone) {
     clipState.Clear();
   }
 
   Maybe<nsRect> clipForMask;
   if (usingMask) {
-    clipForMask = ComputeClipForMaskItem(aBuilder, this, !useOpacity);
+    clipForMask = ComputeClipForMaskItem(aBuilder, this);
   }
 
   nsDisplayListCollection set(aBuilder);
   {
     DisplayListClipState::AutoSaveRestore nestedClipState(aBuilder);
     nsDisplayListBuilder::AutoInTransformSetter
       inTransformSetter(aBuilder, inTransform);
     nsDisplayListBuilder::AutoEnterFilter
@@ -3190,25 +3191,19 @@ nsIFrame::BuildDisplayListForStackingCon
     if (clipCapturedBy == ContainerItemType::eFilter) {
       clipState.Restore();
     }
     // Revert to the post-filter dirty rect.
     aBuilder->SetVisibleRect(visibleRectOutsideSVGEffects);
 
     // Skip all filter effects while generating glyph mask.
     if (usingFilter && !aBuilder->IsForGenerateGlyphMask()) {
-      // If we are going to create a mask display item, handle opacity effect
-      // in that mask display item; Otherwise, take care of opacity in this
-      // filter display item.
-      bool handleOpacity = !usingMask && !useOpacity;
-
       /* List now emptied, so add the new list to the top. */
-      resultList.AppendToTop(
-        MakeDisplayItem<nsDisplayFilters>(aBuilder, this, &resultList,
-                                          handleOpacity));
+      resultList.AppendToTop(MakeDisplayItem<nsDisplayFilters>(
+        aBuilder, this, &resultList));
     }
 
     if (usingMask) {
       DisplayListClipState::AutoSaveRestore maskClipState(aBuilder);
       // The mask should move with aBuilder->CurrentActiveScrolledRoot(), so
       // that's the ASR we prefer to use for the mask item. However, we can
       // only do this if the mask if clipped with respect to that ASR, because
       // an item always needs to have finite bounds with respect to its ASR.
@@ -3216,19 +3211,18 @@ nsIFrame::BuildDisplayListForStackingCon
       // using containerItemASR, which is the lowest common ancestor clip of
       // the mask's contents. That's not entirely crrect, but it satisfies
       // the base requirement of the ASR system (that items have finite bounds
       // wrt. their ASR).
       const ActiveScrolledRoot* maskASR = clipForMask.isSome()
                                         ? aBuilder->CurrentActiveScrolledRoot()
                                         : containerItemASR;
       /* List now emptied, so add the new list to the top. */
-      resultList.AppendToTop(
-        MakeDisplayItem<nsDisplayMasksAndClipPaths>(aBuilder, this, &resultList,
-                                                    !useOpacity, maskASR));
+      resultList.AppendToTop(MakeDisplayItem<nsDisplayMasksAndClipPaths>(
+        aBuilder, this, &resultList, maskASR));
     }
 
     // Also add the hoisted scroll info items. We need those for APZ scrolling
     // because nsDisplayMasksAndClipPaths items can't build active layers.
     aBuilder->ExitSVGEffectsContents();
     resultList.AppendToTop(&hoistedScrollInfoItemsStorage);
     if (aCreatedContainerItem) {
       *aCreatedContainerItem = false;
@@ -3238,16 +3232,19 @@ nsIFrame::BuildDisplayListForStackingCon
   /* If the list is non-empty and there is CSS group opacity without SVG
    * effects, wrap it up in an opacity item.
    */
   if (useOpacity) {
     // Don't clip nsDisplayOpacity items. We clip their descendants instead.
     // The clip we would set on an element with opacity would clip
     // all descendant content, but some should not be clipped.
     DisplayListClipState::AutoSaveRestore opacityClipState(aBuilder);
+    const bool needsActiveOpacityLayer =
+      nsDisplayOpacity::NeedsActiveLayer(aBuilder, this);
+
     resultList.AppendToTop(
       MakeDisplayItem<nsDisplayOpacity>(aBuilder, this, &resultList,
                                         containerItemASR,
                                         opacityItemForEventsAndPluginsOnly,
                                         needsActiveOpacityLayer));
     if (aCreatedContainerItem) {
       *aCreatedContainerItem = true;
     }
--- a/layout/painting/RetainedDisplayListBuilder.cpp
+++ b/layout/painting/RetainedDisplayListBuilder.cpp
@@ -409,16 +409,23 @@ public:
 
     if (type == DisplayItemType::TYPE_CARET) {
       // The caret can change position while still being owned by the same frame
       // and we don't invalidate in that case. Use the new version since the
       // changed bounds are needed for DLBI.
       return true;
     }
 
+    if (type == DisplayItemType::TYPE_MASK ||
+        type == DisplayItemType::TYPE_FILTER ||
+        type == DisplayItemType::TYPE_SVG_WRAPPER) {
+      // SVG items have some invalidation issues, see bugs 1494110 and 1494663.
+      return true;
+    }
+
     return false;
   }
 
   RetainedDisplayList Finalize()
   {
     for (size_t i = 0; i < mOldDAG.Length(); i++) {
       if (mOldItems[i].IsUsed()) {
         continue;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6534,16 +6534,40 @@ nsDisplayOpacity::ApplyOpacityToChildren
   for (uint32_t i = 0; i < childCount; i++) {
     children[i].item->ApplyOpacity(aBuilder, mOpacity, mClipChain);
   }
 
   mChildOpacityState = ChildOpacityState::Applied;
   return true;
 }
 
+/**
+ * Returns true if this nsDisplayOpacity contains only a filter or a mask item
+ * that has the same frame as the opacity item. In this case the opacity item
+ * can be optimized away.
+ */
+bool
+nsDisplayOpacity::IsEffectsWrapper() const
+{
+  if (mList.Count() != 1) {
+    return false;
+  }
+
+  const nsDisplayItem* item = mList.GetBottom();
+
+  if (item->Frame() != mFrame) {
+    // The effect item needs to have the same frame as the opacity item.
+    return false;
+  }
+
+  const DisplayItemType type = item->GetType();
+  return type == DisplayItemType::TYPE_MASK ||
+         type == DisplayItemType::TYPE_FILTER;
+}
+
 bool
 nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
 {
   if (mFrame->GetPrevContinuation() || mFrame->GetNextContinuation() ||
       mFrame->HasAnyStateBits(NS_FRAME_PART_OF_IBSPLIT)) {
     // If we've been split, then we might need to merge, so
     // don't flatten us away.
     return false;
@@ -6556,16 +6580,23 @@ nsDisplayOpacity::ShouldFlattenAway(nsDi
     // might trigger repainting).
     return false;
   }
 
   if (mList.IsEmpty()) {
     return false;
   }
 
+  if (IsEffectsWrapper()) {
+    MOZ_ASSERT(nsSVGIntegrationUtils::UsingEffectsForFrame(mFrame));
+    static_cast<nsDisplayEffectsBase*>(mList.GetBottom())->SetHandleOpacity();
+    mChildOpacityState = ChildOpacityState::Applied;
+    return true;
+  }
+
   // Return true if we successfully applied opacity to child items, or if
   // WebRender is not in use. In the latter case, the opacity gets flattened and
   // applied during layer building.
   return ApplyOpacityToChildren(aBuilder) || !gfxVars::UseWebRender();
 }
 
 nsDisplayItem::LayerState
 nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
@@ -9440,35 +9471,33 @@ nsCharClipDisplayItem::ComputeInvalidati
     aInvalidRegion->Or(oldRect, newRect);
   }
 }
 
 nsDisplayEffectsBase::nsDisplayEffectsBase(
   nsDisplayListBuilder* aBuilder,
   nsIFrame* aFrame,
   nsDisplayList* aList,
-  bool aHandleOpacity,
   const ActiveScrolledRoot* aActiveScrolledRoot,
   bool aClearClipChain)
   : nsDisplayWrapList(aBuilder,
                       aFrame,
                       aList,
                       aActiveScrolledRoot,
                       aClearClipChain)
-  , mHandleOpacity(aHandleOpacity)
+  , mHandleOpacity(false)
 {
   MOZ_COUNT_CTOR(nsDisplayEffectsBase);
 }
 
 nsDisplayEffectsBase::nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
                                            nsIFrame* aFrame,
-                                           nsDisplayList* aList,
-                                           bool aHandleOpacity)
+                                           nsDisplayList* aList)
   : nsDisplayWrapList(aBuilder, aFrame, aList)
-  , mHandleOpacity(aHandleOpacity)
+  , mHandleOpacity(false)
 {
   MOZ_COUNT_CTOR(nsDisplayEffectsBase);
 }
 
 nsRegion
 nsDisplayEffectsBase::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                                       bool* aSnap) const
 {
@@ -9507,17 +9536,19 @@ nsDisplayEffectsBase::ComputeInvalidatio
   const nsDisplayItemGeometry* aGeometry,
   nsRegion* aInvalidRegion) const
 {
   auto* geometry = static_cast<const nsDisplaySVGEffectGeometry*>(aGeometry);
   bool snap;
   nsRect bounds = GetBounds(aBuilder, &snap);
   if (geometry->mFrameOffsetToReferenceFrame != ToReferenceFrame() ||
       geometry->mUserSpaceOffset != UserSpaceOffset() ||
-      !geometry->mBBox.IsEqualInterior(BBoxInUserSpace())) {
+      !geometry->mBBox.IsEqualInterior(BBoxInUserSpace()) ||
+      geometry->mOpacity != mFrame->StyleEffects()->mOpacity ||
+      geometry->mHandleOpacity != ShouldHandleOpacity()) {
     // Filter and mask output can depend on the location of the frame's user
     // space and on the frame's BBox. We need to invalidate if either of these
     // change relative to the reference frame.
     // Invalidations from our inactive layer manager are not enough to catch
     // some of these cases because filters can produce output even if there's
     // nothing in the filter input.
     aInvalidRegion->Or(bounds, geometry->mBounds);
   }
@@ -9628,22 +9659,20 @@ ComputeMaskGeometry(PaintFramesParams& a
   IntRect result = ComputeClipExtsInDeviceSpace(ctx);
   aParams.maskRect = result;
 }
 
 nsDisplayMasksAndClipPaths::nsDisplayMasksAndClipPaths(
                               nsDisplayListBuilder* aBuilder,
                               nsIFrame* aFrame,
                               nsDisplayList* aList,
-                              bool aHandleOpacity,
                               const ActiveScrolledRoot* aActiveScrolledRoot)
   : nsDisplayEffectsBase(aBuilder,
                          aFrame,
                          aList,
-                         aHandleOpacity,
                          aActiveScrolledRoot,
                          true)
 {
   MOZ_COUNT_CTOR(nsDisplayMasksAndClipPaths);
 
   nsPresContext* presContext = mFrame->PresContext();
   uint32_t flags =
     aBuilder->GetBackgroundPaintFlags() | nsCSSRendering::PAINTBG_MASK_IMAGE;
@@ -9831,21 +9860,16 @@ nsDisplayMasksAndClipPaths::ComputeInval
   nsDisplayEffectsBase::ComputeInvalidationRegion(
     aBuilder, aGeometry, aInvalidRegion);
 
   auto* geometry =
     static_cast<const nsDisplayMasksAndClipPathsGeometry*>(aGeometry);
   bool snap;
   nsRect bounds = GetBounds(aBuilder, &snap);
 
-  if (mFrame->StyleEffects()->mOpacity != geometry->mOpacity ||
-      mHandleOpacity != geometry->mHandleOpacity) {
-    aInvalidRegion->Or(*aInvalidRegion, bounds);
-  }
-
   if (mDestRects.Length() != geometry->mDestRects.Length()) {
     aInvalidRegion->Or(bounds, geometry->mBounds);
   } else {
     for (size_t i = 0; i < mDestRects.Length(); i++) {
       if (!mDestRects[i].IsEqualInterior(geometry->mDestRects[i])) {
         aInvalidRegion->Or(bounds, geometry->mBounds);
         break;
       }
@@ -10027,17 +10051,17 @@ nsDisplayMasksAndClipPaths::GetClipWithR
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplayMasksAndClipPaths::PrintEffects(nsACString& aTo)
 {
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
   bool first = true;
   aTo += " effects=(";
-  if (mFrame->StyleEffects()->mOpacity != 1.0f && mHandleOpacity) {
+  if (mHandleOpacity) {
     first = false;
     aTo += nsPrintfCString("opacity(%f)", mFrame->StyleEffects()->mOpacity);
   }
   nsSVGClipPathFrame* clipPathFrame;
   // XXX Check return value?
   SVGObserverUtils::GetAndObserveClipPath(firstFrame, &clipPathFrame);
   if (clipPathFrame) {
     if (!first) {
@@ -10064,19 +10088,18 @@ nsDisplayMasksAndClipPaths::PrintEffects
     aTo += "mask";
   }
   aTo += ")";
 }
 #endif
 
 nsDisplayFilters::nsDisplayFilters(nsDisplayListBuilder* aBuilder,
                                    nsIFrame* aFrame,
-                                   nsDisplayList* aList,
-                                   bool aHandleOpacity)
-  : nsDisplayEffectsBase(aBuilder, aFrame, aList, aHandleOpacity)
+                                   nsDisplayList* aList)
+  : nsDisplayEffectsBase(aBuilder, aFrame, aList)
   , mEffectsBounds(aFrame->GetVisualOverflowRectRelativeToSelf())
 {
   MOZ_COUNT_CTOR(nsDisplayFilters);
 }
 
 already_AddRefed<Layer>
 nsDisplayFilters::BuildLayer(
   nsDisplayListBuilder* aBuilder,
@@ -10315,17 +10338,17 @@ nsDisplayFilters::CreateWebRenderCommand
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplayFilters::PrintEffects(nsACString& aTo)
 {
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
   bool first = true;
   aTo += " effects=(";
-  if (mFrame->StyleEffects()->mOpacity != 1.0f && mHandleOpacity) {
+  if (mHandleOpacity) {
     first = false;
     aTo += nsPrintfCString("opacity(%f)", mFrame->StyleEffects()->mOpacity);
   }
   // We may exist for a mix of CSS filter functions and/or references to SVG
   // filters.  If we have invalid references to SVG filters then we paint
   // nothing, but otherwise we will apply one or more filters.
   if (SVGObserverUtils::GetAndObserveFilters(firstFrame, nullptr) !=
         SVGObserverUtils::eHasRefsSomeInvalid) {
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -5785,16 +5785,17 @@ public:
     const StackingContextHelper& aSc,
     mozilla::layers::WebRenderLayerManager* aManager,
     nsDisplayListBuilder* aDisplayListBuilder) override;
 
   float GetOpacity() const { return mOpacity; }
 
 private:
   bool ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder);
+  bool IsEffectsWrapper() const;
 
   float mOpacity;
   bool mForEventsAndPluginsOnly : 1;
   enum class ChildOpacityState : uint8_t
   {
     // Our child list has changed since the last time ApplyOpacityToChildren was
     // called.
     Unknown,
@@ -6683,23 +6684,21 @@ private:
  * A base class for different effects types.
  */
 class nsDisplayEffectsBase : public nsDisplayWrapList
 {
 public:
   nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
                        nsIFrame* aFrame,
                        nsDisplayList* aList,
-                       bool aHandleOpacity,
                        const ActiveScrolledRoot* aActiveScrolledRoot,
                        bool aClearClipChain = false);
   nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
                        nsIFrame* aFrame,
-                       nsDisplayList* aList,
-                       bool aHandleOpacity);
+                       nsDisplayList* aList);
 
   nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
                        const nsDisplayEffectsBase& aOther)
     : nsDisplayWrapList(aBuilder, aOther)
     , mEffectsBounds(aOther.mEffectsBounds)
     , mHandleOpacity(aOther.mHandleOpacity)
   {
     MOZ_COUNT_CTOR(nsDisplayEffectsBase);
@@ -6711,22 +6710,25 @@ public:
 
   nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                            bool* aSnap) const override;
   void HitTest(nsDisplayListBuilder* aBuilder,
                const nsRect& aRect,
                HitTestState* aState,
                nsTArray<nsIFrame*>* aOutFrames) override;
 
+  void RestoreState() override { mHandleOpacity = false; }
+
   bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
   {
     return false;
   }
 
-  bool ShouldHandleOpacity() { return mHandleOpacity; }
+  void SetHandleOpacity() { mHandleOpacity = true; }
+  bool ShouldHandleOpacity() const { return mHandleOpacity; }
 
   gfxRect BBoxInUserSpace() const;
   gfxPoint UserSpaceOffset() const;
 
   void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                  const nsDisplayItemGeometry* aGeometry,
                                  nsRegion* aInvalidRegion) const override;
 
@@ -6752,17 +6754,16 @@ protected:
 class nsDisplayMasksAndClipPaths : public nsDisplayEffectsBase
 {
 public:
   typedef mozilla::layers::ImageLayer ImageLayer;
 
   nsDisplayMasksAndClipPaths(nsDisplayListBuilder* aBuilder,
                              nsIFrame* aFrame,
                              nsDisplayList* aList,
-                             bool aHandleOpacity,
                              const ActiveScrolledRoot* aActiveScrolledRoot);
   nsDisplayMasksAndClipPaths(nsDisplayListBuilder* aBuilder,
                              const nsDisplayMasksAndClipPaths& aOther)
     : nsDisplayEffectsBase(aBuilder, aOther)
     , mDestRects(aOther.mDestRects)
   {
   }
 
@@ -6864,18 +6865,17 @@ private:
  * Note that the filters may just be simple CSS filter functions.  That is,
  * they won't necessarily be references to SVG 'filter' elements.
  */
 class nsDisplayFilters : public nsDisplayEffectsBase
 {
 public:
   nsDisplayFilters(nsDisplayListBuilder* aBuilder,
                    nsIFrame* aFrame,
-                   nsDisplayList* aList,
-                   bool aHandleOpacity);
+                   nsDisplayList* aList);
 
   nsDisplayFilters(nsDisplayListBuilder* aBuilder,
                    const nsDisplayFilters& aOther)
     : nsDisplayEffectsBase(aBuilder, aOther)
     , mEffectsBounds(aOther.mEffectsBounds)
   {
   }
 
--- a/layout/painting/nsDisplayListInvalidation.cpp
+++ b/layout/painting/nsDisplayListInvalidation.cpp
@@ -126,34 +126,34 @@ nsDisplaySolidColorRegionGeometry::MoveB
 
 nsDisplaySVGEffectGeometry::nsDisplaySVGEffectGeometry(
   nsDisplayEffectsBase* aItem,
   nsDisplayListBuilder* aBuilder)
   : nsDisplayItemGeometry(aItem, aBuilder)
   , mBBox(aItem->BBoxInUserSpace())
   , mUserSpaceOffset(aItem->UserSpaceOffset())
   , mFrameOffsetToReferenceFrame(aItem->ToReferenceFrame())
+  , mOpacity(aItem->Frame()->StyleEffects()->mOpacity)
+  , mHandleOpacity(aItem->ShouldHandleOpacity())
 {
 }
 
 void
 nsDisplaySVGEffectGeometry::MoveBy(const nsPoint& aOffset)
 {
   mBounds.MoveBy(aOffset);
   mFrameOffsetToReferenceFrame += aOffset;
 }
 
 nsDisplayMasksAndClipPathsGeometry::nsDisplayMasksAndClipPathsGeometry(
                                       nsDisplayMasksAndClipPaths* aItem,
                                       nsDisplayListBuilder* aBuilder)
   : nsDisplaySVGEffectGeometry(aItem, aBuilder)
   , nsImageGeometryMixin(aItem, aBuilder)
   , mDestRects(aItem->GetDestRects())
-  , mOpacity(aItem->Frame()->StyleEffects()->mOpacity)
-  , mHandleOpacity(aItem->ShouldHandleOpacity())
 {
 }
 
 nsDisplayFiltersGeometry::nsDisplayFiltersGeometry(nsDisplayFilters* aItem,
                                                    nsDisplayListBuilder* aBuilder)
   : nsDisplaySVGEffectGeometry(aItem, aBuilder)
   , nsImageGeometryMixin(aItem, aBuilder)
 {
--- a/layout/painting/nsDisplayListInvalidation.h
+++ b/layout/painting/nsDisplayListInvalidation.h
@@ -297,34 +297,34 @@ public:
   nsDisplaySVGEffectGeometry(nsDisplayEffectsBase* aItem,
                              nsDisplayListBuilder* aBuilder);
 
   void MoveBy(const nsPoint& aOffset) override;
 
   gfxRect mBBox;
   gfxPoint mUserSpaceOffset;
   nsPoint mFrameOffsetToReferenceFrame;
+  float mOpacity;
+  bool mHandleOpacity;
 };
 
 class nsDisplayMasksAndClipPathsGeometry
   : public nsDisplaySVGEffectGeometry
   , public nsImageGeometryMixin<nsDisplayMasksAndClipPathsGeometry>
 {
 public:
   nsDisplayMasksAndClipPathsGeometry(nsDisplayMasksAndClipPaths* aItem,
                                      nsDisplayListBuilder* aBuilder);
 
   bool InvalidateForSyncDecodeImages() const override
   {
     return ShouldInvalidateToSyncDecodeImages();
   }
 
   nsTArray<nsRect> mDestRects;
-  float mOpacity;
-  bool mHandleOpacity;
 };
 
 class nsDisplayFiltersGeometry
   : public nsDisplaySVGEffectGeometry
   , public nsImageGeometryMixin<nsDisplayFiltersGeometry>
 {
 public:
   nsDisplayFiltersGeometry(nsDisplayFilters* aItem,
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -1151,16 +1151,20 @@ static void ToRTCIceCandidateStats(
     cand.mIpAddress.Construct(
         NS_ConvertASCIItoUTF16(candidate.cand_addr.host.c_str()));
     cand.mPortNumber.Construct(candidate.cand_addr.port);
     cand.mTransport.Construct(
         NS_ConvertASCIItoUTF16(candidate.cand_addr.transport.c_str()));
     if (candidateType == RTCStatsType::Local_candidate) {
       cand.mMozLocalTransport.Construct(
           NS_ConvertASCIItoUTF16(candidate.local_addr.transport.c_str()));
+      if (RTCStatsIceCandidateType(candidate.type) == RTCStatsIceCandidateType::Relayed) {
+        cand.mRelayProtocol.Construct(
+            NS_ConvertASCIItoUTF16(candidate.local_addr.transport.c_str()));
+      }
     }
     report->mIceCandidateStats.Value().AppendElement(cand, fallible);
     if (candidate.trickled) {
       report->mTrickledIceCandidateStats.Value().AppendElement(cand, fallible);
     }
   }
 }
 
--- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
+++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
@@ -975,19 +975,19 @@ static uint32_t GetCandidateIpAndTranspo
     CANDIDATE_BITMASK_UDP = 1,
     CANDIDATE_BITMASK_TCP = 1 << 1,
     CANDIDATE_BITMASK_IPV6 = 1 << 2,
   };
 
   uint32_t res = 0;
 
   nsAutoCString transport;
-  // prefer local transport for local relay candidates
-  if (cand->mMozLocalTransport.WasPassed()) {
-    transport.Assign(NS_ConvertUTF16toUTF8(cand->mMozLocalTransport.Value()));
+  // prefer relay transport for local relay candidates
+  if (cand->mRelayProtocol.WasPassed()) {
+    transport.Assign(NS_ConvertUTF16toUTF8(cand->mRelayProtocol.Value()));
   } else {
     transport.Assign(NS_ConvertUTF16toUTF8(cand->mTransport.Value()));
   }
   if (transport == kNrIceTransportUdp) {
     res |= CANDIDATE_BITMASK_UDP;
   } else if (transport == kNrIceTransportTcp) {
     res |= CANDIDATE_BITMASK_TCP;
   }
--- a/mfbt/tests/moz.build
+++ b/mfbt/tests/moz.build
@@ -4,16 +4,18 @@
 # 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/.
 
 if CONFIG['MOZ_WIDGET_TOOLKIT']:
     TEST_DIRS += [
         'gtest',
     ]
 
+# Important: for these tests to be run, they also need to be added
+# to testing/cppunittest.ini.
 CppUnitTests([
     'TestAlgorithm',
     'TestArray',
     'TestArrayUtils',
     'TestAtomics',
     'TestBinarySearch',
     'TestBloomFilter',
     'TestBufferList',
--- a/security/sandbox/mac/Sandbox.h
+++ b/security/sandbox/mac/Sandbox.h
@@ -40,50 +40,40 @@ typedef struct _MacSandboxPluginInfo {
 
 typedef struct _MacSandboxInfo {
   _MacSandboxInfo()
     : type(MacSandboxType_Default)
     , level(0)
     , hasFilePrivileges(false)
     , hasSandboxedProfile(false)
     , hasAudio(false)
-    , hasWindowServer(false)
     , shouldLog(true)
   {
   }
   _MacSandboxInfo(const struct _MacSandboxInfo& other) = default;
 
   MacSandboxType type;
   int32_t level;
   bool hasFilePrivileges;
   bool hasSandboxedProfile;
   bool hasAudio;
-  bool hasWindowServer;
   MacSandboxPluginInfo pluginInfo;
   std::string appPath;
   std::string appBinaryPath;
   std::string appDir;
   std::string profileDir;
   std::string debugWriteDir;
 
   std::string testingReadPath1;
   std::string testingReadPath2;
   std::string testingReadPath3;
   std::string testingReadPath4;
 
-  std::string parentPort;
-  std::string crashServerPort;
-
   bool shouldLog;
 } MacSandboxInfo;
 
 namespace mozilla {
 
 bool StartMacSandbox(MacSandboxInfo const &aInfo, std::string &aErrorMessage);
-bool EarlyStartMacSandboxIfEnabled(int aArgc, char** aArgv,
-                                   std::string &aErrorMessage);
-#ifdef DEBUG
-void AssertMacSandboxEnabled();
-#endif /* DEBUG */
 
 } // namespace mozilla
 
 #endif // mozilla_Sandbox_h
--- a/security/sandbox/mac/Sandbox.mm
+++ b/security/sandbox/mac/Sandbox.mm
@@ -10,18 +10,16 @@
 // linking to nsCocoaFeatures.mm in XUL.
 
 #include "Sandbox.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <CoreFoundation/CoreFoundation.h>
 
-#include <iostream>
-#include <sstream>
 #include <vector>
 
 #include "mozilla/Assertions.h"
 
 // XXX There are currently problems with the /usr/include/sandbox.h file on
 // some/all of the Macs in Mozilla's build system. Further,
 // sandbox_init_with_parameters is not included in the header.  For the time
 // being (until this problem is resolved), we refer directly to what we need
@@ -221,32 +219,26 @@ bool StartMacSandbox(MacSandboxInfo cons
       params.push_back("SANDBOX_LEVEL_2");
       params.push_back(aInfo.level == 2 ? "TRUE" : "FALSE");
       params.push_back("SANDBOX_LEVEL_3");
       params.push_back(aInfo.level == 3 ? "TRUE" : "FALSE");
       params.push_back("MAC_OS_MINOR");
       params.push_back(macOSMinor.c_str());
       params.push_back("APP_PATH");
       params.push_back(aInfo.appPath.c_str());
+      params.push_back("APP_BINARY_PATH");
+      params.push_back(aInfo.appBinaryPath.c_str());
+      params.push_back("APP_DIR");
+      params.push_back(aInfo.appDir.c_str());
       params.push_back("PROFILE_DIR");
       params.push_back(aInfo.profileDir.c_str());
       params.push_back("HOME_PATH");
       params.push_back(getenv("HOME"));
       params.push_back("HAS_SANDBOXED_PROFILE");
       params.push_back(aInfo.hasSandboxedProfile ? "TRUE" : "FALSE");
-      params.push_back("HAS_WINDOW_SERVER");
-      params.push_back(aInfo.hasWindowServer ? "TRUE" : "FALSE");
-      if (!aInfo.parentPort.empty()) {
-        params.push_back("PARENT_PORT");
-        params.push_back(aInfo.parentPort.c_str());
-      }
-      if (!aInfo.crashServerPort.empty()) {
-        params.push_back("CRASH_PORT");
-        params.push_back(aInfo.crashServerPort.c_str());
-      }
       if (!aInfo.testingReadPath1.empty()) {
         params.push_back("TESTING_READ_PATH1");
         params.push_back(aInfo.testingReadPath1.c_str());
       }
       if (!aInfo.testingReadPath2.empty()) {
         params.push_back("TESTING_READ_PATH2");
         params.push_back(aInfo.testingReadPath2.c_str());
       }
@@ -325,191 +317,9 @@ bool StartMacSandbox(MacSandboxInfo cons
   }
   if (rv) {
     return false;
   }
 
   return true;
 }
 
-/*
- * Fill |aInfo| with content sandbox params parsed from the provided
- * command line arguments. Return false if any sandbox parameters needed
- * for early startup of the sandbox are not present in the arguments.
- */
-bool
-GetContentSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo)
-{
-  // Ensure we find these paramaters in the command
-  // line arguments. Return false if any are missing.
-  bool foundSandboxLevel = false;
-  bool foundValidSandboxLevel = false;
-  bool foundParentPort = false;
-  bool foundAppPath = false;
-
-  // Read access directories used in testing
-  int nTestingReadPaths = 0;
-  std::string testingReadPaths[MAX_TESTING_READ_PATHS] = {};
-
-  // Collect sandbox params from CLI arguments
-  for (int i = 0; i < aArgc; i++) {
-
-    if ((strcmp(aArgv[i], "-sbLevel") == 0) && (i + 1 < aArgc)) {
-      std::stringstream ss(aArgv[i+1]);
-      int level = 0;
-      ss >> level;
-      foundSandboxLevel = true;
-      aInfo.level = level;
-      foundValidSandboxLevel = level > 0 && level <= 3 ? true : false;
-      if (!foundValidSandboxLevel) {
-        break;
-      }
-      i++;
-      continue;
-    }
-
-    if (strcmp(aArgv[i], "-sbLogging") == 0) {
-      aInfo.shouldLog = true;
-      continue;
-    }
-
-    if (strcmp(aArgv[i], "-sbAllowFileAccess") == 0) {
-      aInfo.hasFilePrivileges = true;
-      continue;
-    }
-
-    if (strcmp(aArgv[i], "-sbAllowAudio") == 0) {
-      aInfo.hasAudio = true;
-      continue;
-    }
-
-    if (strcmp(aArgv[i], "-sbAllowWindowServer") == 0) {
-      aInfo.hasWindowServer = true;
-      continue;
-    }
-
-    if ((strcmp(aArgv[i], "-sbAppPath") == 0) && (i + 1 < aArgc)) {
-      foundAppPath = true;
-      aInfo.appPath.assign(aArgv[i+1]);
-      i++;
-      continue;
-    }
-
-    if ((strcmp(aArgv[i], "-sbTestingReadPath") == 0) && (i + 1 < aArgc)) {
-      MOZ_ASSERT(nTestingReadPaths < MAX_TESTING_READ_PATHS);
-      testingReadPaths[nTestingReadPaths] = aArgv[i+1];
-      nTestingReadPaths++;
-      i++;
-      continue;
-    }
-
-    if ((strcmp(aArgv[i], "-profile") == 0) && (i + 1 < aArgc)) {
-      aInfo.hasSandboxedProfile = true;
-      aInfo.profileDir.assign(aArgv[i+1]);
-      i++;
-      continue;
-    }
-
-#ifdef DEBUG
-    if ((strcmp(aArgv[i], "-sbDebugWriteDir") == 0) && (i + 1 < aArgc)) {
-      aInfo.debugWriteDir.assign(aArgv[i+1]);
-      i++;
-      continue;
-    }
-#endif // DEBUG
-
-    // Handle positional arguments
-    if (strstr(aArgv[i], "org.mozilla.machname") != NULL) {
-      foundParentPort = true;
-      aInfo.parentPort.assign(aArgv[i]);
-      continue;
-    }
-
-    if (strstr(aArgv[i], "gecko-crash-server-pipe") != NULL) {
-      aInfo.crashServerPort.assign(aArgv[i]);
-      continue;
-    }
-  }
-
-  if (!foundSandboxLevel) {
-    fprintf(stderr, "Content sandbox disabled due to "
-                    "missing sandbox CLI level parameter.\n");
-    return false;
-  }
-
-  if (!foundValidSandboxLevel) {
-    fprintf(stderr, "Content sandbox disabled due to invalid"
-                    "sandbox level (%d)\n", aInfo.level);
-    return false;
-  }
-
-  if (!foundParentPort) {
-    fprintf(stderr, "Content sandbox disabled due to "
-                    "missing sandbox CLI parent port parameter.\n");
-    return false;
-  }
-
-  if (!foundAppPath) {
-    fprintf(stderr, "Content sandbox disabled due to "
-                    "missing sandbox CLI app path parameter.\n");
-    return false;
-  }
-
-  aInfo.testingReadPath1 = testingReadPaths[0];
-  aInfo.testingReadPath2 = testingReadPaths[1];
-  aInfo.testingReadPath3 = testingReadPaths[2];
-  aInfo.testingReadPath4 = testingReadPaths[3];
-
-  return true;
-}
-
-/*
- * Returns true if no errors were encountered or if early sandbox startup is
- * not enabled for this process. Returns false if an error was encountered.
- */
-bool
-EarlyStartMacSandboxIfEnabled(int aArgc, char** aArgv,
-                              std::string &aErrorMessage)
-{
-  bool earlyStartupEnabled = false;
-
-  // Check for the -sbStartup CLI parameter which
-  // indicates we should start the sandbox now.
-  for (int i = 0; i < aArgc; i++) {
-    if (strcmp(aArgv[i], "-sbStartup") == 0) {
-      earlyStartupEnabled = true;
-      break;
-    }
-  }
-
-  // The sandbox will be started later when/if parent
-  // sends the sandbox startup message. Return true
-  // indicating no errors occurred.
-  if (!earlyStartupEnabled) {
-    return true;
-  }
-
-  MacSandboxInfo info;
-  info.type = MacSandboxType_Content;
-  if (!GetContentSandboxParamsFromArgs(aArgc, aArgv, info)) {
-    return false;
-  }
-
-  return StartMacSandbox(info, aErrorMessage);
-}
-
-#ifdef DEBUG
-/*
- * Ensures that a process sandbox is enabled by attempting to enable
- * a new sandbox policy and ASSERT'ing that this fails. This depends
- * on sandbox_init() failing when called again after a sandbox has
- * already been successfully enabled.
- */
-void
-AssertMacSandboxEnabled()
-{
-  char *errorbuf = NULL;
-  int rv = sandbox_init("(version 1)(deny default)", 0, &errorbuf);
-  MOZ_ASSERT(rv != 0);
-}
-#endif /* DEBUG */
-
 } // namespace mozilla
--- a/security/sandbox/mac/SandboxPolicies.h
+++ b/security/sandbox/mac/SandboxPolicies.h
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #ifndef mozilla_SandboxPolicies_h
 #define mozilla_SandboxPolicies_h
 
-#define MAX_TESTING_READ_PATHS 4
-
 namespace mozilla {
 
 static const char pluginSandboxRules[] = R"SANDBOX_LITERAL(
   (version 1)
 
   (define should-log (param "SHOULD_LOG"))
   (define plugin-binary-path (param "PLUGIN_BINARY_PATH"))
   (define app-path (param "APP_PATH"))
@@ -47,27 +45,26 @@ static const char contentSandboxRules[] 
   (version 1)
 
   (define should-log (param "SHOULD_LOG"))
   (define sandbox-level-1 (param "SANDBOX_LEVEL_1"))
   (define sandbox-level-2 (param "SANDBOX_LEVEL_2"))
   (define sandbox-level-3 (param "SANDBOX_LEVEL_3"))
   (define macosMinorVersion (string->number (param "MAC_OS_MINOR")))
   (define appPath (param "APP_PATH"))
+  (define appBinaryPath (param "APP_BINARY_PATH"))
+  (define appdir-path (param "APP_DIR"))
   (define hasProfileDir (param "HAS_SANDBOXED_PROFILE"))
   (define profileDir (param "PROFILE_DIR"))
-  (define hasWindowServer (param "HAS_WINDOW_SERVER"))
   (define home-path (param "HOME_PATH"))
   (define debugWriteDir (param "DEBUG_WRITE_DIR"))
   (define testingReadPath1 (param "TESTING_READ_PATH1"))
   (define testingReadPath2 (param "TESTING_READ_PATH2"))
   (define testingReadPath3 (param "TESTING_READ_PATH3"))
   (define testingReadPath4 (param "TESTING_READ_PATH4"))
-  (define parentPort (param "PARENT_PORT"))
-  (define crashPort (param "CRASH_PORT"))
 
   (if (string=? should-log "TRUE")
     (deny default)
     (deny default (with no-log)))
   (debug deny)
   ; These are not included in (deny default)
   (deny process-info*)
   ; This isn't available in some older macOS releases.
@@ -79,22 +76,22 @@ static const char contentSandboxRules[] 
   (if (defined? 'file-map-executable)
     (deny file-map-executable))
 
   (if (defined? 'file-map-executable)
     (allow file-map-executable file-read*
       (subpath "/System")
       (subpath "/usr/lib")
       (subpath "/Library/GPUBundles")
-      (subpath appPath))
+      (subpath appdir-path))
     (allow file-read*
         (subpath "/System")
         (subpath "/usr/lib")
         (subpath "/Library/GPUBundles")
-        (subpath appPath)))
+        (subpath appdir-path)))
 
   ; Allow read access to standard system paths.
   (allow file-read*
     (require-all (file-mode #o0004)
       (require-any
         (subpath "/Library/Filesystems/NetFSPlugins")
         (subpath "/usr/share"))))
 
@@ -183,24 +180,16 @@ static const char contentSandboxRules[] 
   (define (allow-shared-list domain)
     (allow file-read*
            (home-regex (string-append "/Library/Preferences/" (regex-quote domain)))))
 
   (allow ipc-posix-shm-read-data ipc-posix-shm-write-data
     (ipc-posix-name-regex #"^CFPBS:"))
 
   (allow signal (target self))
-  (if (string? parentPort)
-    (allow mach-lookup (global-name parentPort)))
-  (if (string? crashPort)
-    (allow mach-lookup (global-name crashPort)))
-  (if (string=? hasWindowServer "TRUE")
-    (allow mach-lookup (global-name "com.apple.windowserver.active")))
-  (allow mach-lookup (global-name "com.apple.coreservices.launchservicesd"))
-  (allow mach-lookup (global-name "com.apple.lsd.mapdb"))
 
   (if (>= macosMinorVersion 13)
     (allow mach-lookup
       ; bug 1392988
       (xpc-service-name "com.apple.coremedia.videodecoder")
       (xpc-service-name "com.apple.coremedia.videoencoder")))
 
 ; bug 1312273
@@ -236,17 +225,19 @@ static const char contentSandboxRules[] 
       (literal "/")
       (literal "/private/tmp")
       (literal "/private/var/tmp")
       (home-literal "/.CFUserTextEncoding")
       (home-literal "/Library/Preferences/com.apple.DownloadAssessment.plist")
       (home-subpath "/Library/Colors")
       (home-subpath "/Library/Keyboard Layouts")
       (home-subpath "/Library/Input Methods")
-      (home-subpath "/Library/Spelling"))
+      (home-subpath "/Library/Spelling")
+      (literal appPath)
+      (literal appBinaryPath))
 
   (if (defined? 'file-map-executable)
     (begin
       (when testingReadPath1
         (allow file-read* file-map-executable (subpath testingReadPath1)))
       (when testingReadPath2
         (allow file-read* file-map-executable (subpath testingReadPath2)))
       (when testingReadPath3
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -1,62 +1,74 @@
 [ShowSSEConfig]
 [TestPrintf]
 [TestAppShellSteadyState]
+[TestAlgorithm]
 [TestArray]
 [TestArrayUtils]
 [TestAtomics]
 [TestBinarySearch]
 [TestBloomFilter]
+[TestBufferList]
 [TestCasting]
 [TestCeilingFloor]
 [TestCheckedInt]
 [TestCountPopulation]
 [TestCountZeroes]
 [TestDefineEnum]
+[TestDoublyLinkedList]
 [TestDllInterceptor]
 skip-if = os != 'win'
 [TestEndian]
 [TestEnumeratedArray]
 [TestEnumSet]
 [TestEnumTypeTraits]
 [TestFastBernoulliTrial]
 [TestFloatingPoint]
+[TestFunctionTypeTraits]
 [TestIntegerPrintfMacros]
 [TestIntegerRange]
 [TestJSONWriter]
 [TestLinkedList]
 [TestMacroArgs]
 [TestMacroForEach]
 [TestMathAlgorithms]
 [TestMaybe]
+[TestNonDereferenceable]
+[TestNotNull]
 [TestParseFTPList]
 [TestPLDHash]
 [TestPair]
 [TestPoisonArea]
 skip-if = os == 'android' # Bug 1147630
+[TestRange]
 [TestRefPtr]
+[TestResult]
 [TestRollingMean]
 [TestScopeExit]
 [TestSegmentedVector]
 [TestSHA1]
 [TestSmallPointerArray]
 [TestSaturate]
 [TestSplayTree]
 [TestSPSCQueue]
 [TestSyncRunnable]
 [TestTemplateLib]
+[TestTextUtils]
+[TestThreadSafeWeakPtr]
 [TestTuple]
 [TestTypeTraits]
 [TestTypedEnum]
 [TestUniquePtr]
+[TestUtf8]
 [TestVariant]
 [TestVector]
 [TestVolatileBuffer]
 [TestWeakPtr]
+[TestWrappingOperations]
 [TestXorShift128PlusRNG]
 [buffered_stun_socket_unittest]
 [ice_unittest]
 [test_nr_socket_unittest]
 [jsapi-tests]
 [multi_tcp_socket_unittest]
 [nrappkit_unittest]
 [rlogringbuffer_unittest]
--- a/toolkit/content/aboutwebrtc/aboutWebrtc.js
+++ b/toolkit/content/aboutwebrtc/aboutWebrtc.js
@@ -845,17 +845,17 @@ ICEStats.prototype = {
   candidateToString(c) {
     if (!c) {
       return "*";
     }
 
     var type = c.candidateType;
 
     if (c.type == "local-candidate" && c.candidateType == "relayed") {
-      type = `${c.candidateType}-${c.mozLocalTransport}`;
+      type = `${c.candidateType}-${c.relayProtocol}`;
     }
 
     return `${c.ipAddress}:${c.portNumber}/${c.transport}(${type})`;
   },
 };
 
 function FoldableSection(parentElement, options = {}) {
   this._foldableElement = document.createElement("div");
--- a/toolkit/recordreplay/ProcessRedirectDarwin.cpp
+++ b/toolkit/recordreplay/ProcessRedirectDarwin.cpp
@@ -711,24 +711,17 @@ Preamble_gettimeofday(CallArguments* aAr
     return PreambleResult::PassThrough;
   }
   return PreambleResult::Redirect;
 }
 
 static PreambleResult
 Preamble_fcntl(CallArguments* aArguments)
 {
-  // We don't record any outputs for fcntl other than its return value, but
-  // some commands have an output parameter they write additional data to.
-  // Handle this by only allowing a limited set of commands to be used when
-  // events are not passed through and we are recording/replaying the outputs.
-  if (AreThreadEventsPassedThrough()) {
-    return PreambleResult::Redirect;
-  }
-
+  // Make sure fcntl is only used with a limited set of commands.
   auto& cmd = aArguments->Arg<1, size_t>();
   switch (cmd) {
   case F_GETFL:
   case F_SETFL:
   case F_GETFD:
   case F_SETFD:
   case F_NOCACHE:
   case F_SETLK:
--- a/xpcom/base/nsMacUtilsImpl.cpp
+++ b/xpcom/base/nsMacUtilsImpl.cpp
@@ -1,23 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "nsMacUtilsImpl.h"
 
-#include "base/command_line.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsCOMPtr.h"
-#include "nsIFile.h"
-#include "nsIProperties.h"
-#include "nsServiceManagerUtils.h"
-
 #include <CoreFoundation/CoreFoundation.h>
 
 NS_IMPL_ISUPPORTS(nsMacUtilsImpl, nsIMacUtils)
 
 nsresult
 nsMacUtilsImpl::GetArchString(nsAString& aArchString)
 {
   if (!mBinaryArchs.IsEmpty()) {
@@ -127,69 +120,8 @@ nsMacUtilsImpl::GetIsTranslated(bool* aI
 #else
   // Translation only exists for ppc code.  Other architectures aren't
   // translated.
   *aIsTranslated = false;
 #endif
 
   return NS_OK;
 }
-
-#if defined(MOZ_CONTENT_SANDBOX)
-bool
-nsMacUtilsImpl::GetAppPath(nsCString &aAppPath)
-{
-  nsAutoCString appPath;
-  nsAutoCString appBinaryPath(
-    (CommandLine::ForCurrentProcess()->argv()[0]).c_str());
-
-  nsAutoCString::const_iterator start, end;
-  appBinaryPath.BeginReading(start);
-  appBinaryPath.EndReading(end);
-  if (RFindInReadable(NS_LITERAL_CSTRING(".app/Contents/MacOS/"), start, end)) {
-    end = start;
-    ++end; ++end; ++end; ++end;
-    appBinaryPath.BeginReading(start);
-    appPath.Assign(Substring(start, end));
-  } else {
-    return false;
-  }
-
-  nsCOMPtr<nsIFile> app;
-  nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(appPath),
-                                true, getter_AddRefs(app));
-  if (NS_FAILED(rv)) {
-    return false;
-  }
-
-  rv = app->Normalize();
-  if (NS_FAILED(rv)) {
-    return false;
-  }
-  app->GetNativePath(aAppPath);
-
-  return true;
-}
-
-#if defined(DEBUG)
-// Given a path to a file, return the directory which contains it.
-nsAutoCString
-nsMacUtilsImpl::GetDirectoryPath(const char *aPath)
-{
-  nsCOMPtr<nsIFile> file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
-  if (!file ||
-      NS_FAILED(file->InitWithNativePath(nsDependentCString(aPath)))) {
-    MOZ_CRASH("Failed to create or init an nsIFile");
-  }
-  nsCOMPtr<nsIFile> directoryFile;
-  if (NS_FAILED(file->GetParent(getter_AddRefs(directoryFile))) ||
-      !directoryFile) {
-    MOZ_CRASH("Failed to get parent for an nsIFile");
-  }
-  directoryFile->Normalize();
-  nsAutoCString directoryPath;
-  if (NS_FAILED(directoryFile->GetNativePath(directoryPath))) {
-    MOZ_CRASH("Failed to get path for an nsIFile");
-  }
-  return directoryPath;
-}
-#endif /* DEBUG */
-#endif /* MOZ_CONTENT_SANDBOX */
--- a/xpcom/base/nsMacUtilsImpl.h
+++ b/xpcom/base/nsMacUtilsImpl.h
@@ -16,24 +16,16 @@ class nsMacUtilsImpl final : public nsIM
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIMACUTILS
 
   nsMacUtilsImpl()
   {
   }
 
-#if defined(MOZ_CONTENT_SANDBOX)
-  static bool GetAppPath(nsCString &aAppPath);
-
-#ifdef DEBUG
-  static nsAutoCString GetDirectoryPath(const char *aPath);
-#endif /* DEBUG */
-#endif /* MOZ_CONTENT_SANDBOX */
-
 private:
   ~nsMacUtilsImpl()
   {
   }
 
   nsresult GetArchString(nsAString& aArchString);
 
   // A string containing a "-" delimited list of architectures