Browse Source

more early stuff plus std:: cleanups

Frank-Rainer Grahl 1 month ago
parent
commit
7e92c7f33c
33 changed files with 8084 additions and 582 deletions
  1. 1259 0
      mozilla-release/patches/1204606-PARTIAL-fake-cdm-65a1.patch
  2. 7 7
      mozilla-release/patches/1252998-04-61a1.patch
  3. 177 0
      mozilla-release/patches/1401359-59a1.patch
  4. 103 0
      mozilla-release/patches/1422316-59a1.patch
  5. 94 0
      mozilla-release/patches/1431184-60a1.patch
  6. 25 0
      mozilla-release/patches/1433276-1-60a1.patch
  7. 28 0
      mozilla-release/patches/1433276-2-60a1.patch
  8. 547 0
      mozilla-release/patches/1433505-1-60a1.patch
  9. 895 0
      mozilla-release/patches/1433505-2-60a1.patch
  10. 339 0
      mozilla-release/patches/1433505-3-60a1.patch
  11. 187 0
      mozilla-release/patches/1433545-1-60a1.patch
  12. 139 0
      mozilla-release/patches/1433545-2-60a1.patch
  13. 32 0
      mozilla-release/patches/1433914-60a1.patch
  14. 148 0
      mozilla-release/patches/1434342-1-60a1.patch
  15. 159 0
      mozilla-release/patches/1434342-2-60a1.patch
  16. 101 0
      mozilla-release/patches/1434342-3-60a1.patch
  17. 412 0
      mozilla-release/patches/1434342-4-60a1.patch
  18. 355 0
      mozilla-release/patches/1434342-5-60a1.patch
  19. 89 0
      mozilla-release/patches/1434342-6-60a1.patch
  20. 145 0
      mozilla-release/patches/1434342-7-60a1.patch
  21. 29 0
      mozilla-release/patches/1434342-8-60a1.patch
  22. 104 0
      mozilla-release/patches/1434599-60a1.patch
  23. 328 0
      mozilla-release/patches/1434934-60a1.patch
  24. 5 5
      mozilla-release/patches/1461181-62a1.patch
  25. 3 3
      mozilla-release/patches/1463048-64a1.patch
  26. 184 516
      mozilla-release/patches/1465060-1-std-62a1.patch
  27. 164 28
      mozilla-release/patches/1465585-3-std-62a1.patch
  28. 21 23
      mozilla-release/patches/1480236-PARTIAL-notests-69a1.patch
  29. 730 0
      mozilla-release/patches/1577934-70a1.patch
  30. 1118 0
      mozilla-release/patches/1757122-99a1.patch
  31. 31 0
      mozilla-release/patches/1768999-102a1.patch
  32. 100 0
      mozilla-release/patches/870698-02-FIX-58a1.patch
  33. 26 0
      mozilla-release/patches/series

+ 1259 - 0
mozilla-release/patches/1204606-PARTIAL-fake-cdm-65a1.patch

@@ -0,0 +1,1259 @@
+# HG changeset patch
+# User Sylvestre Ledru <sledru@mozilla.com>
+# Date 1542633937 0
+# Node ID 0ceae9db9ec0be18daa1a279511ad305723185d4
+# Parent  4e4b190e0e1e1186d7301d3dd08daf4919d8192e
+Bug 1204606 - Reformat of dom/media r=jya
+
+# skip-blame
+
+Differential Revision: https://phabricator.services.mozilla.com/D12251
+
+diff --git a/dom/media/fake-cdm/cdm-fake.cpp b/dom/media/fake-cdm/cdm-fake.cpp
+--- a/dom/media/fake-cdm/cdm-fake.cpp
++++ b/dom/media/fake-cdm/cdm-fake.cpp
+@@ -36,37 +36,29 @@
+ #include "stddef.h"
+ #include "cdm-test-decryptor.h"
+ #include "content_decryption_module.h"
+ #include "content_decryption_module_ext.h"
+ 
+ extern "C" {
+ 
+ CDM_API
+-void INITIALIZE_CDM_MODULE() {
+-
+-}
++void INITIALIZE_CDM_MODULE() {}
+ 
+ CDM_API
+-void* CreateCdmInstance(int cdm_interface_version,
+-                        const char* key_system,
++void* CreateCdmInstance(int cdm_interface_version, const char* key_system,
+                         uint32_t key_system_size,
+-                        GetCdmHostFunc get_cdm_host_func,
+-                        void* user_data)
+-{
++                        GetCdmHostFunc get_cdm_host_func, void* user_data) {
+   if (cdm_interface_version != cdm::ContentDecryptionModule_9::kVersion) {
+     // Only support CDM version 9 currently.
+     return nullptr;
+   }
+   cdm::Host_9* host = static_cast<cdm::Host_9*>(
+-    get_cdm_host_func(cdm_interface_version, user_data));
++      get_cdm_host_func(cdm_interface_version, user_data));
+   return new FakeDecryptor(host);
+ }
+ 
+-
+ CDM_API
+-bool
+-VerifyCdmHost_0(const cdm::HostFile* aHostFiles, uint32_t aNumFiles)
+-{
++bool VerifyCdmHost_0(const cdm::HostFile* aHostFiles, uint32_t aNumFiles) {
+   return true;
+ }
+ 
+-} // extern "C"
++}  // extern "C"
+diff --git a/dom/media/fake-cdm/cdm-test-decryptor.cpp b/dom/media/fake-cdm/cdm-test-decryptor.cpp
+--- a/dom/media/fake-cdm/cdm-test-decryptor.cpp
++++ b/dom/media/fake-cdm/cdm-test-decryptor.cpp
+@@ -20,17 +20,17 @@
+ #include "mozilla/Assertions.h"
+ #include "mozilla/Attributes.h"
+ 
+ using namespace std;
+ 
+ FakeDecryptor* FakeDecryptor::sInstance = nullptr;
+ 
+ class TestManager {
+-public:
++ public:
+   TestManager() = default;
+ 
+   // Register a test with the test manager.
+   void BeginTest(const string& aTestID) {
+     std::lock_guard<std::mutex> lock(mMutex);
+     auto found = mTestIDs.find(aTestID);
+     if (found == mTestIDs.end()) {
+       mTestIDs.insert(aTestID);
+@@ -56,253 +56,231 @@ public:
+       }
+     }
+     if (isEmpty) {
+       Finish();
+       delete this;
+     }
+   }
+ 
+-private:
++ private:
+   ~TestManager() = default;
+ 
+-  static void Error(const string& msg) {
+-    FakeDecryptor::Message(msg);
+-  }
++  static void Error(const string& msg) { FakeDecryptor::Message(msg); }
+ 
+-  static void Finish() {
+-    FakeDecryptor::Message("test-storage complete");
+-  }
++  static void Finish() { FakeDecryptor::Message("test-storage complete"); }
+ 
+   std::mutex mMutex;
+   set<string> mTestIDs;
+ };
+ 
+-FakeDecryptor::FakeDecryptor(cdm::Host_9* aHost)
+-  : mHost(aHost)
+-{
++FakeDecryptor::FakeDecryptor(cdm::Host_9* aHost) : mHost(aHost) {
+   MOZ_ASSERT(!sInstance);
+   sInstance = this;
+ }
+ 
+-void
+-FakeDecryptor::Message(const std::string& aMessage)
+-{
++void FakeDecryptor::Message(const std::string& aMessage) {
+   MOZ_ASSERT(sInstance);
+   const static std::string sid("fake-session-id");
+-  sInstance->mHost->OnSessionMessage(sid.c_str(),
+-                                     sid.size(),
++  sInstance->mHost->OnSessionMessage(sid.c_str(), sid.size(),
+                                      cdm::MessageType::kLicenseRequest,
+-                                     aMessage.c_str(),
+-                                     aMessage.size());
++                                     aMessage.c_str(), aMessage.size());
+ }
+ 
+-std::vector<std::string>
+-Tokenize(const std::string& aString)
+-{
++std::vector<std::string> Tokenize(const std::string& aString) {
+   std::stringstream strstr(aString);
+   std::istream_iterator<std::string> it(strstr), end;
+   return std::vector<std::string>(it, end);
+ }
+ 
+ static const string TruncateRecordId = "truncate-record-id";
+ static const string TruncateRecordData = "I will soon be truncated";
+ 
+-template<class Continuation>
++template <class Continuation>
+ class WriteRecordSuccessTask {
+-public:
++ public:
+   WriteRecordSuccessTask(string aId, Continuation aThen)
+-    : mId(aId)
+-    , mThen(move(aThen))
+-  {}
++      : mId(aId), mThen(move(aThen)) {}
+ 
+-  void operator()()
+-  {
+-    ReadRecord(FakeDecryptor::sInstance->mHost, mId, mThen);
+-  }
++  void operator()() { ReadRecord(FakeDecryptor::sInstance->mHost, mId, mThen); }
+ 
+   string mId;
+   Continuation mThen;
+ };
+ 
+ class WriteRecordFailureTask {
+-public:
++ public:
+   explicit WriteRecordFailureTask(const string& aMessage,
+                                   TestManager* aTestManager = nullptr,
+                                   const string& aTestID = "")
+-    : mMessage(aMessage), mTestmanager(aTestManager), mTestID(aTestID) {}
++      : mMessage(aMessage), mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+-  void operator()()
+-  {
++  void operator()() {
+     FakeDecryptor::Message(mMessage);
+     if (mTestmanager) {
+       mTestmanager->EndTest(mTestID);
+     }
+   }
+ 
+-private:
++ private:
+   string mMessage;
+   TestManager* const mTestmanager;
+   const string mTestID;
+ };
+ 
+ class TestEmptyContinuation : public ReadContinuation {
+-public:
++ public:
+   TestEmptyContinuation(TestManager* aTestManager, const string& aTestID)
+-    : mTestmanager(aTestManager), mTestID(aTestID) {}
++      : mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+-  virtual void operator()(bool aSuccess,
+-                          const uint8_t* aData,
+-                          uint32_t aDataSize) override
+-  {
++  virtual void operator()(bool aSuccess, const uint8_t* aData,
++                          uint32_t aDataSize) override {
+     if (aDataSize) {
+-      FakeDecryptor::Message("FAIL TestEmptyContinuation record was not truncated");
++      FakeDecryptor::Message(
++          "FAIL TestEmptyContinuation record was not truncated");
+     }
+     mTestmanager->EndTest(mTestID);
+   }
+ 
+-private:
++ private:
+   TestManager* const mTestmanager;
+   const string mTestID;
+ };
+ 
+ class TruncateContinuation : public ReadContinuation {
+-public:
+-  TruncateContinuation(const string& aID,
+-                       TestManager* aTestManager,
++ public:
++  TruncateContinuation(const string& aID, TestManager* aTestManager,
+                        const string& aTestID)
+-    : mID(aID), mTestmanager(aTestManager), mTestID(aTestID) {}
++      : mID(aID), mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+-  virtual void operator()(bool aSuccess,
+-                          const uint8_t* aData,
+-                          uint32_t aDataSize) override
+-  {
+-    if (string(reinterpret_cast<const char*>(aData), aDataSize) != TruncateRecordData) {
+-      FakeDecryptor::Message("FAIL TruncateContinuation read data doesn't match written data");
++  virtual void operator()(bool aSuccess, const uint8_t* aData,
++                          uint32_t aDataSize) override {
++    if (string(reinterpret_cast<const char*>(aData), aDataSize) !=
++        TruncateRecordData) {
++      FakeDecryptor::Message(
++          "FAIL TruncateContinuation read data doesn't match written data");
+     }
+     auto cont = TestEmptyContinuation(mTestmanager, mTestID);
+     auto msg = "FAIL in TruncateContinuation write.";
+     WriteRecord(FakeDecryptor::sInstance->mHost, mID, nullptr, 0,
+                 WriteRecordSuccessTask<TestEmptyContinuation>(mID, cont),
+                 WriteRecordFailureTask(msg, mTestmanager, mTestID));
+   }
+ 
+-private:
++ private:
+   const string mID;
+   TestManager* const mTestmanager;
+   const string mTestID;
+ };
+ 
+ class VerifyAndFinishContinuation : public ReadContinuation {
+-public:
+-  explicit VerifyAndFinishContinuation(string aValue,
+-                                       TestManager* aTestManager,
++ public:
++  explicit VerifyAndFinishContinuation(string aValue, TestManager* aTestManager,
+                                        const string& aTestID)
+-  : mValue(aValue), mTestmanager(aTestManager), mTestID(aTestID) {}
++      : mValue(aValue), mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+-  virtual void operator()(bool aSuccess,
+-                          const uint8_t* aData,
+-                          uint32_t aDataSize) override
+-  {
++  virtual void operator()(bool aSuccess, const uint8_t* aData,
++                          uint32_t aDataSize) override {
+     if (string(reinterpret_cast<const char*>(aData), aDataSize) != mValue) {
+-      FakeDecryptor::Message("FAIL VerifyAndFinishContinuation read data doesn't match expected data");
++      FakeDecryptor::Message(
++          "FAIL VerifyAndFinishContinuation read data doesn't match expected "
++          "data");
+     }
+     mTestmanager->EndTest(mTestID);
+   }
+ 
+-private:
++ private:
+   string mValue;
+   TestManager* const mTestmanager;
+   const string mTestID;
+ };
+ 
+ class VerifyAndOverwriteContinuation : public ReadContinuation {
+-public:
++ public:
+   VerifyAndOverwriteContinuation(string aId, string aValue, string aOverwrite,
+-                                 TestManager* aTestManager, const string& aTestID)
+-    : mId(aId)
+-    , mValue(aValue)
+-    , mOverwrite(aOverwrite)
+-    , mTestmanager(aTestManager)
+-    , mTestID(aTestID)
+-  {}
++                                 TestManager* aTestManager,
++                                 const string& aTestID)
++      : mId(aId),
++        mValue(aValue),
++        mOverwrite(aOverwrite),
++        mTestmanager(aTestManager),
++        mTestID(aTestID) {}
+ 
+-  virtual void operator()(bool aSuccess,
+-                          const uint8_t* aData,
+-                          uint32_t aDataSize) override
+-  {
++  virtual void operator()(bool aSuccess, const uint8_t* aData,
++                          uint32_t aDataSize) override {
+     if (string(reinterpret_cast<const char*>(aData), aDataSize) != mValue) {
+-      FakeDecryptor::Message("FAIL VerifyAndOverwriteContinuation read data doesn't match expected data");
++      FakeDecryptor::Message(
++          "FAIL VerifyAndOverwriteContinuation read data doesn't match "
++          "expected data");
+     }
+     auto cont = VerifyAndFinishContinuation(mOverwrite, mTestmanager, mTestID);
+     auto msg = "FAIL in VerifyAndOverwriteContinuation write.";
+     WriteRecord(FakeDecryptor::sInstance->mHost, mId, mOverwrite,
+                 WriteRecordSuccessTask<VerifyAndFinishContinuation>(mId, cont),
+                 WriteRecordFailureTask(msg, mTestmanager, mTestID));
+   }
+ 
+-private:
++ private:
+   string mId;
+   string mValue;
+   string mOverwrite;
+   TestManager* const mTestmanager;
+   const string mTestID;
+ };
+ 
+ static const string OpenAgainRecordId = "open-again-record-id";
+ 
+ class OpenedSecondTimeContinuation : public OpenContinuation {
+-public:
++ public:
+   explicit OpenedSecondTimeContinuation(TestManager* aTestManager,
+                                         const string& aTestID)
+-    : mTestmanager(aTestManager), mTestID(aTestID)
+-  {
+-  }
++      : mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+   void operator()(bool aSuccess) override {
+     if (!aSuccess) {
+-      FakeDecryptor::Message("FAIL OpenSecondTimeContinuation should not be able to re-open record.");
++      FakeDecryptor::Message(
++          "FAIL OpenSecondTimeContinuation should not be able to re-open "
++          "record.");
+     }
+     // Succeeded, open should have failed.
+     mTestmanager->EndTest(mTestID);
+   }
+ 
+-private:
++ private:
+   TestManager* const mTestmanager;
+   const string mTestID;
+ };
+ 
+ class OpenedFirstTimeContinuation : public OpenContinuation {
+-public:
+-  OpenedFirstTimeContinuation(const string& aID,
+-                              TestManager* aTestManager,
++ public:
++  OpenedFirstTimeContinuation(const string& aID, TestManager* aTestManager,
+                               const string& aTestID)
+-    : mID(aID), mTestmanager(aTestManager), mTestID(aTestID) {}
++      : mID(aID), mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+   void operator()(bool aSuccess) override {
+     if (!aSuccess) {
+-      FakeDecryptor::Message("FAIL OpenAgainContinuation to open record initially.");
++      FakeDecryptor::Message(
++          "FAIL OpenAgainContinuation to open record initially.");
+       mTestmanager->EndTest(mTestID);
+       return;
+     }
+ 
+     auto cont = OpenedSecondTimeContinuation(mTestmanager, mTestID);
+     OpenRecord(FakeDecryptor::sInstance->mHost, mID, cont);
+   }
+ 
+-private:
++ private:
+   const string mID;
+   TestManager* const mTestmanager;
+   const string mTestID;
+ };
+ 
+-static void
+-DoTestStorage(const string& aPrefix, TestManager* aTestManager)
+-{
+-  MOZ_ASSERT(FakeDecryptor::sInstance->mHost, "FakeDecryptor::sInstance->mHost should not be null");
++static void DoTestStorage(const string& aPrefix, TestManager* aTestManager) {
++  MOZ_ASSERT(FakeDecryptor::sInstance->mHost,
++             "FakeDecryptor::sInstance->mHost should not be null");
+   // Basic I/O tests. We run three cases concurrently. The tests, like
+   // CDMStorage run asynchronously. When they've all passed, we send
+   // a message back to the parent process, or a failure message if not.
+ 
+   // Test 1: Basic I/O test, and test that writing 0 bytes in a record
+   // deletes record.
+   //
+   // Write data to truncate record, then
+@@ -328,145 +306,128 @@ DoTestStorage(const string& aPrefix, Tes
+   string id2 = aPrefix + "record1";
+   string record1 = "This is the first write to a record.";
+   string overwrite = "A shorter record";
+   const string testID2 = aPrefix + "write-test-2";
+   aTestManager->BeginTest(testID2);
+   auto task2 = VerifyAndOverwriteContinuation(id2, record1, overwrite,
+                                               aTestManager, testID2);
+   auto msg2 = "FAIL in TestStorage writing record1.";
+-  WriteRecord(FakeDecryptor::sInstance->mHost, id2, record1,
+-              WriteRecordSuccessTask<VerifyAndOverwriteContinuation>(id2, task2),
+-              WriteRecordFailureTask(msg2, aTestManager, testID2));
++  WriteRecord(
++      FakeDecryptor::sInstance->mHost, id2, record1,
++      WriteRecordSuccessTask<VerifyAndOverwriteContinuation>(id2, task2),
++      WriteRecordFailureTask(msg2, aTestManager, testID2));
+ 
+   // Test 3: Test that opening a record while it's already open fails.
+   //
+   // Open record1, then
+   // open record1, should fail.
+   // close record1
+   const string id3 = aPrefix + OpenAgainRecordId;
+   const string testID3 = aPrefix + "open-test-1";
+   aTestManager->BeginTest(testID3);
+   auto task3 = OpenedFirstTimeContinuation(id3, aTestManager, testID3);
+   OpenRecord(FakeDecryptor::sInstance->mHost, id3, task3);
+ }
+ 
+-void
+-FakeDecryptor::TestStorage()
+-{
++void FakeDecryptor::TestStorage() {
+   auto* testManager = new TestManager();
+   // Main thread tests.
+   DoTestStorage("mt1-", testManager);
+   DoTestStorage("mt2-", testManager);
+ 
+   // Note: Once all tests finish, TestManager will dispatch "test-pass" message,
+   // which ends the test for the parent.
+ }
+ 
+-class ReportWritten
+-{
+-public:
++class ReportWritten {
++ public:
+   ReportWritten(const string& aRecordId, const string& aValue)
+-    : mRecordId(aRecordId)
+-    , mValue(aValue)
+-  {}
++      : mRecordId(aRecordId), mValue(aValue) {}
+   void operator()() {
+     FakeDecryptor::Message("stored " + mRecordId + " " + mValue);
+   }
+ 
+   const string mRecordId;
+   const string mValue;
+ };
+ 
+ class ReportReadStatusContinuation : public ReadContinuation {
+-public:
++ public:
+   explicit ReportReadStatusContinuation(const string& aRecordId)
+-    : mRecordId(aRecordId)
+-  {}
+-  void operator()(bool aSuccess,
+-                  const uint8_t* aData,
+-                  uint32_t aDataSize) override
+-  {
++      : mRecordId(aRecordId) {}
++  void operator()(bool aSuccess, const uint8_t* aData,
++                  uint32_t aDataSize) override {
+     if (!aSuccess) {
+       FakeDecryptor::Message("retrieve " + mRecordId + " failed");
+     } else {
+       stringstream ss;
+       ss << aDataSize;
+       string len;
+       ss >> len;
+       FakeDecryptor::Message("retrieve " + mRecordId + " succeeded (length " +
+                              len + " bytes)");
+     }
+   }
+   string mRecordId;
+ };
+ 
+ class ReportReadRecordContinuation : public ReadContinuation {
+-public:
++ public:
+   explicit ReportReadRecordContinuation(const string& aRecordId)
+-    : mRecordId(aRecordId)
+-  {}
+-  void operator()(bool aSuccess,
+-                  const uint8_t* aData,
+-                  uint32_t aDataSize) override
+-  {
++      : mRecordId(aRecordId) {}
++  void operator()(bool aSuccess, const uint8_t* aData,
++                  uint32_t aDataSize) override {
+     if (!aSuccess) {
+       FakeDecryptor::Message("retrieved " + mRecordId + " failed");
+     } else {
+-      FakeDecryptor::Message("retrieved " + mRecordId + " " +
+-                             string(reinterpret_cast<const char*>(aData),
+-                                    aDataSize));
++      FakeDecryptor::Message(
++          "retrieved " + mRecordId + " " +
++          string(reinterpret_cast<const char*>(aData), aDataSize));
+     }
+   }
+   string mRecordId;
+ };
+ 
+-enum ShutdownMode {
+-  ShutdownNormal,
+-  ShutdownTimeout,
+-  ShutdownStoreToken
+-};
++enum ShutdownMode { ShutdownNormal, ShutdownTimeout, ShutdownStoreToken };
+ 
+ static ShutdownMode sShutdownMode = ShutdownNormal;
+ static string sShutdownToken;
+ 
+-void
+-FakeDecryptor::UpdateSession(uint32_t aPromiseId,
+-                             const char* aSessionId,
+-                             uint32_t aSessionIdLength,
+-                             const uint8_t* aResponse,
+-                             uint32_t aResponseSize)
+-{
+-  MOZ_ASSERT(FakeDecryptor::sInstance->mHost, "FakeDecryptor::sInstance->mHost should not be null");
+-  std::string response((const char*)aResponse, (const char*)(aResponse)+aResponseSize);
++void FakeDecryptor::UpdateSession(uint32_t aPromiseId, const char* aSessionId,
++                                  uint32_t aSessionIdLength,
++                                  const uint8_t* aResponse,
++                                  uint32_t aResponseSize) {
++  MOZ_ASSERT(FakeDecryptor::sInstance->mHost,
++             "FakeDecryptor::sInstance->mHost should not be null");
++  std::string response((const char*)aResponse,
++                       (const char*)(aResponse) + aResponseSize);
+   std::vector<std::string> tokens = Tokenize(response);
+   const string& task = tokens[0];
+   if (task == "test-storage") {
+     TestStorage();
+   } else if (task == "store") {
+-      // send "stored record" message on complete.
++    // send "stored record" message on complete.
+     const string& id = tokens[1];
+     const string& value = tokens[2];
+-    WriteRecord(FakeDecryptor::sInstance->mHost,
+-                id,
+-                value,
++    WriteRecord(FakeDecryptor::sInstance->mHost, id, value,
+                 ReportWritten(id, value),
+                 WriteRecordFailureTask("FAIL in writing record."));
+   } else if (task == "retrieve") {
+     const string& id = tokens[1];
+-    ReadRecord(FakeDecryptor::sInstance->mHost, id, ReportReadStatusContinuation(id));
++    ReadRecord(FakeDecryptor::sInstance->mHost, id,
++               ReportReadStatusContinuation(id));
+   } else if (task == "shutdown-mode") {
+     const string& mode = tokens[1];
+     if (mode == "timeout") {
+       sShutdownMode = ShutdownTimeout;
+     } else if (mode == "token") {
+       sShutdownMode = ShutdownStoreToken;
+       sShutdownToken = tokens[2];
+       Message("shutdown-token received " + sShutdownToken);
+     }
+   } else if (task == "retrieve-shutdown-token") {
+-    ReadRecord(FakeDecryptor::sInstance->mHost,
+-               "shutdown-token",
++    ReadRecord(FakeDecryptor::sInstance->mHost, "shutdown-token",
+                ReportReadRecordContinuation("shutdown-token"));
+   } else if (task == "test-op-apis") {
+     mozilla::cdmtest::TestOuputProtectionAPIs();
+   }
+ }
+diff --git a/dom/media/fake-cdm/cdm-test-decryptor.h b/dom/media/fake-cdm/cdm-test-decryptor.h
+--- a/dom/media/fake-cdm/cdm-test-decryptor.h
++++ b/dom/media/fake-cdm/cdm-test-decryptor.h
+@@ -6,143 +6,100 @@
+ #ifndef FAKE_DECRYPTOR_H__
+ #define FAKE_DECRYPTOR_H__
+ 
+ #include "content_decryption_module.h"
+ #include <string>
+ #include "mozilla/Attributes.h"
+ 
+ class FakeDecryptor : public cdm::ContentDecryptionModule_9 {
+-public:
++ public:
+   explicit FakeDecryptor(cdm::Host_9* aHost);
+ 
+   void Initialize(bool aAllowDistinctiveIdentifier,
+-                  bool aAllowPersistentState) override
+-  {
+-  }
++                  bool aAllowPersistentState) override {}
+ 
+   void GetStatusForPolicy(uint32_t aPromiseId,
+-                          const cdm::Policy& aPolicy) override
+-  {
+-  }
++                          const cdm::Policy& aPolicy) override {}
+ 
+   void SetServerCertificate(uint32_t aPromiseId,
+                             const uint8_t* aServerCertificateData,
+-                            uint32_t aServerCertificateDataSize)
+-                            override
+-  {
+-  }
++                            uint32_t aServerCertificateDataSize) override {}
+ 
+   void CreateSessionAndGenerateRequest(uint32_t aPromiseId,
+                                        cdm::SessionType aSessionType,
+                                        cdm::InitDataType aInitDataType,
+                                        const uint8_t* aInitData,
+-                                       uint32_t aInitDataSize)
+-                                       override
+-  {
+-  }
++                                       uint32_t aInitDataSize) override {}
+ 
+-  void LoadSession(uint32_t aPromiseId,
+-                   cdm::SessionType aSessionType,
+-                   const char* aSessionId,
+-                   uint32_t aSessionIdSize) override
+-  {
+-  }
++  void LoadSession(uint32_t aPromiseId, cdm::SessionType aSessionType,
++                   const char* aSessionId, uint32_t aSessionIdSize) override {}
+ 
+-  void UpdateSession(uint32_t aPromiseId,
+-                     const char* aSessionId,
+-                     uint32_t aSessionIdSize,
+-                     const uint8_t* aResponse,
++  void UpdateSession(uint32_t aPromiseId, const char* aSessionId,
++                     uint32_t aSessionIdSize, const uint8_t* aResponse,
+                      uint32_t aResponseSize) override;
+ 
+-  void CloseSession(uint32_t aPromiseId,
+-                    const char* aSessionId,
+-                    uint32_t aSessionIdSize) override
+-  {
+-  }
++  void CloseSession(uint32_t aPromiseId, const char* aSessionId,
++                    uint32_t aSessionIdSize) override {}
+ 
+-  void RemoveSession(uint32_t aPromiseId,
+-                     const char* aSessionId,
+-                     uint32_t aSessionIdSize) override
+-  {
+-  }
++  void RemoveSession(uint32_t aPromiseId, const char* aSessionId,
++                     uint32_t aSessionIdSize) override {}
+ 
+-  void TimerExpired(void* aContext) override
+-  {
+-  }
++  void TimerExpired(void* aContext) override {}
+ 
+   cdm::Status Decrypt(const cdm::InputBuffer_1& aEncryptedBuffer,
+-                      cdm::DecryptedBlock* aDecryptedBuffer) override
+-  {
++                      cdm::DecryptedBlock* aDecryptedBuffer) override {
+     return cdm::Status::kDecodeError;
+   }
+ 
+   cdm::Status InitializeAudioDecoder(
+-    const cdm::AudioDecoderConfig_1& aAudioDecoderConfig) override
+-  {
++      const cdm::AudioDecoderConfig_1& aAudioDecoderConfig) override {
+     return cdm::Status::kDecodeError;
+   }
+ 
+   cdm::Status InitializeVideoDecoder(
+-    const cdm::VideoDecoderConfig_1& aVideoDecoderConfig) override
+-  {
++      const cdm::VideoDecoderConfig_1& aVideoDecoderConfig) override {
+     return cdm::Status::kDecodeError;
+   }
+ 
+-  void DeinitializeDecoder(cdm::StreamType aDecoderType) override
+-  {
+-  }
++  void DeinitializeDecoder(cdm::StreamType aDecoderType) override {}
+ 
+-  void ResetDecoder(cdm::StreamType aDecoderType) override
+-  {
+-  }
++  void ResetDecoder(cdm::StreamType aDecoderType) override {}
+ 
+   cdm::Status DecryptAndDecodeFrame(const cdm::InputBuffer_1& aEncryptedBuffer,
+-                                    cdm::VideoFrame* aVideoFrame) override
+-  {
++                                    cdm::VideoFrame* aVideoFrame) override {
+     return cdm::Status::kDecodeError;
+   }
+ 
+   cdm::Status DecryptAndDecodeSamples(
+-    const cdm::InputBuffer_1& aEncryptedBuffer,
+-    cdm::AudioFrames* aAudioFrame) override
+-  {
++      const cdm::InputBuffer_1& aEncryptedBuffer,
++      cdm::AudioFrames* aAudioFrame) override {
+     return cdm::Status::kDecodeError;
+   }
+ 
+   void OnPlatformChallengeResponse(
+-    const cdm::PlatformChallengeResponse& aResponse) override
+-  {
+-  }
++      const cdm::PlatformChallengeResponse& aResponse) override {}
+ 
+   void OnQueryOutputProtectionStatus(cdm::QueryResult aResult,
+                                      uint32_t aLinkMask,
+-                                     uint32_t aOutputProtectionMask) override
+-  {
+-  }
++                                     uint32_t aOutputProtectionMask) override {}
+ 
+-  void OnStorageId(uint32_t aVersion,
+-                   const uint8_t* aStorageId,
+-                   uint32_t aStorageIdSize) override
+-  {
+-  }
++  void OnStorageId(uint32_t aVersion, const uint8_t* aStorageId,
++                   uint32_t aStorageIdSize) override {}
+ 
+-  void Destroy() override
+-  {
++  void Destroy() override {
+     delete this;
+     sInstance = nullptr;
+   }
+ 
+   static void Message(const std::string& aMessage);
+ 
+   cdm::Host_9* mHost;
+ 
+   static FakeDecryptor* sInstance;
+ 
+-private:
+-
++ private:
+   virtual ~FakeDecryptor() {}
+ 
+   void TestStorage();
+-
+ };
+ 
+ #endif
+diff --git a/dom/media/fake-cdm/cdm-test-output-protection.h b/dom/media/fake-cdm/cdm-test-output-protection.h
+--- a/dom/media/fake-cdm/cdm-test-output-protection.h
++++ b/dom/media/fake-cdm/cdm-test-output-protection.h
+@@ -1,74 +1,75 @@
+ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+ /* vim: set ts=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/. */
+ 
+ #if defined(XP_WIN)
+-#include <d3d9.h> // needed to prevent re-definition of enums
++#include <d3d9.h>  // needed to prevent re-definition of enums
+ #include <stdio.h>
+ #include <string>
+ #include <vector>
+ #include <windows.h>
+ 
+ #include "opmapi.h"
+ #endif
+ 
+ namespace mozilla {
+ namespace cdmtest {
+ 
+ #if defined(XP_WIN)
+-typedef HRESULT(STDAPICALLTYPE * OPMGetVideoOutputsFromHMONITORProc)
+-          (HMONITOR, OPM_VIDEO_OUTPUT_SEMANTICS, ULONG*, IOPMVideoOutput***);
++typedef HRESULT(STDAPICALLTYPE* OPMGetVideoOutputsFromHMONITORProc)(
++    HMONITOR, OPM_VIDEO_OUTPUT_SEMANTICS, ULONG*, IOPMVideoOutput***);
+ 
+-static OPMGetVideoOutputsFromHMONITORProc sOPMGetVideoOutputsFromHMONITORProc = nullptr;
++static OPMGetVideoOutputsFromHMONITORProc sOPMGetVideoOutputsFromHMONITORProc =
++    nullptr;
+ 
+ static BOOL CALLBACK EnumDisplayMonitorsCallback(HMONITOR hMonitor, HDC hdc,
+-                                                 LPRECT lprc, LPARAM pData)
+-{
++                                                 LPRECT lprc, LPARAM pData) {
+   std::vector<std::string>* failureMsgs = (std::vector<std::string>*)pData;
+ 
+   MONITORINFOEXA miex;
+   ZeroMemory(&miex, sizeof(miex));
+   miex.cbSize = sizeof(miex);
+   if (!GetMonitorInfoA(hMonitor, &miex)) {
+     failureMsgs->push_back("FAIL GetMonitorInfoA call failed");
+   }
+ 
+   ULONG numVideoOutputs = 0;
+   IOPMVideoOutput** opmVideoOutputArray = nullptr;
+-  HRESULT hr = sOPMGetVideoOutputsFromHMONITORProc(hMonitor,
+-                                                   OPM_VOS_OPM_SEMANTICS,
+-                                                   &numVideoOutputs,
+-                                                   &opmVideoOutputArray);
++  HRESULT hr = sOPMGetVideoOutputsFromHMONITORProc(
++      hMonitor, OPM_VOS_OPM_SEMANTICS, &numVideoOutputs, &opmVideoOutputArray);
+   if (S_OK != hr) {
+-    if ((HRESULT)0x8007001f != hr && (HRESULT)0x80070032 != hr && (HRESULT)0xc02625e5 != hr) {
++    if ((HRESULT)0x8007001f != hr && (HRESULT)0x80070032 != hr &&
++        (HRESULT)0xc02625e5 != hr) {
+       char msg[100];
+-      sprintf(msg, "FAIL OPMGetVideoOutputsFromHMONITOR call failed: HRESULT=0x%08lx", hr);
++      sprintf(
++          msg,
++          "FAIL OPMGetVideoOutputsFromHMONITOR call failed: HRESULT=0x%08lx",
++          hr);
+       failureMsgs->push_back(msg);
+     }
+     return true;
+   }
+ 
+   DISPLAY_DEVICEA dd;
+   ZeroMemory(&dd, sizeof(dd));
+   dd.cb = sizeof(dd);
+   if (!EnumDisplayDevicesA(miex.szDevice, 0, &dd, 1)) {
+     failureMsgs->push_back("FAIL EnumDisplayDevicesA call failed");
+   }
+ 
+   for (ULONG i = 0; i < numVideoOutputs; ++i) {
+     OPM_RANDOM_NUMBER opmRandomNumber;
+     BYTE* certificate = nullptr;
+     ULONG certificateLength = 0;
+-    hr = opmVideoOutputArray[i]->StartInitialization(&opmRandomNumber,
+-                                                     &certificate,
+-                                                     &certificateLength);
++    hr = opmVideoOutputArray[i]->StartInitialization(
++        &opmRandomNumber, &certificate, &certificateLength);
+     if (S_OK != hr) {
+       char msg[100];
+       sprintf(msg, "FAIL StartInitialization call failed: HRESULT=0x%08lx", hr);
+       failureMsgs->push_back(msg);
+     }
+ 
+     if (certificate) {
+       CoTaskMemFree(certificate);
+@@ -80,50 +81,48 @@ static BOOL CALLBACK EnumDisplayMonitors
+   if (opmVideoOutputArray) {
+     CoTaskMemFree(opmVideoOutputArray);
+   }
+ 
+   return true;
+ }
+ #endif
+ 
+-static void
+-RunOutputProtectionAPITests()
+-{
++static void RunOutputProtectionAPITests() {
+ #if defined(XP_WIN)
+   // Get hold of OPMGetVideoOutputsFromHMONITOR function.
+   HMODULE hDvax2DLL = GetModuleHandleW(L"dxva2.dll");
+   if (!hDvax2DLL) {
+     FakeDecryptor::Message("FAIL GetModuleHandleW call failed for dxva2.dll");
+     return;
+   }
+ 
+-  sOPMGetVideoOutputsFromHMONITORProc = (OPMGetVideoOutputsFromHMONITORProc)
+-    GetProcAddress(hDvax2DLL, "OPMGetVideoOutputsFromHMONITOR");
++  sOPMGetVideoOutputsFromHMONITORProc =
++      (OPMGetVideoOutputsFromHMONITORProc)GetProcAddress(
++          hDvax2DLL, "OPMGetVideoOutputsFromHMONITOR");
+   if (!sOPMGetVideoOutputsFromHMONITORProc) {
+-    FakeDecryptor::Message("FAIL GetProcAddress call failed for OPMGetVideoOutputsFromHMONITOR");
++    FakeDecryptor::Message(
++        "FAIL GetProcAddress call failed for OPMGetVideoOutputsFromHMONITOR");
+     return;
+   }
+ 
+   // Test EnumDisplayMonitors.
+   // Other APIs are tested in the callback function.
+   std::vector<std::string> failureMsgs;
+   if (!EnumDisplayMonitors(NULL, NULL, EnumDisplayMonitorsCallback,
+-                           (LPARAM) &failureMsgs)) {
++                           (LPARAM)&failureMsgs)) {
+     FakeDecryptor::Message("FAIL EnumDisplayMonitors call failed");
+   }
+ 
+   // Report any failures in the callback function.
+   for (size_t i = 0; i < failureMsgs.size(); i++) {
+     FakeDecryptor::Message(failureMsgs[i]);
+   }
+ #endif
+ }
+ 
+-static void
+-TestOuputProtectionAPIs()
+-{
++static void TestOuputProtectionAPIs() {
+   RunOutputProtectionAPITests();
+   FakeDecryptor::Message("OP tests completed");
+ }
+ 
+-} // namespace cdmtest
+-} // namespace mozilla
++}  // namespace cdmtest
++}  // namespace mozilla
+diff --git a/dom/media/fake-cdm/cdm-test-storage.cpp b/dom/media/fake-cdm/cdm-test-storage.cpp
+--- a/dom/media/fake-cdm/cdm-test-storage.cpp
++++ b/dom/media/fake-cdm/cdm-test-storage.cpp
+@@ -7,60 +7,47 @@
+ #include <vector>
+ 
+ #include "mozilla/Assertions.h"
+ #include "mozilla/Attributes.h"
+ 
+ using namespace cdm;
+ using namespace std;
+ 
+-class WriteRecordClient : public FileIOClient
+-{
+-public:
++class WriteRecordClient : public FileIOClient {
++ public:
+   WriteRecordClient(function<void()>&& aOnSuccess,
+-                    function<void()>&& aOnFailure,
+-                    const uint8_t* aData,
++                    function<void()>&& aOnFailure, const uint8_t* aData,
+                     uint32_t aDataSize)
+-    : mOnSuccess(move(aOnSuccess))
+-    , mOnFailure(move(aOnFailure))
+-  {
++      : mOnSuccess(move(aOnSuccess)), mOnFailure(move(aOnFailure)) {
+     mData.insert(mData.end(), aData, aData + aDataSize);
+   }
+ 
+-  void OnOpenComplete(Status aStatus) override
+-  {
++  void OnOpenComplete(Status aStatus) override {
+     // If we hit an error, fail.
+     if (aStatus != Status::kSuccess) {
+       Done(aStatus);
+-    } else if (mFileIO) { // Otherwise, write our data to the file.
++    } else if (mFileIO) {  // Otherwise, write our data to the file.
+       mFileIO->Write(mData.empty() ? nullptr : &mData.front(), mData.size());
+     }
+   }
+ 
+-  void OnReadComplete(Status aStatus,
+-                      const uint8_t* aData,
+-                      uint32_t aDataSize) override
+-  {
+-  }
++  void OnReadComplete(Status aStatus, const uint8_t* aData,
++                      uint32_t aDataSize) override {}
+ 
+-  void OnWriteComplete(Status aStatus) override
+-  {
+-    Done(aStatus);
+-  }
++  void OnWriteComplete(Status aStatus) override { Done(aStatus); }
+ 
+-  void Do(const string& aName, Host_9* aHost)
+-  {
++  void Do(const string& aName, Host_9* aHost) {
+     // Initialize the FileIO.
+     mFileIO = aHost->CreateFileIO(this);
+     mFileIO->Open(aName.c_str(), aName.size());
+   }
+ 
+-private:
+-  void Done(cdm::FileIOClient::Status aStatus)
+-  {
++ private:
++  void Done(cdm::FileIOClient::Status aStatus) {
+     // Note: Call Close() before running continuation, in case the
+     // continuation tries to open the same record; if we call Close()
+     // after running the continuation, the Close() call will arrive
+     // just after the Open() call succeeds, immediately closing the
+     // record we just opened.
+     if (mFileIO) {
+       // will delete mFileIO inside Close.
+       mFileIO->Close();
+@@ -76,87 +63,62 @@ private:
+   }
+ 
+   FileIO* mFileIO = nullptr;
+   function<void()> mOnSuccess;
+   function<void()> mOnFailure;
+   std::vector<uint8_t> mData;
+ };
+ 
+-void
+-WriteRecord(Host_9* aHost,
+-            const std::string& aRecordName,
+-            const uint8_t* aData,
+-            uint32_t aNumBytes,
+-            function<void()>&& aOnSuccess,
+-            function<void()>&& aOnFailure)
+-{
++void WriteRecord(Host_9* aHost, const std::string& aRecordName,
++                 const uint8_t* aData, uint32_t aNumBytes,
++                 function<void()>&& aOnSuccess, function<void()>&& aOnFailure) {
+   // client will be delete in WriteRecordClient::Done
+-  WriteRecordClient* client = new WriteRecordClient(move(aOnSuccess),
+-                                                    move(aOnFailure),
+-                                                    aData,
+-                                                    aNumBytes);
++  WriteRecordClient* client = new WriteRecordClient(
++      move(aOnSuccess), move(aOnFailure), aData, aNumBytes);
+   client->Do(aRecordName, aHost);
+ }
+ 
+-void
+-WriteRecord(Host_9* aHost,
+-            const std::string& aRecordName,
+-            const std::string& aData,
+-            function<void()> &&aOnSuccess,
+-            function<void()>&& aOnFailure)
+-{
+-  return WriteRecord(aHost,
+-                     aRecordName,
+-                     (const uint8_t*)aData.c_str(),
+-                     aData.size(),
+-                     move(aOnSuccess),
+-                     move(aOnFailure));
++void WriteRecord(Host_9* aHost, const std::string& aRecordName,
++                 const std::string& aData, function<void()>&& aOnSuccess,
++                 function<void()>&& aOnFailure) {
++  return WriteRecord(aHost, aRecordName, (const uint8_t*)aData.c_str(),
++                     aData.size(), move(aOnSuccess), move(aOnFailure));
+ }
+ 
+-class ReadRecordClient : public FileIOClient
+-{
+-public:
+-  explicit ReadRecordClient(function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete)
+-    : mOnReadComplete(move(aOnReadComplete))
+-  {
+-  }
++class ReadRecordClient : public FileIOClient {
++ public:
++  explicit ReadRecordClient(
++      function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete)
++      : mOnReadComplete(move(aOnReadComplete)) {}
+ 
+-  void OnOpenComplete(Status aStatus) override
+-  {
++  void OnOpenComplete(Status aStatus) override {
+     auto err = aStatus;
+     if (aStatus != Status::kSuccess) {
+       Done(err, reinterpret_cast<const uint8_t*>(""), 0);
+     } else {
+       mFileIO->Read();
+     }
+   }
+ 
+-  void OnReadComplete(Status aStatus,
+-                      const uint8_t* aData,
+-                      uint32_t aDataSize) override
+-  {
++  void OnReadComplete(Status aStatus, const uint8_t* aData,
++                      uint32_t aDataSize) override {
+     Done(aStatus, aData, aDataSize);
+   }
+ 
+-  void OnWriteComplete(Status aStatus) override
+-  {
+-  }
++  void OnWriteComplete(Status aStatus) override {}
+ 
+-  void Do(const string& aName, Host_9* aHost)
+-  {
++  void Do(const string& aName, Host_9* aHost) {
+     mFileIO = aHost->CreateFileIO(this);
+     mFileIO->Open(aName.c_str(), aName.size());
+   }
+ 
+-private:
+-  void Done(cdm::FileIOClient::Status aStatus,
+-            const uint8_t* aData,
+-            uint32_t aDataSize)
+-  {
++ private:
++  void Done(cdm::FileIOClient::Status aStatus, const uint8_t* aData,
++            uint32_t aDataSize) {
+     // Note: Call Close() before running continuation, in case the
+     // continuation tries to open the same record; if we call Close()
+     // after running the continuation, the Close() call will arrive
+     // just after the Open() call succeeds, immediately closing the
+     // record we just opened.
+     if (mFileIO) {
+       // will delete mFileIO inside Close.
+       mFileIO->Close();
+@@ -170,59 +132,44 @@ private:
+ 
+     delete this;
+   }
+ 
+   FileIO* mFileIO = nullptr;
+   function<void(bool, const uint8_t*, uint32_t)> mOnReadComplete;
+ };
+ 
+-void
+-ReadRecord(Host_9* aHost,
+-           const std::string& aRecordName,
+-           function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete)
+-{
++void ReadRecord(
++    Host_9* aHost, const std::string& aRecordName,
++    function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete) {
+   // client will be delete in ReadRecordClient::Done
+   ReadRecordClient* client = new ReadRecordClient(move(aOnReadComplete));
+   client->Do(aRecordName, aHost);
+ }
+ 
+-class OpenRecordClient : public FileIOClient
+-{
+-public:
++class OpenRecordClient : public FileIOClient {
++ public:
+   explicit OpenRecordClient(function<void(bool)>&& aOpenComplete)
+-    : mOpenComplete(move(aOpenComplete))
+-  {
+-  }
++      : mOpenComplete(move(aOpenComplete)) {}
+ 
+-  void OnOpenComplete(Status aStatus) override
+-  {
+-    Done(aStatus);
+-  }
++  void OnOpenComplete(Status aStatus) override { Done(aStatus); }
+ 
+-  void OnReadComplete(Status aStatus,
+-                      const uint8_t* aData,
+-                      uint32_t aDataSize) override
+-  {
+-  }
++  void OnReadComplete(Status aStatus, const uint8_t* aData,
++                      uint32_t aDataSize) override {}
+ 
+-  void OnWriteComplete(Status aStatus) override
+-  {
+-  }
++  void OnWriteComplete(Status aStatus) override {}
+ 
+-  void Do(const string& aName, Host_9* aHost)
+-  {
++  void Do(const string& aName, Host_9* aHost) {
+     // Initialize the FileIO.
+     mFileIO = aHost->CreateFileIO(this);
+     mFileIO->Open(aName.c_str(), aName.size());
+   }
+ 
+-private:
+-  void Done(cdm::FileIOClient::Status aStatus)
+-  {
++ private:
++  void Done(cdm::FileIOClient::Status aStatus) {
+     // Note: Call Close() before running continuation, in case the
+     // continuation tries to open the same record; if we call Close()
+     // after running the continuation, the Close() call will arrive
+     // just after the Open() call succeeds, immediately closing the
+     // record we just opened.
+     if (mFileIO) {
+       // will delete mFileIO inside Close.
+       mFileIO->Close();
+@@ -233,20 +180,18 @@ private:
+     } else {
+       mOpenComplete(false);
+     }
+ 
+     delete this;
+   }
+ 
+   FileIO* mFileIO = nullptr;
+-  function<void(bool)> mOpenComplete;;
++  function<void(bool)> mOpenComplete;
++  ;
+ };
+ 
+-void
+-OpenRecord(Host_9* aHost,
+-           const std::string& aRecordName,
+-           function<void(bool)>&& aOpenComplete)
+-{
++void OpenRecord(Host_9* aHost, const std::string& aRecordName,
++                function<void(bool)>&& aOpenComplete) {
+   // client will be delete in OpenRecordClient::Done
+   OpenRecordClient* client = new OpenRecordClient(move(aOpenComplete));
+   client->Do(aRecordName, aHost);
+ }
+diff --git a/dom/media/fake-cdm/cdm-test-storage.h b/dom/media/fake-cdm/cdm-test-storage.h
+--- a/dom/media/fake-cdm/cdm-test-storage.h
++++ b/dom/media/fake-cdm/cdm-test-storage.h
+@@ -13,42 +13,36 @@
+ // on Unix systems.
+ #include "stddef.h"
+ #include "content_decryption_module.h"
+ 
+ #define IO_SUCCEEDED(x) ((x) == cdm::FileIOClient::Status::kSuccess)
+ #define IO_FAILED(x) ((x) != cdm::FileIOClient::Status::kSuccess)
+ 
+ class ReadContinuation {
+-public:
++ public:
+   virtual ~ReadContinuation() {}
+-  virtual void operator()(bool aSuccess,
+-                          const uint8_t* aData,
++  virtual void operator()(bool aSuccess, const uint8_t* aData,
+                           uint32_t aDataSize) = 0;
+ };
+ 
+-void WriteRecord(cdm::Host_9* aHost,
+-                 const std::string& aRecordName,
+-                 const std::string& aData,
++void WriteRecord(cdm::Host_9* aHost, const std::string& aRecordName,
++                 const std::string& aData, std::function<void()>&& aOnSuccess,
++                 std::function<void()>&& aOnFailure);
++
++void WriteRecord(cdm::Host_9* aHost, const std::string& aRecordName,
++                 const uint8_t* aData, uint32_t aNumBytes,
+                  std::function<void()>&& aOnSuccess,
+                  std::function<void()>&& aOnFailure);
+ 
+-void WriteRecord(cdm::Host_9* aHost,
+-                 const std::string& aRecordName,
+-                 const uint8_t* aData,
+-                 uint32_t aNumBytes,
+-                 std::function<void()>&& aOnSuccess,
+-                 std::function<void()>&& aOnFailure);
+-
+-void ReadRecord(cdm::Host_9* aHost,
+-                const std::string& aRecordName,
+-                std::function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete);
++void ReadRecord(
++    cdm::Host_9* aHost, const std::string& aRecordName,
++    std::function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete);
+ 
+ class OpenContinuation {
+-public:
++ public:
+   virtual ~OpenContinuation() {}
+   virtual void operator()(bool aSuccess) = 0;
+ };
+ 
+-void OpenRecord(cdm::Host_9* aHost,
+-                const std::string& aRecordName,
++void OpenRecord(cdm::Host_9* aHost, const std::string& aRecordName,
+                 std::function<void(bool)>&& aOpenComplete);
+-#endif // TEST_CDM_STORAGE_H__
++#endif  // TEST_CDM_STORAGE_H__

+ 7 - 7
mozilla-release/patches/1252998-04-61a1.patch

@@ -2,7 +2,7 @@
 # User Andrea Marchesini <amarchesini@mozilla.com>
 # Date 1524068352 -7200
 # Node ID f60bc2fa25660c571283eb63c3475aff4566f2ac
-# Parent  313adff3650da9454622a05349bf71f80303b33a
+# Parent  e110b07e0444c83e19376b3cf20ee27962962461
 Bug 1252998 - StorageActivityService - part 4 - Introduce ServiceWorkerCleanUp.jsm to clean up ServiceWorker data, r=asuth
 
 diff --git a/browser/components/extensions/ext-browsingData.js b/browser/components/extensions/ext-browsingData.js
@@ -285,7 +285,7 @@ diff --git a/dom/interfaces/base/nsIServiceWorkerManager.idl b/dom/interfaces/ba
 diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/ServiceWorkerManager.cpp
 --- a/dom/serviceworkers/ServiceWorkerManager.cpp
 +++ b/dom/serviceworkers/ServiceWorkerManager.cpp
-@@ -94,17 +94,16 @@
+@@ -92,17 +92,16 @@
  
  using namespace mozilla;
  using namespace mozilla::dom;
@@ -303,7 +303,7 @@ diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/Se
                "RequestMode enumeration value should match Necko CORS mode value.");
  static_assert(nsIHttpChannelInternal::CORS_MODE_CORS == static_cast<uint32_t>(RequestMode::Cors),
                "RequestMode enumeration value should match Necko CORS mode value.");
-@@ -284,18 +283,16 @@ ServiceWorkerManager::Init(ServiceWorker
+@@ -282,18 +281,16 @@ ServiceWorkerManager::Init(ServiceWorker
      MOZ_DIAGNOSTIC_ASSERT(aRegistrar);
  
      nsTArray<ServiceWorkerRegistrationData> data;
@@ -322,7 +322,7 @@ diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/Se
    PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread();
    if (NS_WARN_IF(!actorChild)) {
      MaybeStartShutdown();
-@@ -406,17 +403,16 @@ ServiceWorkerManager::MaybeStartShutdown
+@@ -404,17 +401,16 @@ ServiceWorkerManager::MaybeStartShutdown
      it1.UserData()->mJobQueues.Clear();
    }
  
@@ -340,13 +340,13 @@ diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/Se
      return;
    }
  
-@@ -3264,24 +3260,16 @@ ServiceWorkerManager::ForceUnregister(Re
+@@ -3263,24 +3259,16 @@ ServiceWorkerManager::ForceUnregister(Re
      entry.Data()->Cancel();
      entry.Remove();
    }
  
    // Since Unregister is async, it is ok to call it in an enumeration.
-   Unregister(aRegistration->mPrincipal, nullptr, NS_ConvertUTF8toUTF16(aRegistration->mScope));
+   Unregister(aRegistration->Principal(), nullptr, NS_ConvertUTF8toUTF16(aRegistration->Scope()));
  }
  
 -NS_IMETHODIMP
@@ -365,7 +365,7 @@ diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/Se
    for (auto it1 = mRegistrationInfos.Iter(); !it1.Done(); it1.Next()) {
      ServiceWorkerManager::RegistrationDataPerPrincipal* data = it1.UserData();
      for (auto it2 = data->mInfos.Iter(); !it2.Done(); it2.Next()) {
-@@ -3384,23 +3372,16 @@ ServiceWorkerManager::RemoveListener(nsI
+@@ -3383,23 +3371,16 @@ ServiceWorkerManager::RemoveListener(nsI
    return NS_OK;
  }
  

+ 177 - 0
mozilla-release/patches/1401359-59a1.patch

@@ -0,0 +1,177 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1513871427 18000
+# Node ID 950d56123c676ddb5f1630aba0e1fb78451eba97
+# Parent  19767a5982fba2eeb379391356c26d38b966d266
+Bug 1401359 Disable SharedWorker if in windows that cannot access storage. r=baku
+
+diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
+--- a/dom/workers/RuntimeService.cpp
++++ b/dom/workers/RuntimeService.cpp
+@@ -2450,16 +2450,41 @@ RuntimeService::CreateSharedWorker(const
+                                    const nsAString& aName,
+                                    SharedWorker** aSharedWorker)
+ {
+   AssertIsOnMainThread();
+ 
+   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
+   MOZ_ASSERT(window);
+ 
++  // If the window is blocked from accessing storage, do not allow it
++  // to connect to a SharedWorker.  This would potentially allow it
++  // to communicate with other windows that do have storage access.
++  // Allow private browsing, however, as we handle that isolation
++  // via the principal.
++  auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window);
++  if (storageAllowed != nsContentUtils::StorageAccess::eAllow &&
++      storageAllowed != nsContentUtils::StorageAccess::ePrivateBrowsing) {
++    return NS_ERROR_DOM_SECURITY_ERR;
++  }
++
++  // Assert that the principal private browsing state matches the
++  // StorageAccess value.
++#ifdef  MOZ_DIAGNOSTIC_ASSERT_ENABLED
++  if (storageAllowed == nsContentUtils::StorageAccess::ePrivateBrowsing) {
++    nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
++    nsCOMPtr<nsIPrincipal> principal = doc ? doc->NodePrincipal() : nullptr;
++    uint32_t privateBrowsingId = 0;
++    if (principal) {
++      MOZ_ALWAYS_SUCCEEDS(principal->GetPrivateBrowsingId(&privateBrowsingId));
++    }
++    MOZ_DIAGNOSTIC_ASSERT(privateBrowsingId != 0);
++  }
++#endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED
++
+   JSContext* cx = aGlobal.Context();
+ 
+   WorkerLoadInfo loadInfo;
+   nsresult rv = WorkerPrivate::GetLoadInfo(cx, window, nullptr, aScriptURL,
+                                            false,
+                                            WorkerPrivate::OverrideLoadGroup,
+                                            WorkerTypeShared, &loadInfo);
+   NS_ENSURE_SUCCESS(rv, rv);
+diff --git a/dom/workers/test/mochitest.ini b/dom/workers/test/mochitest.ini
+--- a/dom/workers/test/mochitest.ini
++++ b/dom/workers/test/mochitest.ini
+@@ -51,16 +51,17 @@ support-files =
+   onLine_worker_head.js
+   promise_worker.js
+   recursion_worker.js
+   recursiveOnerror_worker.js
+   redirect_to_foreign.sjs
+   rvals_worker.js
+   sharedWorker_console.js
+   sharedWorker_sharedWorker.js
++  sharedWorker_thirdparty_frame.html
+   simpleThread_worker.js
+   suspend_window.html
+   suspend_worker.js
+   terminate_worker.js
+   test_csp.html^headers^
+   test_csp.js
+   referrer_worker.html
+   threadErrors_worker1.js
+@@ -167,16 +168,17 @@ support-files =
+ [test_promise.html]
+ [test_promise_resolved_with_string.html]
+ [test_recursion.html]
+ [test_recursiveOnerror.html]
+ [test_resolveWorker.html]
+ [test_resolveWorker-assignment.html]
+ [test_rvals.html]
+ [test_sharedWorker.html]
++[test_sharedWorker_thirdparty.html]
+ [test_simpleThread.html]
+ [test_suspend.html]
+ [test_terminate.html]
+ [test_threadErrors.html]
+ [test_threadTimeouts.html]
+ [test_throwingOnerror.html]
+ [test_timeoutTracing.html]
+ [test_transferable.html]
+diff --git a/dom/workers/test/sharedWorker_thirdparty_frame.html b/dom/workers/test/sharedWorker_thirdparty_frame.html
+new file mode 100644
+--- /dev/null
++++ b/dom/workers/test/sharedWorker_thirdparty_frame.html
+@@ -0,0 +1,16 @@
++<!DOCTYPE HTML>
++<script>
++  let params = new URLSearchParams(document.location.search.substring(1));
++  let name = params.get('name');
++  try {
++    let worker = new SharedWorker('sharedWorker_sharedWorker.js',
++                                  { name: name });
++    worker.port.addEventListener('message', evt => {
++      parent.postMessage( { name: name, result: 'allowed' }, '*');
++    }, { once: true });
++    worker.port.start();
++    worker.port.postMessage('ping');
++  } catch(e) {
++    parent.postMessage({ name: name, result: 'blocked' }, '*');
++  }
++</script>
+diff --git a/dom/workers/test/test_sharedWorker_thirdparty.html b/dom/workers/test/test_sharedWorker_thirdparty.html
+new file mode 100644
+--- /dev/null
++++ b/dom/workers/test/test_sharedWorker_thirdparty.html
+@@ -0,0 +1,60 @@
++<!--
++  Any copyright is dedicated to the Public Domain.
++  http://creativecommons.org/publicdomain/zero/1.0/
++-->
++<!DOCTYPE HTML>
++<html>
++<head>
++  <title>Test for SharedWorker in 3rd Party Iframes</title>
++  <script src="/tests/SimpleTest/SimpleTest.js"> </script>
++  <script src="/tests/SimpleTest/SpawnTask.js"> </script>
++  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
++</head>
++<body>
++  <p id="display"></p>
++  <div id="content" style="display: none"></div>
++  <pre id="test">
++  <script class="testbody">
++
++  function testThirdPartyFrame(name) {
++    return new Promise(resolve => {
++      let frame = document.createElement('iframe');
++      frame.src =
++        'http://example.org/tests/dom/workers/test/sharedWorker_thirdparty_frame.html?name=' + name;
++      document.body.appendChild(frame);
++      window.addEventListener('message', function messageListener(evt) {
++        if (evt.data.name !== name) {
++          return;
++        }
++        frame.remove();
++        window.removeEventListener('message', messageListener);
++        resolve(evt.data.result);
++      });
++    });
++  }
++
++  const COOKIE_BEHAVIOR_ACCEPT        = 0;
++  const COOKIE_BEHAVIOR_REJECTFOREIGN = 1;
++
++  add_task(async function allowed() {
++    await SpecialPowers.pushPrefEnv({ set: [
++      ["network.cookie.cookieBehavior", COOKIE_BEHAVIOR_ACCEPT]
++    ]});
++    let result = await testThirdPartyFrame('allowed');
++    ok(result === 'allowed',
++       'SharedWorker should be allowed when 3rd party iframes can access storage');
++  });
++
++  add_task(async function blocked() {
++    await SpecialPowers.pushPrefEnv({ set: [
++      ["network.cookie.cookieBehavior", COOKIE_BEHAVIOR_REJECTFOREIGN]
++    ]});
++    let result = await testThirdPartyFrame('blocked');
++    ok(result === 'blocked',
++       'SharedWorker should not be allowed when 3rd party iframes are denied storage');
++  });
++
++  </script>
++  </pre>
++</body>
++</html>

+ 103 - 0
mozilla-release/patches/1422316-59a1.patch

@@ -0,0 +1,103 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1513616370 -3600
+# Node ID bb89831b9aadfc4b6d736b89d781a5c04b35f369
+# Parent  c0cd3d66a2e7ef8b4770fce5522a2d78318bc112
+Bug 1422316 - WorkerJSRuntime::Shutdown must call the base class ::Shutdown method, f=yoric, r=bkelly
+
+diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
+--- a/dom/workers/RuntimeService.cpp
++++ b/dom/workers/RuntimeService.cpp
+@@ -988,16 +988,18 @@ public:
+     }
+   }
+ 
+   void Shutdown(JSContext* cx) override
+   {
+     // The CC is shut down, and the superclass destructor will GC, so make sure
+     // we don't try to CC again.
+     mWorkerPrivate = nullptr;
++
++    CycleCollectedJSRuntime::Shutdown(cx);
+   }
+ 
+   ~WorkerJSRuntime()
+   {
+     MOZ_COUNT_DTOR_INHERITED(WorkerJSRuntime, CycleCollectedJSRuntime);
+   }
+ 
+   virtual void
+diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp
+--- a/xpcom/base/CycleCollectedJSRuntime.cpp
++++ b/xpcom/base/CycleCollectedJSRuntime.cpp
+@@ -508,16 +508,19 @@ CycleCollectedJSRuntime::CycleCollectedJ
+   , mJSZoneCycleCollectorGlobal(sJSZoneCycleCollectorGlobal)
+   , mJSRuntime(JS_GetRuntime(aCx))
+   , mHasPendingIdleGCTask(false)
+   , mPrevGCSliceCallback(nullptr)
+   , mPrevGCNurseryCollectionCallback(nullptr)
+   , mJSHolderMap(256)
+   , mOutOfMemoryState(OOMState::OK)
+   , mLargeAllocationFailureState(OOMState::OK)
++#ifdef DEBUG
++  , mShutdownCalled(false)
++#endif
+ {
+   MOZ_COUNT_CTOR(CycleCollectedJSRuntime);
+   MOZ_ASSERT(aCx);
+   MOZ_ASSERT(mJSRuntime);
+ 
+   if (!JS_AddExtraGCRootsTracer(aCx, TraceBlackJS, this)) {
+     MOZ_CRASH("JS_AddExtraGCRootsTracer failed");
+   }
+@@ -555,22 +558,26 @@ CycleCollectedJSRuntime::CycleCollectedJ
+   JS::dbg::SetDebuggerMallocSizeOf(aCx, moz_malloc_size_of);
+ }
+ 
+ void
+ CycleCollectedJSRuntime::Shutdown(JSContext* cx)
+ {
+   JS_RemoveExtraGCRootsTracer(cx, TraceBlackJS, this);
+   JS_RemoveExtraGCRootsTracer(cx, TraceGrayJS, this);
++#ifdef DEBUG
++  mShutdownCalled = true;
++#endif
+ }
+ 
+ CycleCollectedJSRuntime::~CycleCollectedJSRuntime() {
+   MOZ_COUNT_DTOR(CycleCollectedJSRuntime);
+   MOZ_ASSERT(!mDeferredFinalizerTable.Count());
+   MOZ_ASSERT(!mFinalizeRunnable);
++  MOZ_ASSERT(mShutdownCalled);
+ }
+ 
+ void
+ CycleCollectedJSRuntime::AddContext(CycleCollectedJSContext* aContext)
+ {
+   mContexts.insertBack(aContext);
+ }
+ 
+diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h
+--- a/xpcom/base/CycleCollectedJSRuntime.h
++++ b/xpcom/base/CycleCollectedJSRuntime.h
+@@ -361,16 +361,20 @@ private:
+     mPreservedNurseryObjects;
+ 
+   nsTHashtable<nsPtrHashKey<JS::Zone>> mZonesWaitingForGC;
+ 
+   struct EnvironmentPreparer : public js::ScriptEnvironmentPreparer {
+     void invoke(JS::HandleObject scope, Closure& closure) override;
+   };
+   EnvironmentPreparer mEnvironmentPreparer;
++
++#ifdef DEBUG
++  bool mShutdownCalled;
++#endif
+ };
+ 
+ void TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer);
+ 
+ // Returns true if the JS::TraceKind is one the cycle collector cares about.
+ inline bool AddToCCKind(JS::TraceKind aKind)
+ {
+   return aKind == JS::TraceKind::Object ||

+ 94 - 0
mozilla-release/patches/1431184-60a1.patch

@@ -0,0 +1,94 @@
+# HG changeset patch
+# User Markus Stange <mstange@themasta.com>
+# Date 1516836027 18000
+# Node ID 296ef6baf20b73d754ea7053ace0a4f1749cb4e3
+# Parent  c1ced18856e8fa12804b72c10cc78aa6fb9d3606
+Bug 1431184 - Register DOM Worker threads with the profiler for their entire lifetime, not just for the ranges during which they're running a worker script. r=froydnj
+
+Our Web Worker code uses a thread pool where a single OS thread can be reused
+for different worker scripts during its lifetime. Before this patch, we only
+registered these threads with the profiler for the duration that they're
+running a worker script. So the same OS thread could be registered with the
+profiler during multiple disjoint time ranges, and we would expect the profiler
+to treat those different registrations as different conceptual threads.
+
+This had multiple advantages:
+ - The "thread name" of the conceptual thread can include the script URL:
+   "DOM Worker <scriptURL>". This allowed you to create thread filter which
+   match a part of the URL, so you had the option of profiling just the worker
+   threads you were interested in.
+ - We wouldn't waste time sampling a worker thread while it's idle and has no
+   script.
+
+But it also had disadvantages:
+ - The profiler platform doesn't actually know how to deal with different
+   "conceptual threads" that share the same OS thread. This lead to surprising
+   breakage in different places. For example, the contents in the profiler
+   buffer are marked with ThreadId entries which use the OS thread id.
+ - What we show in the profiler UI didn't not match reality, and might be
+   confusing to some people.
+
+I don't think the advantages are large enough to warrant teaching the rest of
+the profiler platform to deal with conceptual threads. So this change makes us
+stop doing the special thing and just register the OS threads for their entire
+duration.
+
+MozReview-Commit-ID: 82RtlRlwy3Y
+
+diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
+--- a/dom/workers/RuntimeService.cpp
++++ b/dom/workers/RuntimeService.cpp
+@@ -2831,27 +2831,21 @@ LogViolationDetailsRunnable::MainThreadR
+   return true;
+ }
+ 
+ NS_IMPL_ISUPPORTS_INHERITED0(WorkerThreadPrimaryRunnable, Runnable)
+ 
+ NS_IMETHODIMP
+ WorkerThreadPrimaryRunnable::Run()
+ {
++  AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(
++    "WorkerThreadPrimaryRunnable::Run", OTHER, mWorkerPrivate->ScriptURL());
++
+   using mozilla::ipc::BackgroundChild;
+ 
+-  NS_SetCurrentThreadName("DOM Worker");
+-
+-  nsAutoCString threadName;
+-  threadName.AssignLiteral("DOM Worker '");
+-  threadName.Append(NS_LossyConvertUTF16toASCII(mWorkerPrivate->ScriptURL()));
+-  threadName.Append('\'');
+-
+-  AUTO_PROFILER_REGISTER_THREAD(threadName.get());
+-
+   // Note: GetOrCreateForCurrentThread() must be called prior to
+   //       mWorkerPrivate->SetThread() in order to avoid accidentally consuming
+   //       worker messages here.
+   if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread())) {
+     // XXX need to fire an error at parent.
+     // Failed in creating BackgroundChild: probably in shutdown. Continue to run
+     // without BackgroundChild created.
+   }
+diff --git a/dom/workers/WorkerThread.cpp b/dom/workers/WorkerThread.cpp
+--- a/dom/workers/WorkerThread.cpp
++++ b/dom/workers/WorkerThread.cpp
+@@ -88,17 +88,17 @@ WorkerThread::~WorkerThread()
+   MOZ_ASSERT(mAcceptingNonWorkerRunnables);
+ }
+ 
+ // static
+ already_AddRefed<WorkerThread>
+ WorkerThread::Create(const WorkerThreadFriendKey& /* aKey */)
+ {
+   RefPtr<WorkerThread> thread = new WorkerThread();
+-  if (NS_FAILED(thread->Init())) {
++  if (NS_FAILED(thread->Init(NS_LITERAL_CSTRING("DOM Worker")))) {
+     NS_WARNING("Failed to create new thread!");
+     return nullptr;
+   }
+ 
+   return thread.forget();
+ }
+ 
+ void
+

+ 25 - 0
mozilla-release/patches/1433276-1-60a1.patch

@@ -0,0 +1,25 @@
+# HG changeset patch
+# User Joel Maher <jmaher@mozilla.com>
+# Date 1517046576 18000
+# Node ID 9d96681c74f2e059d7e9607731823f59ef524dcb
+# Parent  ea8ee59ac289800ac9ec0f4ece04c0589623027e
+Bug 1433276 - adjust non-e10s test scheduling. r=ahal
+
+diff --git a/layout/reftests/selection/reftest.list b/layout/reftests/selection/reftest.list
+--- a/layout/reftests/selection/reftest.list
++++ b/layout/reftests/selection/reftest.list
+@@ -43,11 +43,11 @@ fuzzy-if(OSX==1010,9,1) fuzzy-if(OSX&&sk
+ == invalidation-1e.html invalidation-1-ref.html
+ == invalidation-1f.html invalidation-1-ref.html
+ == invalidation-2a.html invalidation-2-ref.html
+ == invalidation-2b.html invalidation-2-ref.html
+ == invalidation-2c.html invalidation-2-ref.html
+ == invalidation-2d.html invalidation-2-ref.html
+ == invalidation-2e.html invalidation-2-ref.html
+ == invalidation-2f.html invalidation-2-ref.html
+-fuzzy(7,2) fuzzy-if(OSX,1,1) fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&isDebugBuild&&!browserIsRemote) fails-if(Android) needs-focus == rtl-selection-with-decoration.html rtl-selection-with-decoration-ref.html
+-fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&isDebugBuild&&!browserIsRemote) fails-if(Android) needs-focus == semitransparent-decoration-line.html semitransparent-decoration-line-ref.html
+-fuzzy-if(OSX,1,6) fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&isDebugBuild&&!browserIsRemote) fails-if(Android) needs-focus == writing-mode.html writing-mode-ref.html
++fuzzy(7,2) fuzzy-if(OSX,1,1) fails-if(isDebugBuild&&!browserIsRemote) fails-if(Android) needs-focus == rtl-selection-with-decoration.html rtl-selection-with-decoration-ref.html
++fails-if(isDebugBuild&&!browserIsRemote) fails-if(Android) needs-focus == semitransparent-decoration-line.html semitransparent-decoration-line-ref.html
++fuzzy-if(OSX,1,6) fails-if(isDebugBuild&&!browserIsRemote) fails-if(Android) needs-focus == writing-mode.html writing-mode-ref.html

+ 28 - 0
mozilla-release/patches/1433276-2-60a1.patch

@@ -0,0 +1,28 @@
+# HG changeset patch
+# User Joel Maher <jmaher@mozilla.com>
+# Date 1517077551 18000
+# Node ID 1d32e08b9e1404c273b4e2700410c9305c28817a
+# Parent  ca73f9471eded208cbf1206f22e0fe9f10550497
+Bug 1433276 - skip serviceworker test temporarily as it fails on linux32 non e10s. r=me, a=testonly
+
+diff --git a/dom/serviceworkers/test/mochitest.ini b/dom/serviceworkers/test/mochitest.ini
+--- a/dom/serviceworkers/test/mochitest.ini
++++ b/dom/serviceworkers/test/mochitest.ini
+@@ -336,15 +336,16 @@ tags = openwindow
+ [test_strict_mode_warning.html]
+ [test_third_party_iframes.html]
+ [test_unregister.html]
+ [test_unresolved_fetch_interception.html]
+ [test_update_missing_imported_script.html]
+ [test_workerUnregister.html]
+ [test_workerUpdate.html]
+ [test_workerupdatefoundevent.html]
++skip-if = !e10s # Bug 1433276
+ [test_xslt.html]
+ [test_async_waituntil.html]
+ [test_worker_reference_gc_timeout.html]
+ [test_nofetch_handler.html]
+ [test_bad_script_cache.html]
+ [test_file_upload.html]
+ support-files = script_file_upload.js sw_file_upload.js server_file_upload.sjs
+

+ 547 - 0
mozilla-release/patches/1433505-1-60a1.patch

@@ -0,0 +1,547 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517416189 28800
+# Node ID f1ce51d14559a76fe6a6cae74b40431824880c20
+# Parent  2bda1bbb8d22eacccdb4ca5a997b32507a1f9f9a
+Bug 1433505 P1 Add the ServiceWorkerRegistrationDescriptor and backing IPC type. r=asuth
+
+diff --git a/dom/serviceworkers/IPCServiceWorkerRegistrationDescriptor.ipdlh b/dom/serviceworkers/IPCServiceWorkerRegistrationDescriptor.ipdlh
+new file mode 100644
+--- /dev/null
++++ b/dom/serviceworkers/IPCServiceWorkerRegistrationDescriptor.ipdlh
+@@ -0,0 +1,34 @@
++/* 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 PBackgroundSharedTypes;
++include IPCServiceWorkerDescriptor;
++
++using ServiceWorkerUpdateViaCache from "mozilla/dom/ServiceWorkerIPCUtils.h";
++
++namespace mozilla {
++namespace dom {
++
++// IPC type with enough information to create a ServiceWorker DOM object
++// in a child process.  Note that the state may be slightly out-of-sync
++// with the parent and should be updated dynamically if necessary.
++struct IPCServiceWorkerRegistrationDescriptor
++{
++  // These values should match the principal and scope in each
++  // associated worker.  It may be possible to optimize in the future,
++  // but for now we duplicate the information here to ensure correctness.
++  // Its possible we may need to reference a registration before the
++  // worker is installed yet, etc.
++  PrincipalInfo principalInfo;
++  nsCString scope;
++
++  ServiceWorkerUpdateViaCache updateViaCache;
++
++  OptionalIPCServiceWorkerDescriptor installing;
++  OptionalIPCServiceWorkerDescriptor waiting;
++  OptionalIPCServiceWorkerDescriptor active;
++};
++
++} // namespace dom
++} // namespace mozilla
+diff --git a/dom/serviceworkers/ServiceWorkerDescriptor.h b/dom/serviceworkers/ServiceWorkerDescriptor.h
+--- a/dom/serviceworkers/ServiceWorkerDescriptor.h
++++ b/dom/serviceworkers/ServiceWorkerDescriptor.h
+@@ -20,17 +20,17 @@ class IPCServiceWorkerDescriptor;
+ enum class ServiceWorkerState : uint8_t;
+ 
+ // This class represents a snapshot of a particular ServiceWorkerInfo object.
+ // It is threadsafe and can be transferred across processes.  This is useful
+ // because most of its values are immutable and can be relied upon to be
+ // accurate. Currently the only variable field is the ServiceWorkerState.
+ class ServiceWorkerDescriptor final
+ {
+-  // This class is largely a wrapper wround an IPDL generated struct.  We
++  // This class is largely a wrapper around an IPDL generated struct.  We
+   // need the wrapper class since IPDL generated code includes windows.h
+   // which is in turn incompatible with bindings code.
+   UniquePtr<IPCServiceWorkerDescriptor> mData;
+ 
+ public:
+   ServiceWorkerDescriptor(uint64_t aId,
+                           nsIPrincipal* aPrincipal,
+                           const nsACString& aScope,
+diff --git a/dom/serviceworkers/ServiceWorkerIPCUtils.h b/dom/serviceworkers/ServiceWorkerIPCUtils.h
+--- a/dom/serviceworkers/ServiceWorkerIPCUtils.h
++++ b/dom/serviceworkers/ServiceWorkerIPCUtils.h
+@@ -2,22 +2,34 @@
+ /* 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/. */
+ #ifndef _mozilla_dom_ServiceWorkerIPCUtils_h
+ #define _mozilla_dom_ServiceWorkerIPCUtils_h
+ 
+ #include "ipc/IPCMessageUtils.h"
++
++// Undo X11/X.h's definition of None
++#undef None
++
+ #include "mozilla/dom/ServiceWorkerBinding.h"
++#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
+ 
+ namespace IPC {
+ 
+   template<>
+   struct ParamTraits<mozilla::dom::ServiceWorkerState> :
+     public ContiguousEnumSerializer<mozilla::dom::ServiceWorkerState,
+                                     mozilla::dom::ServiceWorkerState::Parsed,
+                                     mozilla::dom::ServiceWorkerState::EndGuard_>
+   {};
+ 
++  template<>
++  struct ParamTraits<mozilla::dom::ServiceWorkerUpdateViaCache> :
++    public ContiguousEnumSerializer<mozilla::dom::ServiceWorkerUpdateViaCache,
++                                    mozilla::dom::ServiceWorkerUpdateViaCache::Imports,
++                                    mozilla::dom::ServiceWorkerUpdateViaCache::EndGuard_>
++  {};
++
+ } // namespace IPC
+ 
+ #endif // _mozilla_dom_ServiceWorkerIPCUtils_h
+diff --git a/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp
+new file mode 100644
+--- /dev/null
++++ b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp
+@@ -0,0 +1,269 @@
++/* -*- 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 "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
++#include "mozilla/ipc/PBackgroundSharedTypes.h"
++#include "ServiceWorkerInfo.h"
++
++namespace mozilla {
++namespace dom {
++
++Maybe<IPCServiceWorkerDescriptor>
++ServiceWorkerRegistrationDescriptor::NewestInternal() const
++{
++  Maybe<IPCServiceWorkerDescriptor> result;
++  if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
++    result.emplace(mData->installing().get_IPCServiceWorkerDescriptor());
++  } else if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
++    result.emplace(mData->waiting().get_IPCServiceWorkerDescriptor());
++  } else if (mData->active().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
++    result.emplace(mData->active().get_IPCServiceWorkerDescriptor());
++  }
++  return Move(result);
++}
++
++ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
++                                    nsIPrincipal* aPrincipal,
++                                    const nsACString& aScope,
++                                    ServiceWorkerUpdateViaCache aUpdateViaCache)
++  : mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>())
++{
++  MOZ_ALWAYS_SUCCEEDS(
++    PrincipalToPrincipalInfo(aPrincipal, &mData->principalInfo()));
++
++  mData->scope() = aScope;
++  mData->updateViaCache() = aUpdateViaCache;
++  mData->installing() = void_t();
++  mData->waiting() = void_t();
++  mData->active() = void_t();
++}
++
++ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
++                                    const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
++                                    const nsACString& aScope,
++                                    ServiceWorkerUpdateViaCache aUpdateViaCache)
++  : mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>(aPrincipalInfo,
++                                                             nsCString(aScope),
++                                                             aUpdateViaCache,
++                                                             void_t(),
++                                                             void_t(),
++                                                             void_t()))
++{
++}
++
++ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(const IPCServiceWorkerRegistrationDescriptor& aDescriptor)
++  : mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>(aDescriptor))
++{
++  MOZ_DIAGNOSTIC_ASSERT(IsValid());
++}
++
++ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(const ServiceWorkerRegistrationDescriptor& aRight)
++{
++  // UniquePtr doesn't have a default copy constructor, so we can't rely
++  // on default copy construction.  Use the assignment operator to
++  // minimize duplication.
++  operator=(aRight);
++}
++
++ServiceWorkerRegistrationDescriptor&
++ServiceWorkerRegistrationDescriptor::operator=(const ServiceWorkerRegistrationDescriptor& aRight)
++{
++  mData.reset();
++  mData = MakeUnique<IPCServiceWorkerRegistrationDescriptor>(*aRight.mData);
++  MOZ_DIAGNOSTIC_ASSERT(IsValid());
++  return *this;
++}
++
++ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(ServiceWorkerRegistrationDescriptor&& aRight)
++  : mData(Move(aRight.mData))
++{
++  MOZ_DIAGNOSTIC_ASSERT(IsValid());
++}
++
++ServiceWorkerRegistrationDescriptor&
++ServiceWorkerRegistrationDescriptor::operator=(ServiceWorkerRegistrationDescriptor&& aRight)
++{
++  mData.reset();
++  mData = Move(aRight.mData);
++  MOZ_DIAGNOSTIC_ASSERT(IsValid());
++  return *this;
++}
++
++bool
++ServiceWorkerRegistrationDescriptor::operator==(const ServiceWorkerRegistrationDescriptor& aRight) const
++{
++  return *mData == *aRight.mData;
++}
++
++ServiceWorkerUpdateViaCache
++ServiceWorkerRegistrationDescriptor::UpdateViaCache() const
++{
++  return mData->updateViaCache();
++}
++
++const mozilla::ipc::PrincipalInfo&
++ServiceWorkerRegistrationDescriptor::PrincipalInfo() const
++{
++  return mData->principalInfo();
++}
++
++const nsCString&
++ServiceWorkerRegistrationDescriptor::Scope() const
++{
++  return mData->scope();
++}
++
++Maybe<ServiceWorkerDescriptor>
++ServiceWorkerRegistrationDescriptor::GetInstalling() const
++{
++  Maybe<ServiceWorkerDescriptor> result;
++
++  if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
++    result.emplace(ServiceWorkerDescriptor(
++      mData->installing().get_IPCServiceWorkerDescriptor()));
++  }
++
++  return Move(result);
++}
++
++Maybe<ServiceWorkerDescriptor>
++ServiceWorkerRegistrationDescriptor::GetWaiting() const
++{
++  Maybe<ServiceWorkerDescriptor> result;
++
++  if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
++    result.emplace(ServiceWorkerDescriptor(
++      mData->waiting().get_IPCServiceWorkerDescriptor()));
++  }
++
++  return Move(result);
++}
++
++Maybe<ServiceWorkerDescriptor>
++ServiceWorkerRegistrationDescriptor::GetActive() const
++{
++  Maybe<ServiceWorkerDescriptor> result;
++
++  if (mData->active().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
++    result.emplace(ServiceWorkerDescriptor(
++      mData->active().get_IPCServiceWorkerDescriptor()));
++  }
++
++  return Move(result);
++}
++
++Maybe<ServiceWorkerDescriptor>
++ServiceWorkerRegistrationDescriptor::Newest() const
++{
++  Maybe<ServiceWorkerDescriptor> result;
++  Maybe<IPCServiceWorkerDescriptor> newest(NewestInternal());
++  if (newest.isSome()) {
++    result.emplace(ServiceWorkerDescriptor(newest.ref()));
++  }
++  return Move(result);
++}
++
++namespace {
++
++bool
++IsValidWorker(const OptionalIPCServiceWorkerDescriptor& aWorker,
++              const nsACString& aScope,
++              const mozilla::ipc::ContentPrincipalInfo& aContentPrincipal)
++{
++  if (aWorker.type() == OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
++    return true;
++  }
++
++  auto& worker = aWorker.get_IPCServiceWorkerDescriptor();
++  if (worker.scope() != aScope) {
++    return false;
++  }
++
++  auto& principalInfo = worker.principalInfo();
++  if (principalInfo.type() != mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
++    return false;
++  }
++
++  auto& contentPrincipal = principalInfo.get_ContentPrincipalInfo();
++  if (contentPrincipal.originNoSuffix() != aContentPrincipal.originNoSuffix() ||
++      contentPrincipal.attrs() != aContentPrincipal.attrs()) {
++    return false;
++  }
++
++  return true;
++}
++
++} // anonymous namespace
++
++bool
++ServiceWorkerRegistrationDescriptor::IsValid() const
++{
++  auto& principalInfo = PrincipalInfo();
++  if (principalInfo.type() != mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
++    return false;
++  }
++
++  auto& contentPrincipal = principalInfo.get_ContentPrincipalInfo();
++  if (!IsValidWorker(mData->installing(), Scope(), contentPrincipal) ||
++      !IsValidWorker(mData->waiting(), Scope(), contentPrincipal) ||
++      !IsValidWorker(mData->active(), Scope(), contentPrincipal)) {
++    return false;
++  }
++
++  return true;
++}
++
++void
++ServiceWorkerRegistrationDescriptor::SetUpdateViaCache(ServiceWorkerUpdateViaCache aUpdateViaCache)
++{
++  mData->updateViaCache() = aUpdateViaCache;
++}
++
++void
++ServiceWorkerRegistrationDescriptor::SetWorkers(ServiceWorkerInfo* aInstalling,
++                                                ServiceWorkerInfo* aWaiting,
++                                                ServiceWorkerInfo* aActive)
++{
++  if (aInstalling) {
++    mData->installing() = aInstalling->Descriptor().ToIPC();
++  } else {
++    mData->installing() = void_t();
++  }
++
++  if (aWaiting) {
++    mData->waiting() = aWaiting->Descriptor().ToIPC();
++  } else {
++    mData->waiting() = void_t();
++  }
++
++  if (aActive) {
++    mData->active() = aActive->Descriptor().ToIPC();
++  } else {
++    mData->active() = void_t();
++  }
++
++  MOZ_DIAGNOSTIC_ASSERT(IsValid());
++}
++
++void
++ServiceWorkerRegistrationDescriptor::SetWorkers(OptionalIPCServiceWorkerDescriptor& aInstalling,
++                                                OptionalIPCServiceWorkerDescriptor& aWaiting,
++                                                OptionalIPCServiceWorkerDescriptor& aActive)
++{
++  mData->installing() = aInstalling;
++  mData->waiting() = aWaiting;
++  mData->active() = aActive;
++  MOZ_DIAGNOSTIC_ASSERT(IsValid());
++}
++
++const IPCServiceWorkerRegistrationDescriptor&
++ServiceWorkerRegistrationDescriptor::ToIPC() const
++{
++  return *mData;
++}
++
++} // namespace dom
++} // namespace mozilla
+diff --git a/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.h b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.h
+new file mode 100644
+--- /dev/null
++++ b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.h
+@@ -0,0 +1,110 @@
++/* -*- 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/. */
++#ifndef _mozilla_dom_ServiceWorkerRegistrationDescriptor_h
++#define _mozilla_dom_ServiceWorkerRegistrationDescriptor_h
++
++#include "mozilla/Maybe.h"
++#include "mozilla/dom/IPCServiceWorkerRegistrationDescriptor.h"
++#include "mozilla/dom/ServiceWorkerDescriptor.h"
++#include "mozilla/UniquePtr.h"
++
++namespace mozilla {
++
++namespace ipc {
++class PrincipalInfo;
++} // namespace ipc
++
++namespace dom {
++
++class IPCServiceWorkerRegistrationDescriptor;
++class ServiceWorkerInfo;
++enum class ServiceWorkerUpdateViaCache : uint8_t;
++
++// This class represents a snapshot of a particular
++// ServiceWorkerRegistrationInfo object. It is threadsafe and can be
++// transferred across processes.
++class ServiceWorkerRegistrationDescriptor final
++{
++  // This class is largely a wrapper wround an IPDL generated struct.  We
++  // need the wrapper class since IPDL generated code includes windows.h
++  // which is in turn incompatible with bindings code.
++  UniquePtr<IPCServiceWorkerRegistrationDescriptor> mData;
++
++  Maybe<IPCServiceWorkerDescriptor>
++  NewestInternal() const;
++
++public:
++  ServiceWorkerRegistrationDescriptor(nsIPrincipal* aPrincipal,
++                                      const nsACString& aScope,
++                                      ServiceWorkerUpdateViaCache aUpdateViaCache);
++
++  ServiceWorkerRegistrationDescriptor(const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
++                                      const nsACString& aScope,
++                                      ServiceWorkerUpdateViaCache aUpdateViaCache);
++
++  explicit ServiceWorkerRegistrationDescriptor(const IPCServiceWorkerRegistrationDescriptor& aDescriptor);
++
++  ServiceWorkerRegistrationDescriptor(const ServiceWorkerRegistrationDescriptor& aRight);
++
++  ServiceWorkerRegistrationDescriptor&
++  operator=(const ServiceWorkerRegistrationDescriptor& aRight);
++
++  ServiceWorkerRegistrationDescriptor(ServiceWorkerRegistrationDescriptor&& aRight);
++
++  ServiceWorkerRegistrationDescriptor&
++  operator=(ServiceWorkerRegistrationDescriptor&& aRight);
++
++  ~ServiceWorkerRegistrationDescriptor() = default;
++
++  bool
++  operator==(const ServiceWorkerRegistrationDescriptor& aRight) const;
++
++  ServiceWorkerUpdateViaCache
++  UpdateViaCache() const;
++
++  const mozilla::ipc::PrincipalInfo&
++  PrincipalInfo() const;
++
++  const nsCString&
++  Scope() const;
++
++  Maybe<ServiceWorkerDescriptor>
++  GetInstalling() const;
++
++  Maybe<ServiceWorkerDescriptor>
++  GetWaiting() const;
++
++  Maybe<ServiceWorkerDescriptor>
++  GetActive() const;
++
++  Maybe<ServiceWorkerDescriptor>
++  Newest() const;
++
++  bool
++  IsValid() const;
++
++  void
++  SetUpdateViaCache(ServiceWorkerUpdateViaCache aUpdateViaCache);
++
++  void
++  SetWorkers(ServiceWorkerInfo* aInstalling,
++             ServiceWorkerInfo* aWaiting,
++             ServiceWorkerInfo* aActive);
++
++  void
++  SetWorkers(OptionalIPCServiceWorkerDescriptor& aInstalling,
++             OptionalIPCServiceWorkerDescriptor& aWaiting,
++             OptionalIPCServiceWorkerDescriptor& aActive);
++
++  // Expose the underlying IPC type so that it can be passed via IPC.
++  const IPCServiceWorkerRegistrationDescriptor&
++  ToIPC() const;
++};
++
++} // namespace dom
++} // namespace mozilla
++
++#endif // _mozilla_dom_ServiceWorkerRegistrationDescriptor_h
+diff --git a/dom/serviceworkers/moz.build b/dom/serviceworkers/moz.build
+--- a/dom/serviceworkers/moz.build
++++ b/dom/serviceworkers/moz.build
+@@ -17,16 +17,17 @@ EXPORTS.mozilla.dom += [
+     'ServiceWorkerInfo.h',
+     'ServiceWorkerInterceptController.h',
+     'ServiceWorkerIPCUtils.h',
+     'ServiceWorkerManager.h',
+     'ServiceWorkerManagerChild.h',
+     'ServiceWorkerManagerParent.h',
+     'ServiceWorkerRegistrar.h',
+     'ServiceWorkerRegistration.h',
++    'ServiceWorkerRegistrationDescriptor.h',
+     'ServiceWorkerRegistrationInfo.h',
+     'ServiceWorkerUtils.h',
+ ]
+ 
+ UNIFIED_SOURCES += [
+     'ServiceWorker.cpp',
+     'ServiceWorkerContainer.cpp',
+     'ServiceWorkerDescriptor.cpp',
+@@ -38,27 +39,29 @@ UNIFIED_SOURCES += [
+     'ServiceWorkerManager.cpp',
+     'ServiceWorkerManagerChild.cpp',
+     'ServiceWorkerManagerParent.cpp',
+     'ServiceWorkerManagerService.cpp',
+     'ServiceWorkerPrivate.cpp',
+     'ServiceWorkerRegisterJob.cpp',
+     'ServiceWorkerRegistrar.cpp',
+     'ServiceWorkerRegistration.cpp',
++    'ServiceWorkerRegistrationDescriptor.cpp',
+     'ServiceWorkerRegistrationInfo.cpp',
+     'ServiceWorkerScriptCache.cpp',
+     'ServiceWorkerUnregisterJob.cpp',
+     'ServiceWorkerUpdateJob.cpp',
+     'ServiceWorkerUpdaterChild.cpp',
+     'ServiceWorkerUpdaterParent.cpp',
+     'ServiceWorkerUtils.cpp',
+ ]
+ 
+ IPDL_SOURCES += [
+     'IPCServiceWorkerDescriptor.ipdlh',
++    'IPCServiceWorkerRegistrationDescriptor.ipdlh',
+     'PServiceWorkerManager.ipdl',
+     'PServiceWorkerUpdater.ipdl',
+     'ServiceWorkerRegistrarTypes.ipdlh',
+ ]
+ 
+ include('/ipc/chromium/chromium-config.mozbuild')
+ 
+ FINAL_LIBRARY = 'xul'
+

+ 895 - 0
mozilla-release/patches/1433505-2-60a1.patch

@@ -0,0 +1,895 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517416189 28800
+# Node ID db69a6d02a9d27f56c0ef5a77805161f50b33f88
+# Parent  f1ce51d14559a76fe6a6cae74b40431824880c20
+Bug 1433505 P2 Make various class members on ServiceWorkerRegistrationInfo private. r=asuth
+
+diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/ServiceWorkerManager.cpp
+--- a/dom/serviceworkers/ServiceWorkerManager.cpp
++++ b/dom/serviceworkers/ServiceWorkerManager.cpp
+@@ -187,17 +187,17 @@ PopulateRegistrationData(nsIPrincipal* a
+     return NS_ERROR_FAILURE;
+   }
+ 
+   nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &aData.principal());
+   if (NS_WARN_IF(NS_FAILED(rv))) {
+     return rv;
+   }
+ 
+-  aData.scope() = aRegistration->mScope;
++  aData.scope() = aRegistration->Scope();
+ 
+   RefPtr<ServiceWorkerInfo> newest = aRegistration->Newest();
+   if (NS_WARN_IF(!newest)) {
+     return NS_ERROR_FAILURE;
+   }
+ 
+   if (aRegistration->GetActive()) {
+     aData.currentWorkerURL() = aRegistration->GetActive()->ScriptSpec();
+@@ -460,17 +460,17 @@ class ServiceWorkerResolveWindowPromiseO
+     }
+ 
+     MOZ_ASSERT(aJob->GetType() == ServiceWorkerJob::Type::Register);
+     RefPtr<ServiceWorkerRegisterJob> registerJob =
+       static_cast<ServiceWorkerRegisterJob*>(aJob);
+     RefPtr<ServiceWorkerRegistrationInfo> reg = registerJob->GetRegistration();
+ 
+     RefPtr<ServiceWorkerRegistration> swr =
+-      window->GetServiceWorkerRegistration(NS_ConvertUTF8toUTF16(reg->mScope));
++      window->GetServiceWorkerRegistration(NS_ConvertUTF8toUTF16(reg->Scope()));
+     promise->MaybeResolve(swr);
+   }
+ 
+ public:
+   ServiceWorkerResolveWindowPromiseOnRegisterCallback(nsPIDOMWindowInner* aWindow,
+                                                       Promise* aPromise)
+     : mPromise(aWindow, aPromise)
+   {}
+@@ -998,17 +998,17 @@ public:
+     if (!swm->mRegistrationInfos.Get(scopeKey, &data)) {
+       mPromise->MaybeResolve(array);
+       return NS_OK;
+     }
+ 
+     for (uint32_t i = 0; i < data->mOrderedScopes.Length(); ++i) {
+       RefPtr<ServiceWorkerRegistrationInfo> info =
+         data->mInfos.GetWeak(data->mOrderedScopes[i]);
+-      if (info->mPendingUninstall) {
++      if (info->IsPendingUninstall()) {
+         continue;
+       }
+ 
+       NS_ConvertUTF8toUTF16 scope(data->mOrderedScopes[i]);
+ 
+       nsCOMPtr<nsIURI> scopeURI;
+       nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), scope, nullptr, nullptr);
+       if (NS_WARN_IF(NS_FAILED(rv))) {
+@@ -1141,17 +1141,17 @@ public:
+     RefPtr<ServiceWorkerRegistrationInfo> registration =
+       swm->GetServiceWorkerRegistrationInfo(principal, uri);
+ 
+     if (!registration) {
+       mPromise->MaybeResolveWithUndefined();
+       return NS_OK;
+     }
+ 
+-    NS_ConvertUTF8toUTF16 scope(registration->mScope);
++    NS_ConvertUTF8toUTF16 scope(registration->Scope());
+     RefPtr<ServiceWorkerRegistration> swr =
+       mWindow->GetServiceWorkerRegistration(scope);
+     mPromise->MaybeResolve(swr);
+ 
+     return NS_OK;
+   }
+ };
+ 
+@@ -1458,17 +1458,17 @@ ServiceWorkerManager::CheckReadyPromise(
+ 
+   nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
+   MOZ_ASSERT(principal);
+ 
+   RefPtr<ServiceWorkerRegistrationInfo> registration =
+     GetServiceWorkerRegistrationInfo(principal, aURI);
+ 
+   if (registration && registration->GetActive()) {
+-    NS_ConvertUTF8toUTF16 scope(registration->mScope);
++    NS_ConvertUTF8toUTF16 scope(registration->Scope());
+     RefPtr<ServiceWorkerRegistration> swr =
+       aWindow->GetServiceWorkerRegistration(scope);
+     aPromise->MaybeResolve(swr);
+     return true;
+   }
+ 
+   return false;
+ }
+@@ -1646,17 +1646,17 @@ ServiceWorkerManager::WorkerIsIdle(Servi
+   if (!reg) {
+     return;
+   }
+ 
+   if (reg->GetActive() != aWorker) {
+     return;
+   }
+ 
+-  if (!reg->IsControllingClients() && reg->mPendingUninstall) {
++  if (!reg->IsControllingClients() && reg->IsPendingUninstall()) {
+     RemoveRegistration(reg);
+     return;
+   }
+ 
+   reg->TryToActivateAsync();
+ }
+ 
+ already_AddRefed<ServiceWorkerJobQueue>
+@@ -1835,18 +1835,18 @@ ServiceWorkerManager::LoadRegistration(
+   importsLoadFlags |=
+     aRegistration.updateViaCache() == static_cast<uint16_t>(ServiceWorkerUpdateViaCache::None)
+       ? nsIRequest::LOAD_NORMAL
+       : nsIRequest::VALIDATE_ALWAYS;
+ 
+   const nsCString& currentWorkerURL = aRegistration.currentWorkerURL();
+   if (!currentWorkerURL.IsEmpty()) {
+     registration->SetActive(
+-      new ServiceWorkerInfo(registration->mPrincipal,
+-                            registration->mScope,
++      new ServiceWorkerInfo(registration->Principal(),
++                            registration->Scope(),
+                             currentWorkerURL,
+                             aRegistration.cacheName(),
+                             importsLoadFlags));
+     registration->GetActive()->SetHandlesFetch(aRegistration.currentWorkerHandlesFetch());
+     registration->GetActive()->SetInstalledTime(aRegistration.currentWorkerInstalledTime());
+     registration->GetActive()->SetActivatedTime(aRegistration.currentWorkerActivatedTime());
+   }
+ }
+@@ -1957,22 +1957,22 @@ ServiceWorkerManager::GetServiceWorkerRe
+ 
+   RefPtr<ServiceWorkerRegistrationInfo> registration;
+   data->mInfos.Get(scope, getter_AddRefs(registration));
+   // ordered scopes and registrations better be in sync.
+   MOZ_ASSERT(registration);
+ 
+ #ifdef DEBUG
+   nsAutoCString origin;
+-  rv = registration->mPrincipal->GetOrigin(origin);
++  rv = registration->Principal()->GetOrigin(origin);
+   MOZ_ASSERT(NS_SUCCEEDED(rv));
+   MOZ_ASSERT(origin.Equals(aScopeKey));
+ #endif
+ 
+-  if (registration->mPendingUninstall) {
++  if (registration->IsPendingUninstall()) {
+     return nullptr;
+   }
+   return registration.forget();
+ }
+ 
+ /* static */ nsresult
+ ServiceWorkerManager::PrincipalToScopeKey(nsIPrincipal* aPrincipal,
+                                           nsACString& aKey)
+@@ -2010,26 +2010,26 @@ ServiceWorkerManager::PrincipalInfoToSco
+   return NS_OK;
+ }
+ 
+ /* static */ void
+ ServiceWorkerManager::AddScopeAndRegistration(const nsACString& aScope,
+                                               ServiceWorkerRegistrationInfo* aInfo)
+ {
+   MOZ_ASSERT(aInfo);
+-  MOZ_ASSERT(aInfo->mPrincipal);
++  MOZ_ASSERT(aInfo->Principal());
+ 
+   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+   if (!swm) {
+     // browser shutdown
+     return;
+   }
+ 
+   nsAutoCString scopeKey;
+-  nsresult rv = swm->PrincipalToScopeKey(aInfo->mPrincipal, scopeKey);
++  nsresult rv = swm->PrincipalToScopeKey(aInfo->Principal(), scopeKey);
+   if (NS_WARN_IF(NS_FAILED(rv))) {
+     return;
+   }
+ 
+   MOZ_ASSERT(!scopeKey.IsEmpty());
+ 
+   RegistrationDataPerPrincipal* data =
+     swm->mRegistrationInfos.LookupForAdd(scopeKey).OrInsert(
+@@ -2113,46 +2113,46 @@ ServiceWorkerManager::HasScope(nsIPrinci
+ ServiceWorkerManager::RemoveScopeAndRegistration(ServiceWorkerRegistrationInfo* aRegistration)
+ {
+   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+   if (!swm) {
+     return;
+   }
+ 
+   nsAutoCString scopeKey;
+-  nsresult rv = swm->PrincipalToScopeKey(aRegistration->mPrincipal, scopeKey);
++  nsresult rv = swm->PrincipalToScopeKey(aRegistration->Principal(), scopeKey);
+   if (NS_WARN_IF(NS_FAILED(rv))) {
+     return;
+   }
+ 
+   RegistrationDataPerPrincipal* data;
+   if (!swm->mRegistrationInfos.Get(scopeKey, &data)) {
+     return;
+   }
+ 
+-  if (auto entry = data->mUpdateTimers.Lookup(aRegistration->mScope)) {
++  if (auto entry = data->mUpdateTimers.Lookup(aRegistration->Scope())) {
+     entry.Data()->Cancel();
+     entry.Remove();
+   }
+ 
+   // Verify there are no controlled clients for the purged registration.
+   for (auto iter = swm->mControlledClients.Iter(); !iter.Done(); iter.Next()) {
+     auto& reg = iter.UserData()->mRegistrationInfo;
+-    if (reg->mScope.Equals(aRegistration->mScope) &&
+-        reg->mPrincipal->Equals(aRegistration->mPrincipal)) {
++    if (reg->Scope().Equals(aRegistration->Scope()) &&
++        reg->Principal()->Equals(aRegistration->Principal())) {
+       MOZ_DIAGNOSTIC_ASSERT(false,
+                             "controlled client when removing registration");
+       iter.Remove();
+       break;
+     }
+   }
+ 
+   RefPtr<ServiceWorkerRegistrationInfo> info;
+-  data->mInfos.Remove(aRegistration->mScope, getter_AddRefs(info));
+-  data->mOrderedScopes.RemoveElement(aRegistration->mScope);
++  data->mInfos.Remove(aRegistration->Scope(), getter_AddRefs(info));
++  data->mOrderedScopes.RemoveElement(aRegistration->Scope());
+   swm->NotifyListenersOnUnregister(info);
+ 
+   swm->MaybeRemoveRegistrationInfo(scopeKey);
+   swm->NotifyServiceWorkerRegistrationRemoved(aRegistration);
+ }
+ 
+ void
+ ServiceWorkerManager::MaybeRemoveRegistrationInfo(const nsACString& aScopeKey)
+@@ -2211,17 +2211,17 @@ ServiceWorkerManager::MaybeCheckNavigati
+ void
+ ServiceWorkerManager::StopControllingRegistration(ServiceWorkerRegistrationInfo* aRegistration)
+ {
+   aRegistration->StopControllingClient();
+   if (aRegistration->IsControllingClients() || !aRegistration->IsIdle()) {
+     return;
+   }
+ 
+-  if (aRegistration->mPendingUninstall) {
++  if (aRegistration->IsPendingUninstall()) {
+     RemoveRegistration(aRegistration);
+     return;
+   }
+ 
+   // We use to aggressively terminate the worker at this point, but it
+   // caused problems.  There are more uses for a service worker than actively
+   // controlled documents.  We need to let the worker naturally terminate
+   // in case its handling push events, message events, etc.
+@@ -2241,17 +2241,17 @@ ServiceWorkerManager::GetScopeForUrl(nsI
+   }
+ 
+   RefPtr<ServiceWorkerRegistrationInfo> r =
+     GetServiceWorkerRegistrationInfo(aPrincipal, uri);
+   if (!r) {
+       return NS_ERROR_FAILURE;
+   }
+ 
+-  aScope = NS_ConvertUTF8toUTF16(r->mScope);
++  aScope = NS_ConvertUTF8toUTF16(r->Scope());
+   return NS_OK;
+ }
+ 
+ NS_IMETHODIMP
+ ServiceWorkerManager::AddRegistrationEventListener(const nsAString& aScope,
+                                                    ServiceWorkerRegistrationListener* aListener)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+@@ -2297,17 +2297,17 @@ ServiceWorkerManager::FireUpdateFoundOnS
+   nsTObserverArray<ServiceWorkerRegistrationListener*>::ForwardIterator it(mServiceWorkerRegistrationListeners);
+   while (it.HasMore()) {
+     RefPtr<ServiceWorkerRegistrationListener> target = it.GetNext();
+     nsAutoString regScope;
+     target->GetScope(regScope);
+     MOZ_ASSERT(!regScope.IsEmpty());
+ 
+     NS_ConvertUTF16toUTF8 utf8Scope(regScope);
+-    if (utf8Scope.Equals(aRegistration->mScope)) {
++    if (utf8Scope.Equals(aRegistration->Scope())) {
+       target->UpdateFound();
+     }
+   }
+ }
+ 
+ /*
+  * This is used for installing, waiting and active.
+  */
+@@ -2664,17 +2664,17 @@ ServiceWorkerManager::TransitionServiceW
+   while (it.HasMore()) {
+     RefPtr<ServiceWorkerRegistrationListener> target = it.GetNext();
+     nsAutoString regScope;
+     target->GetScope(regScope);
+     MOZ_ASSERT(!regScope.IsEmpty());
+ 
+     NS_ConvertUTF16toUTF8 utf8Scope(regScope);
+ 
+-    if (utf8Scope.Equals(aRegistration->mScope)) {
++    if (utf8Scope.Equals(aRegistration->Scope())) {
+       target->TransitionWorker(aWhichOne);
+     }
+   }
+ }
+ 
+ void
+ ServiceWorkerManager::InvalidateServiceWorkerRegistrationWorker(ServiceWorkerRegistrationInfo* aRegistration,
+                                                                 WhichServiceWorker aWhichOnes)
+@@ -2684,17 +2684,17 @@ ServiceWorkerManager::InvalidateServiceW
+   while (it.HasMore()) {
+     RefPtr<ServiceWorkerRegistrationListener> target = it.GetNext();
+     nsAutoString regScope;
+     target->GetScope(regScope);
+     MOZ_ASSERT(!regScope.IsEmpty());
+ 
+     NS_ConvertUTF16toUTF8 utf8Scope(regScope);
+ 
+-    if (utf8Scope.Equals(aRegistration->mScope)) {
++    if (utf8Scope.Equals(aRegistration->Scope())) {
+       target->InvalidateWorkers(aWhichOnes);
+     }
+   }
+ }
+ 
+ void
+ ServiceWorkerManager::NotifyServiceWorkerRegistrationRemoved(ServiceWorkerRegistrationInfo* aRegistration)
+ {
+@@ -2703,17 +2703,17 @@ ServiceWorkerManager::NotifyServiceWorke
+   while (it.HasMore()) {
+     RefPtr<ServiceWorkerRegistrationListener> target = it.GetNext();
+     nsAutoString regScope;
+     target->GetScope(regScope);
+     MOZ_ASSERT(!regScope.IsEmpty());
+ 
+     NS_ConvertUTF16toUTF8 utf8Scope(regScope);
+ 
+-    if (utf8Scope.Equals(aRegistration->mScope)) {
++    if (utf8Scope.Equals(aRegistration->Scope())) {
+       target->RegistrationRemoved();
+     }
+   }
+ }
+ 
+ void
+ ServiceWorkerManager::SoftUpdate(const OriginAttributes& aOriginAttributes,
+                                  const nsACString& aScope)
+@@ -2811,17 +2811,17 @@ ServiceWorkerManager::SoftUpdateInternal
+ 
+   RefPtr<ServiceWorkerRegistrationInfo> registration =
+     GetRegistration(scopeKey, aScope);
+   if (NS_WARN_IF(!registration)) {
+     return;
+   }
+ 
+   // "If registration's uninstalling flag is set, abort these steps."
+-  if (registration->mPendingUninstall) {
++  if (registration->IsPendingUninstall()) {
+     return;
+   }
+ 
+   // "If registration's installing worker is not null, abort these steps."
+   if (registration->GetInstalling()) {
+     return;
+   }
+ 
+@@ -2836,17 +2836,17 @@ ServiceWorkerManager::SoftUpdateInternal
+   // "If the registration queue for registration is empty, invoke Update algorithm,
+   // or its equivalent, with client, registration as its argument."
+   // TODO(catalinb): We don't implement the force bypass cache flag.
+   // See: https://github.com/slightlyoff/ServiceWorker/issues/759
+   RefPtr<ServiceWorkerJobQueue> queue = GetOrCreateJobQueue(scopeKey,
+                                                             aScope);
+ 
+   RefPtr<ServiceWorkerUpdateJob> job =
+-    new ServiceWorkerUpdateJob(principal, registration->mScope,
++    new ServiceWorkerUpdateJob(principal, registration->Scope(),
+                                newest->ScriptSpec(), nullptr,
+                                registration->GetUpdateViaCache());
+ 
+   RefPtr<UpdateJobCallback> cb = new UpdateJobCallback(aCallback);
+   job->AppendResultCallback(cb);
+ 
+   queue->ScheduleJob(job);
+ }
+@@ -2911,17 +2911,17 @@ ServiceWorkerManager::UpdateInternal(nsI
+     return;
+   }
+ 
+   RefPtr<ServiceWorkerJobQueue> queue = GetOrCreateJobQueue(scopeKey, aScope);
+ 
+   // "Invoke Update algorithm, or its equivalent, with client, registration as
+   // its argument."
+   RefPtr<ServiceWorkerUpdateJob> job =
+-    new ServiceWorkerUpdateJob(aPrincipal, registration->mScope,
++    new ServiceWorkerUpdateJob(aPrincipal, registration->Scope(),
+                                newest->ScriptSpec(), nullptr,
+                                registration->GetUpdateViaCache());
+ 
+   RefPtr<UpdateJobCallback> cb = new UpdateJobCallback(aCallback);
+   job->AppendResultCallback(cb);
+ 
+   queue->ScheduleJob(job);
+ }
+@@ -2931,17 +2931,17 @@ ServiceWorkerManager::MaybeClaimClient(n
+                                        ServiceWorkerRegistrationInfo* aWorkerRegistration)
+ {
+   MOZ_DIAGNOSTIC_ASSERT(aWorkerRegistration);
+   MOZ_DIAGNOSTIC_ASSERT(aWorkerRegistration->GetActive());
+ 
+   RefPtr<GenericPromise> ref;
+ 
+   // Same origin check
+-  if (!aWorkerRegistration->mPrincipal->Equals(aDocument->NodePrincipal())) {
++  if (!aWorkerRegistration->Principal()->Equals(aDocument->NodePrincipal())) {
+     ref = GenericPromise::CreateAndReject(NS_ERROR_DOM_SECURITY_ERR, __func__);
+     return ref.forget();
+   }
+ 
+   Maybe<ClientInfo> clientInfo(aDocument->GetClientInfo());
+   if (NS_WARN_IF(clientInfo.isNothing())) {
+     ref = GenericPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR,
+                                           __func__);
+@@ -3139,17 +3139,17 @@ ServiceWorkerManager::CreateNewRegistrat
+   return registration.forget();
+ }
+ 
+ void
+ ServiceWorkerManager::MaybeRemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration)
+ {
+   MOZ_ASSERT(aRegistration);
+   RefPtr<ServiceWorkerInfo> newest = aRegistration->Newest();
+-  if (!newest && HasScope(aRegistration->mPrincipal, aRegistration->mScope)) {
++  if (!newest && HasScope(aRegistration->Principal(), aRegistration->Scope())) {
+     RemoveRegistration(aRegistration);
+   }
+ }
+ 
+ void
+ ServiceWorkerManager::RemoveRegistration(ServiceWorkerRegistrationInfo* aRegistration)
+ {
+   // Note, we do not need to call mActor->SendUnregister() here.  There are a few
+@@ -3160,20 +3160,20 @@ ServiceWorkerManager::RemoveRegistration
+   //    starting unregister jobs which in turn call SendUnregister().
+   // 3) Through the failure to install a new service worker.  Since we don't store
+   //    the registration until install succeeds, we do not need to call
+   //    SendUnregister here.
+   // Assert these conditions by testing for pending uninstall (cases 1 and 2) or
+   // null workers (case 3).
+ #ifdef DEBUG
+   RefPtr<ServiceWorkerInfo> newest = aRegistration->Newest();
+-  MOZ_ASSERT(aRegistration->mPendingUninstall || !newest);
++  MOZ_ASSERT(aRegistration->IsPendingUninstall() || !newest);
+ #endif
+ 
+-  MOZ_ASSERT(HasScope(aRegistration->mPrincipal, aRegistration->mScope));
++  MOZ_ASSERT(HasScope(aRegistration->Principal(), aRegistration->Scope()));
+ 
+   // When a registration is removed, we must clear its contents since the DOM
+   // object may be held by content script.
+   aRegistration->Clear();
+ 
+   RemoveScopeAndRegistration(aRegistration);
+ }
+ 
+@@ -3231,17 +3231,17 @@ ServiceWorkerManager::GetAllRegistration
+     return NS_ERROR_OUT_OF_MEMORY;
+   }
+ 
+   for (auto it1 = mRegistrationInfos.Iter(); !it1.Done(); it1.Next()) {
+     for (auto it2 = it1.UserData()->mInfos.Iter(); !it2.Done(); it2.Next()) {
+       ServiceWorkerRegistrationInfo* reg = it2.UserData();
+       MOZ_ASSERT(reg);
+ 
+-      if (reg->mPendingUninstall) {
++      if (reg->IsPendingUninstall()) {
+         continue;
+       }
+ 
+       array->AppendElement(reg);
+     }
+   }
+ 
+   array.forget(aResult);
+@@ -3252,28 +3252,28 @@ ServiceWorkerManager::GetAllRegistration
+ void
+ ServiceWorkerManager::ForceUnregister(RegistrationDataPerPrincipal* aRegistrationData,
+                                       ServiceWorkerRegistrationInfo* aRegistration)
+ {
+   MOZ_ASSERT(aRegistrationData);
+   MOZ_ASSERT(aRegistration);
+ 
+   RefPtr<ServiceWorkerJobQueue> queue;
+-  aRegistrationData->mJobQueues.Get(aRegistration->mScope, getter_AddRefs(queue));
++  aRegistrationData->mJobQueues.Get(aRegistration->Scope(), getter_AddRefs(queue));
+   if (queue) {
+     queue->CancelAll();
+   }
+ 
+-  if (auto entry = aRegistrationData->mUpdateTimers.Lookup(aRegistration->mScope)) {
++  if (auto entry = aRegistrationData->mUpdateTimers.Lookup(aRegistration->Scope())) {
+     entry.Data()->Cancel();
+     entry.Remove();
+   }
+ 
+   // Since Unregister is async, it is ok to call it in an enumeration.
+-  Unregister(aRegistration->mPrincipal, nullptr, NS_ConvertUTF8toUTF16(aRegistration->mScope));
++  Unregister(aRegistration->Principal(), nullptr, NS_ConvertUTF8toUTF16(aRegistration->Scope()));
+ }
+ 
+ NS_IMETHODIMP
+ ServiceWorkerManager::RemoveAndPropagate(const nsACString& aHost)
+ {
+   Remove(aHost);
+   PropagateRemove(aHost);
+   return NS_OK;
+@@ -3340,20 +3340,20 @@ ServiceWorkerManager::RemoveAllRegistrat
+ 
+     // We can use iteration because ForceUnregister (and Unregister) are
+     // async. Otherwise doing some R/W operations on an hashtable during
+     // iteration will crash.
+     for (auto it2 = data->mInfos.Iter(); !it2.Done(); it2.Next()) {
+       ServiceWorkerRegistrationInfo* reg = it2.UserData();
+ 
+       MOZ_ASSERT(reg);
+-      MOZ_ASSERT(reg->mPrincipal);
++      MOZ_ASSERT(reg->Principal());
+ 
+       bool matches =
+-        aPattern->Matches(reg->mPrincipal->OriginAttributesRef());
++        aPattern->Matches(reg->Principal()->OriginAttributesRef());
+       if (!matches) {
+         continue;
+       }
+ 
+       ForceUnregister(data, reg);
+     }
+   }
+ }
+diff --git a/dom/serviceworkers/ServiceWorkerRegisterJob.cpp b/dom/serviceworkers/ServiceWorkerRegisterJob.cpp
+--- a/dom/serviceworkers/ServiceWorkerRegisterJob.cpp
++++ b/dom/serviceworkers/ServiceWorkerRegisterJob.cpp
+@@ -39,18 +39,18 @@ ServiceWorkerRegisterJob::AsyncExecute()
+   if (registration) {
+     bool sameUVC = GetUpdateViaCache() == registration->GetUpdateViaCache();
+     registration->SetUpdateViaCache(GetUpdateViaCache());
+ 
+     // If we are resurrecting an uninstalling registration, then persist
+     // it to disk again.  We preemptively removed it earlier during
+     // unregister so that closing the window by shutting down the browser
+     // results in the registration being gone on restart.
+-    if (registration->mPendingUninstall) {
+-      registration->mPendingUninstall = false;
++    if (registration->IsPendingUninstall()) {
++      registration->ClearPendingUninstall();
+       swm->StoreRegistration(mPrincipal, registration);
+       // Its possible that a ready promise is created between when the
+       // uninstalling flag is set and when we resurrect the registration
+       // here.  In that case we might need to fire the ready promise
+       // now.
+       swm->CheckPendingReadyPromises();
+     }
+     RefPtr<ServiceWorkerInfo> newest = registration->Newest();
+diff --git a/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp b/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp
+--- a/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp
++++ b/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp
+@@ -80,32 +80,62 @@ ServiceWorkerRegistrationInfo::Clear()
+ 
+   NotifyChromeRegistrationListeners();
+ }
+ 
+ ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(
+     const nsACString& aScope,
+     nsIPrincipal* aPrincipal,
+     ServiceWorkerUpdateViaCache aUpdateViaCache)
+-  : mControlledClientsCounter(0)
++  : mScope(aScope)
++  , mPrincipal(aPrincipal)
++  , mControlledClientsCounter(0)
+   , mUpdateState(NoUpdate)
+   , mCreationTime(PR_Now())
+   , mCreationTimeStamp(TimeStamp::Now())
+   , mLastUpdateTime(0)
+   , mUpdateViaCache(aUpdateViaCache)
+-  , mScope(aScope)
+-  , mPrincipal(aPrincipal)
+   , mPendingUninstall(false)
+ {}
+ 
+ ServiceWorkerRegistrationInfo::~ServiceWorkerRegistrationInfo()
+ {
+   MOZ_DIAGNOSTIC_ASSERT(!IsControllingClients());
+ }
+ 
++const nsCString&
++ServiceWorkerRegistrationInfo::Scope() const
++{
++  return mScope;
++}
++
++nsIPrincipal*
++ServiceWorkerRegistrationInfo::Principal() const
++{
++  return mPrincipal;
++}
++
++bool
++ServiceWorkerRegistrationInfo::IsPendingUninstall() const
++{
++  return mPendingUninstall;
++}
++
++void
++ServiceWorkerRegistrationInfo::SetPendingUninstall()
++{
++  mPendingUninstall = true;
++}
++
++void
++ServiceWorkerRegistrationInfo::ClearPendingUninstall()
++{
++  mPendingUninstall = false;
++}
++
+ NS_IMPL_ISUPPORTS(ServiceWorkerRegistrationInfo, nsIServiceWorkerRegistrationInfo)
+ 
+ NS_IMETHODIMP
+ ServiceWorkerRegistrationInfo::GetPrincipal(nsIPrincipal** aPrincipal)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+   NS_ADDREF(*aPrincipal = mPrincipal);
+   return NS_OK;
+diff --git a/dom/serviceworkers/ServiceWorkerRegistrationInfo.h b/dom/serviceworkers/ServiceWorkerRegistrationInfo.h
+--- a/dom/serviceworkers/ServiceWorkerRegistrationInfo.h
++++ b/dom/serviceworkers/ServiceWorkerRegistrationInfo.h
+@@ -13,16 +13,20 @@
+ #include "nsProxyRelease.h"
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ class ServiceWorkerRegistrationInfo final
+   : public nsIServiceWorkerRegistrationInfo
+ {
++  const nsCString mScope;
++  nsCOMPtr<nsIPrincipal> mPrincipal;
++  nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> mListeners;
++
+   uint32_t mControlledClientsCounter;
+ 
+   enum
+   {
+     NoUpdate,
+     NeedTimeCheckAndUpdate,
+     NeedUpdate
+   } mUpdateState;
+@@ -37,35 +41,44 @@ class ServiceWorkerRegistrationInfo fina
+ 
+   RefPtr<ServiceWorkerInfo> mEvaluatingWorker;
+   RefPtr<ServiceWorkerInfo> mActiveWorker;
+   RefPtr<ServiceWorkerInfo> mWaitingWorker;
+   RefPtr<ServiceWorkerInfo> mInstallingWorker;
+ 
+   virtual ~ServiceWorkerRegistrationInfo();
+ 
+-public:
+-  NS_DECL_ISUPPORTS
+-  NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
+-
+-  const nsCString mScope;
+-
+-  nsCOMPtr<nsIPrincipal> mPrincipal;
+-
+-  nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> mListeners;
+-
+   // When unregister() is called on a registration, it is not immediately
+   // removed since documents may be controlled. It is marked as
+   // pendingUninstall and when all controlling documents go away, removed.
+   bool mPendingUninstall;
+ 
++public:
++  NS_DECL_ISUPPORTS
++  NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
++
+   ServiceWorkerRegistrationInfo(const nsACString& aScope,
+                                 nsIPrincipal* aPrincipal,
+                                 ServiceWorkerUpdateViaCache aUpdateViaCache);
+ 
++  const nsCString&
++  Scope() const;
++
++  nsIPrincipal*
++  Principal() const;
++
++  bool
++  IsPendingUninstall() const;
++
++  void
++  SetPendingUninstall();
++
++  void
++  ClearPendingUninstall();
++
+   already_AddRefed<ServiceWorkerInfo>
+   Newest() const
+   {
+     RefPtr<ServiceWorkerInfo> newest;
+     if (mInstallingWorker) {
+       newest = mInstallingWorker;
+     } else if (mWaitingWorker) {
+       newest = mWaitingWorker;
+diff --git a/dom/serviceworkers/ServiceWorkerScriptCache.cpp b/dom/serviceworkers/ServiceWorkerScriptCache.cpp
+--- a/dom/serviceworkers/ServiceWorkerScriptCache.cpp
++++ b/dom/serviceworkers/ServiceWorkerScriptCache.cpp
+@@ -976,18 +976,18 @@ CompareNetwork::OnStreamComplete(nsIStre
+     // Get the stringified numeric status code, not statusText which could be
+     // something misleading like OK for a 404.
+     uint32_t status = 0;
+     Unused << httpChannel->GetResponseStatus(&status); // don't care if this fails, use 0.
+     nsAutoString statusAsText;
+     statusAsText.AppendInt(status);
+ 
+     ServiceWorkerManager::LocalizeAndReportToAllClients(
+-      mRegistration->mScope, "ServiceWorkerRegisterNetworkError",
+-      nsTArray<nsString> { NS_ConvertUTF8toUTF16(mRegistration->mScope),
++      mRegistration->Scope(), "ServiceWorkerRegisterNetworkError",
++      nsTArray<nsString> { NS_ConvertUTF8toUTF16(mRegistration->Scope()),
+         statusAsText, mURL });
+ 
+     rv = NS_ERROR_FAILURE;
+     return NS_OK;
+   }
+ 
+   // Note: we explicitly don't check for the return value here, because the
+   // absence of the header is not an error condition.
+@@ -1011,18 +1011,18 @@ CompareNetwork::OnStreamComplete(nsIStre
+     rv = NS_ERROR_DOM_SECURITY_ERR;
+     return rv;
+   }
+ 
+   if (!mimeType.LowerCaseEqualsLiteral("text/javascript") &&
+       !mimeType.LowerCaseEqualsLiteral("application/x-javascript") &&
+       !mimeType.LowerCaseEqualsLiteral("application/javascript")) {
+     ServiceWorkerManager::LocalizeAndReportToAllClients(
+-      mRegistration->mScope, "ServiceWorkerRegisterMimeTypeError",
+-      nsTArray<nsString> { NS_ConvertUTF8toUTF16(mRegistration->mScope),
++      mRegistration->Scope(), "ServiceWorkerRegisterMimeTypeError",
++      nsTArray<nsString> { NS_ConvertUTF8toUTF16(mRegistration->Scope()),
+         NS_ConvertUTF8toUTF16(mimeType), mURL });
+     rv = NS_ERROR_DOM_SECURITY_ERR;
+     return rv;
+   }
+ 
+   nsCOMPtr<nsIURI> channelURL;
+   rv = httpChannel->GetURI(getter_AddRefs(channelURL));
+   if (NS_WARN_IF(NS_FAILED(rv))) {
+diff --git a/dom/serviceworkers/ServiceWorkerUnregisterJob.cpp b/dom/serviceworkers/ServiceWorkerUnregisterJob.cpp
+--- a/dom/serviceworkers/ServiceWorkerUnregisterJob.cpp
++++ b/dom/serviceworkers/ServiceWorkerUnregisterJob.cpp
+@@ -115,27 +115,27 @@ ServiceWorkerUnregisterJob::Unregister()
+     swm->GetRegistration(mPrincipal, mScope);
+   if (!registration) {
+     // "If registration is null, then, resolve promise with false."
+     Finish(NS_OK);
+     return;
+   }
+ 
+   // Note, we send the message to remove the registration from disk now even
+-  // though we may only set the mPendingUninstall flag below.  This is
++  // though we may only set the pending uninstall flag below.  This is
+   // necessary to ensure the registration is removed if the controlled
+   // clients are closed by shutting down the browser.  If the registration
+-  // is resurrected by clearing mPendingUninstall then it should be saved
++  // is resurrected by clearing pending uninstall then it should be saved
+   // to disk again.
+-  if (mSendToParent && !registration->mPendingUninstall) {
++  if (mSendToParent && !registration->IsPendingUninstall()) {
+     swm->MaybeSendUnregister(mPrincipal, mScope);
+   }
+ 
+   // "Set registration's uninstalling flag."
+-  registration->mPendingUninstall = true;
++  registration->SetPendingUninstall();
+ 
+   // "Resolve promise with true"
+   mResult = true;
+   InvokeResultCallbacks(NS_OK);
+ 
+   // "If no service worker client is using registration..."
+   if (!registration->IsControllingClients() && registration->IsIdle()) {
+     // "Invoke [[Clear Registration]]..."
+diff --git a/dom/serviceworkers/ServiceWorkerUpdateJob.cpp b/dom/serviceworkers/ServiceWorkerUpdateJob.cpp
+--- a/dom/serviceworkers/ServiceWorkerUpdateJob.cpp
++++ b/dom/serviceworkers/ServiceWorkerUpdateJob.cpp
+@@ -255,17 +255,17 @@ ServiceWorkerUpdateJob::AsyncExecute()
+ 
+   // Begin step 1 of the Update algorithm.
+   //
+   //  https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#update-algorithm
+ 
+   RefPtr<ServiceWorkerRegistrationInfo> registration =
+     swm->GetRegistration(mPrincipal, mScope);
+ 
+-  if (!registration || registration->mPendingUninstall) {
++  if (!registration || registration->IsPendingUninstall()) {
+     ErrorResult rv;
+     rv.ThrowTypeError<MSG_SW_UPDATE_BAD_REGISTRATION>(NS_ConvertUTF8toUTF16(mScope),
+                                                       NS_LITERAL_STRING("uninstalled"));
+     FailUpdateJob(rv);
+     return;
+   }
+ 
+   // If a Register job with a new script executed ahead of us in the job queue,
+@@ -394,19 +394,19 @@ ServiceWorkerUpdateJob::ComparisonResult
+   if (maxScopeURI) {
+     rv = GetRequiredScopeStringPrefix(maxScopeURI, maxPrefix, eUsePath);
+     if (NS_WARN_IF(NS_FAILED(rv))) {
+       FailUpdateJob(NS_ERROR_DOM_SECURITY_ERR);
+       return;
+     }
+   }
+ 
+-  if (!StringBeginsWith(mRegistration->mScope, maxPrefix)) {
++  if (!StringBeginsWith(mRegistration->Scope(), maxPrefix)) {
+     nsAutoString message;
+-    NS_ConvertUTF8toUTF16 reportScope(mRegistration->mScope);
++    NS_ConvertUTF8toUTF16 reportScope(mRegistration->Scope());
+     NS_ConvertUTF8toUTF16 reportMaxPrefix(maxPrefix);
+     const char16_t* params[] = { reportScope.get(), reportMaxPrefix.get() };
+ 
+     rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
+                                                "ServiceWorkerScopePathMismatch",
+                                                params, message);
+     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to format localized string");
+     swm->ReportToAllClients(mScope,
+@@ -429,18 +429,18 @@ ServiceWorkerUpdateJob::ComparisonResult
+ 
+   // Begin step 7 of the Update algorithm to evaluate the new script.
+   nsLoadFlags flags = aLoadFlags;
+   if (GetUpdateViaCache() == ServiceWorkerUpdateViaCache::None) {
+     flags |= nsIRequest::VALIDATE_ALWAYS;
+   }
+ 
+   RefPtr<ServiceWorkerInfo> sw =
+-    new ServiceWorkerInfo(mRegistration->mPrincipal,
+-                          mRegistration->mScope,
++    new ServiceWorkerInfo(mRegistration->Principal(),
++                          mRegistration->Scope(),
+                           mScriptSpec,
+                           aNewCacheName,
+                           flags);
+ 
+   mRegistration->SetEvaluating(sw);
+ 
+   nsMainThreadPtrHandle<ServiceWorkerUpdateJob> handle(
+       new nsMainThreadPtrHolder<ServiceWorkerUpdateJob>(
+@@ -470,17 +470,17 @@ ServiceWorkerUpdateJob::ContinueUpdateAf
+ 
+   // Step 7.5 of the Update algorithm verifying that the script evaluated
+   // successfully.
+ 
+   if (NS_WARN_IF(!aScriptEvaluationResult)) {
+     ErrorResult error;
+ 
+     NS_ConvertUTF8toUTF16 scriptSpec(mScriptSpec);
+-    NS_ConvertUTF8toUTF16 scope(mRegistration->mScope);
++    NS_ConvertUTF8toUTF16 scope(mRegistration->Scope());
+     error.ThrowTypeError<MSG_SW_SCRIPT_THREW>(scriptSpec, scope);
+     FailUpdateJob(error);
+     return;
+   }
+ 
+   Install(swm);
+ }
+ 
+

+ 339 - 0
mozilla-release/patches/1433505-3-60a1.patch

@@ -0,0 +1,339 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517416189 28800
+# Node ID 779d1551ac9aed9460f7d92d017266c72026ae8d
+# Parent  db69a6d02a9d27f56c0ef5a77805161f50b33f88
+Bug 1433505 P3 Make ServiceWorkerRegistrationInfo use ServiceWorkerRegistrationDescriptor internally. r=asuth
+
+diff --git a/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp b/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp
+--- a/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp
++++ b/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp
+@@ -73,43 +73,44 @@ ServiceWorkerRegistrationInfo::Clear()
+ 
+   if (mActiveWorker) {
+     mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
+     mActiveWorker->UpdateRedundantTime();
+     mActiveWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
+     mActiveWorker = nullptr;
+   }
+ 
++  mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
++
+   NotifyChromeRegistrationListeners();
+ }
+ 
+ ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(
+     const nsACString& aScope,
+     nsIPrincipal* aPrincipal,
+     ServiceWorkerUpdateViaCache aUpdateViaCache)
+-  : mScope(aScope)
+-  , mPrincipal(aPrincipal)
++  : mPrincipal(aPrincipal)
++  , mDescriptor(aPrincipal, aScope, aUpdateViaCache)
+   , mControlledClientsCounter(0)
+   , mUpdateState(NoUpdate)
+   , mCreationTime(PR_Now())
+   , mCreationTimeStamp(TimeStamp::Now())
+   , mLastUpdateTime(0)
+-  , mUpdateViaCache(aUpdateViaCache)
+   , mPendingUninstall(false)
+ {}
+ 
+ ServiceWorkerRegistrationInfo::~ServiceWorkerRegistrationInfo()
+ {
+   MOZ_DIAGNOSTIC_ASSERT(!IsControllingClients());
+ }
+ 
+ const nsCString&
+ ServiceWorkerRegistrationInfo::Scope() const
+ {
+-  return mScope;
++  return mDescriptor.Scope();
+ }
+ 
+ nsIPrincipal*
+ ServiceWorkerRegistrationInfo::Principal() const
+ {
+   return mPrincipal;
+ }
+ 
+@@ -140,17 +141,17 @@ ServiceWorkerRegistrationInfo::GetPrinci
+   NS_ADDREF(*aPrincipal = mPrincipal);
+   return NS_OK;
+ }
+ 
+ NS_IMETHODIMP
+ ServiceWorkerRegistrationInfo::GetScope(nsAString& aScope)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+-  CopyUTF8toUTF16(mScope, aScope);
++  CopyUTF8toUTF16(Scope(), aScope);
+   return NS_OK;
+ }
+ 
+ NS_IMETHODIMP
+ ServiceWorkerRegistrationInfo::GetScriptSpec(nsAString& aScriptSpec)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+   RefPtr<ServiceWorkerInfo> newest = Newest();
+@@ -336,16 +337,19 @@ ServiceWorkerRegistrationInfo::FinishAct
+   if (mPendingUninstall || !mActiveWorker ||
+       mActiveWorker->State() != ServiceWorkerState::Activating) {
+     return;
+   }
+ 
+   // Activation never fails, so aSuccess is ignored.
+   mActiveWorker->UpdateState(ServiceWorkerState::Activated);
+   mActiveWorker->UpdateActivatedTime();
++
++  mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
++
+   NotifyChromeRegistrationListeners();
+ 
+   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+   if (!swm) {
+     // browser shutdown started during async activation completion step
+     return;
+   }
+   swm->StoreRegistration(mPrincipal, this);
+@@ -445,33 +449,33 @@ ServiceWorkerRegistrationInfo::MaybeSche
+     // shutting down, do nothing
+     return;
+   }
+ 
+   if (mUpdateState == NoUpdate) {
+     mUpdateState = NeedTimeCheckAndUpdate;
+   }
+ 
+-  swm->ScheduleUpdateTimer(mPrincipal, mScope);
++  swm->ScheduleUpdateTimer(mPrincipal, Scope());
+ }
+ 
+ void
+ ServiceWorkerRegistrationInfo::MaybeScheduleUpdate()
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+ 
+   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+   if (!swm) {
+     // shutting down, do nothing
+     return;
+   }
+ 
+   mUpdateState = NeedUpdate;
+ 
+-  swm->ScheduleUpdateTimer(mPrincipal, mScope);
++  swm->ScheduleUpdateTimer(mPrincipal, Scope());
+ }
+ 
+ bool
+ ServiceWorkerRegistrationInfo::CheckAndClearIfUpdateNeeded()
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+ 
+   bool result = mUpdateState == NeedUpdate ||
+@@ -567,28 +571,33 @@ ServiceWorkerRegistrationInfo::ClearInst
+   }
+ 
+   UpdateRegistrationStateProperties(WhichServiceWorker::INSTALLING_WORKER,
+                                     Invalidate);
+   mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
+   mInstallingWorker->UpdateRedundantTime();
+   mInstallingWorker = nullptr;
+ 
++  mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
++
+   NotifyChromeRegistrationListeners();
+ }
+ 
+ void
+ ServiceWorkerRegistrationInfo::TransitionEvaluatingToInstalling()
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+   MOZ_ASSERT(mEvaluatingWorker);
+   MOZ_ASSERT(!mInstallingWorker);
+ 
+   mInstallingWorker = mEvaluatingWorker.forget();
+   mInstallingWorker->UpdateState(ServiceWorkerState::Installing);
++
++  mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
++
+   NotifyChromeRegistrationListeners();
+ }
+ 
+ void
+ ServiceWorkerRegistrationInfo::TransitionInstallingToWaiting()
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+   MOZ_ASSERT(mInstallingWorker);
+@@ -599,16 +608,19 @@ ServiceWorkerRegistrationInfo::Transitio
+     mWaitingWorker->UpdateRedundantTime();
+   }
+ 
+   mWaitingWorker = mInstallingWorker.forget();
+   UpdateRegistrationStateProperties(WhichServiceWorker::INSTALLING_WORKER,
+                                     TransitionToNextState);
+   mWaitingWorker->UpdateState(ServiceWorkerState::Installed);
+   mWaitingWorker->UpdateInstalledTime();
++
++  mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
++
+   NotifyChromeRegistrationListeners();
+ 
+   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+   if (!swm) {
+     // browser shutdown began
+     return;
+   }
+   swm->StoreRegistration(mPrincipal, this);
+@@ -637,16 +649,19 @@ ServiceWorkerRegistrationInfo::SetActive
+   // The active worker is being overriden due to initial load or
+   // another process activating a worker.  Move straight to the
+   // Activated state.
+   mActiveWorker = aServiceWorker;
+   mActiveWorker->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
+   // We don't need to update activated time when we load registration from
+   // registrar.
+   UpdateRegistrationStateProperties(WhichServiceWorker::ACTIVE_WORKER, Invalidate);
++
++  mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
++
+   NotifyChromeRegistrationListeners();
+ }
+ 
+ void
+ ServiceWorkerRegistrationInfo::TransitionWaitingToActive()
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+   MOZ_ASSERT(mWaitingWorker);
+@@ -658,36 +673,39 @@ ServiceWorkerRegistrationInfo::Transitio
+   }
+ 
+   // We are transitioning from waiting to active normally, so go to
+   // the activating state.
+   mActiveWorker = mWaitingWorker.forget();
+   UpdateRegistrationStateProperties(WhichServiceWorker::WAITING_WORKER,
+                                     TransitionToNextState);
+   mActiveWorker->UpdateState(ServiceWorkerState::Activating);
++
++  mDescriptor.SetWorkers(mInstallingWorker, mWaitingWorker, mActiveWorker);
++
+   NotifyChromeRegistrationListeners();
+ }
+ 
+ bool
+ ServiceWorkerRegistrationInfo::IsIdle() const
+ {
+   return !mActiveWorker || mActiveWorker->WorkerPrivate()->IsIdle();
+ }
+ 
+ ServiceWorkerUpdateViaCache
+ ServiceWorkerRegistrationInfo::GetUpdateViaCache() const
+ {
+-  return mUpdateViaCache;
++  return mDescriptor.UpdateViaCache();
+ }
+ 
+ void
+ ServiceWorkerRegistrationInfo::SetUpdateViaCache(
+     ServiceWorkerUpdateViaCache aUpdateViaCache)
+ {
+-  mUpdateViaCache = aUpdateViaCache;
++  mDescriptor.SetUpdateViaCache(aUpdateViaCache);
+ }
+ 
+ int64_t
+ ServiceWorkerRegistrationInfo::GetLastUpdateTime() const
+ {
+   return mLastUpdateTime;
+ }
+ 
+@@ -696,10 +714,16 @@ ServiceWorkerRegistrationInfo::SetLastUp
+ {
+   if (aTime == 0) {
+     return;
+   }
+ 
+   mLastUpdateTime = aTime;
+ }
+ 
++const ServiceWorkerRegistrationDescriptor&
++ServiceWorkerRegistrationInfo::Descriptor() const
++{
++  return mDescriptor;
++}
++
+ } // namespace dom
+ } // namespace mozilla
+diff --git a/dom/serviceworkers/ServiceWorkerRegistrationInfo.h b/dom/serviceworkers/ServiceWorkerRegistrationInfo.h
+--- a/dom/serviceworkers/ServiceWorkerRegistrationInfo.h
++++ b/dom/serviceworkers/ServiceWorkerRegistrationInfo.h
+@@ -5,26 +5,27 @@
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ #ifndef mozilla_dom_serviceworkerregistrationinfo_h
+ #define mozilla_dom_serviceworkerregistrationinfo_h
+ 
+ #include "mozilla/dom/ServiceWorkerInfo.h"
+ #include "mozilla/dom/ServiceWorkerCommon.h"
+ #include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
++#include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
+ #include "nsProxyRelease.h"
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ class ServiceWorkerRegistrationInfo final
+   : public nsIServiceWorkerRegistrationInfo
+ {
+-  const nsCString mScope;
+   nsCOMPtr<nsIPrincipal> mPrincipal;
++  ServiceWorkerRegistrationDescriptor mDescriptor;
+   nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> mListeners;
+ 
+   uint32_t mControlledClientsCounter;
+ 
+   enum
+   {
+     NoUpdate,
+     NeedTimeCheckAndUpdate,
+@@ -32,18 +33,16 @@ class ServiceWorkerRegistrationInfo fina
+   } mUpdateState;
+ 
+   // Timestamp to track SWR's last update time
+   PRTime mCreationTime;
+   TimeStamp mCreationTimeStamp;
+   // The time of update is 0, if SWR've never been updated yet.
+   PRTime mLastUpdateTime;
+ 
+-  ServiceWorkerUpdateViaCache mUpdateViaCache;
+-
+   RefPtr<ServiceWorkerInfo> mEvaluatingWorker;
+   RefPtr<ServiceWorkerInfo> mActiveWorker;
+   RefPtr<ServiceWorkerInfo> mWaitingWorker;
+   RefPtr<ServiceWorkerInfo> mInstallingWorker;
+ 
+   virtual ~ServiceWorkerRegistrationInfo();
+ 
+   // When unregister() is called on a registration, it is not immediately
+@@ -205,16 +204,19 @@ public:
+   SetUpdateViaCache(ServiceWorkerUpdateViaCache aUpdateViaCache);
+ 
+   int64_t
+   GetLastUpdateTime() const;
+ 
+   void
+   SetLastUpdateTime(const int64_t aTime);
+ 
++  const ServiceWorkerRegistrationDescriptor&
++  Descriptor() const;
++
+ private:
+   enum TransitionType {
+     TransitionToNextState = 0,
+     Invalidate
+   };
+ 
+   // Queued as a runnable from UpdateRegistrationStateProperties.
+   void
+

+ 187 - 0
mozilla-release/patches/1433545-1-60a1.patch

@@ -0,0 +1,187 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517416189 28800
+#      Wed Jan 31 08:29:49 2018 -0800
+# Node ID 9be09d7a6297717ff0bf6a8637bc987c73b88658
+# Parent  779d1551ac9aed9460f7d92d017266c72026ae8d
+Bug 1433545 P1 Add scriptURL to ServiceWorkerDescriptor. r=asuth
+
+diff --git a/dom/serviceworkers/IPCServiceWorkerDescriptor.ipdlh b/dom/serviceworkers/IPCServiceWorkerDescriptor.ipdlh
+--- a/dom/serviceworkers/IPCServiceWorkerDescriptor.ipdlh
++++ b/dom/serviceworkers/IPCServiceWorkerDescriptor.ipdlh
+@@ -12,16 +12,17 @@ namespace dom {
+ // IPC type with enough information to create a ServiceWorker DOM object
+ // in a child process.  Note that the state may be slightly out-of-sync
+ // with the parent and should be updated dynamically if necessary.
+ struct IPCServiceWorkerDescriptor
+ {
+   uint64_t id;
+   PrincipalInfo principalInfo;
+   nsCString scope;
++  nsCString scriptURL;
+   ServiceWorkerState state;
+ };
+ 
+ union OptionalIPCServiceWorkerDescriptor
+ {
+   IPCServiceWorkerDescriptor;
+   void_t;
+ };
+diff --git a/dom/serviceworkers/ServiceWorkerDescriptor.cpp b/dom/serviceworkers/ServiceWorkerDescriptor.cpp
+--- a/dom/serviceworkers/ServiceWorkerDescriptor.cpp
++++ b/dom/serviceworkers/ServiceWorkerDescriptor.cpp
+@@ -10,32 +10,36 @@
+ #include "mozilla/ipc/PBackgroundSharedTypes.h"
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ ServiceWorkerDescriptor::ServiceWorkerDescriptor(uint64_t aId,
+                                                  nsIPrincipal* aPrincipal,
+                                                  const nsACString& aScope,
++                                                 const nsACString& aScriptURL,
+                                                  ServiceWorkerState aState)
+   : mData(MakeUnique<IPCServiceWorkerDescriptor>())
+ {
+   MOZ_ALWAYS_SUCCEEDS(
+     PrincipalToPrincipalInfo(aPrincipal, &mData->principalInfo()));
+ 
+   mData->id() = aId;
+   mData->scope() = aScope;
++  mData->scriptURL() = aScriptURL;
+   mData->state() = aState;
+ }
+ 
+ ServiceWorkerDescriptor::ServiceWorkerDescriptor(uint64_t aId,
+                                                  const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
+                                                  const nsACString& aScope,
++                                                 const nsACString& aScriptURL,
+                                                  ServiceWorkerState aState)
+   : mData(MakeUnique<IPCServiceWorkerDescriptor>(aId, aPrincipalInfo,
++                                                 nsCString(aScriptURL),
+                                                  nsCString(aScope), aState))
+ {
+ }
+ 
+ ServiceWorkerDescriptor::ServiceWorkerDescriptor(const IPCServiceWorkerDescriptor& aDescriptor)
+   : mData(MakeUnique<IPCServiceWorkerDescriptor>(aDescriptor))
+ {
+ }
+@@ -89,16 +93,22 @@ ServiceWorkerDescriptor::PrincipalInfo()
+ }
+ 
+ const nsCString&
+ ServiceWorkerDescriptor::Scope() const
+ {
+   return mData->scope();
+ }
+ 
++const nsCString&
++ServiceWorkerDescriptor::ScriptURL() const
++{
++  return mData->scriptURL();
++}
++
+ ServiceWorkerState
+ ServiceWorkerDescriptor::State() const
+ {
+   return mData->state();
+ }
+ 
+ void
+ ServiceWorkerDescriptor::SetState(ServiceWorkerState aState)
+diff --git a/dom/serviceworkers/ServiceWorkerDescriptor.h b/dom/serviceworkers/ServiceWorkerDescriptor.h
+--- a/dom/serviceworkers/ServiceWorkerDescriptor.h
++++ b/dom/serviceworkers/ServiceWorkerDescriptor.h
+@@ -29,21 +29,23 @@ class ServiceWorkerDescriptor final
+   // need the wrapper class since IPDL generated code includes windows.h
+   // which is in turn incompatible with bindings code.
+   UniquePtr<IPCServiceWorkerDescriptor> mData;
+ 
+ public:
+   ServiceWorkerDescriptor(uint64_t aId,
+                           nsIPrincipal* aPrincipal,
+                           const nsACString& aScope,
++                          const nsACString& aScriptURL,
+                           ServiceWorkerState aState);
+ 
+   ServiceWorkerDescriptor(uint64_t aId,
+                           const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
+                           const nsACString& aScope,
++                          const nsACString& aScriptURL,
+                           ServiceWorkerState aState);
+ 
+   explicit ServiceWorkerDescriptor(const IPCServiceWorkerDescriptor& aDescriptor);
+ 
+   ServiceWorkerDescriptor(const ServiceWorkerDescriptor& aRight);
+ 
+   ServiceWorkerDescriptor&
+   operator=(const ServiceWorkerDescriptor& aRight);
+@@ -62,16 +64,19 @@ public:
+   Id() const;
+ 
+   const mozilla::ipc::PrincipalInfo&
+   PrincipalInfo() const;
+ 
+   const nsCString&
+   Scope() const;
+ 
++  const nsCString&
++  ScriptURL() const;
++
+   ServiceWorkerState
+   State() const;
+ 
+   void
+   SetState(ServiceWorkerState aState);
+ 
+   // Expose the underlying IPC type so that it can be passed via IPC.
+   const IPCServiceWorkerDescriptor&
+diff --git a/dom/serviceworkers/ServiceWorkerInfo.cpp b/dom/serviceworkers/ServiceWorkerInfo.cpp
+--- a/dom/serviceworkers/ServiceWorkerInfo.cpp
++++ b/dom/serviceworkers/ServiceWorkerInfo.cpp
+@@ -216,17 +216,18 @@ ServiceWorkerInfo::UpdateState(ServiceWo
+ }
+ 
+ ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
+                                      const nsACString& aScope,
+                                      const nsACString& aScriptSpec,
+                                      const nsAString& aCacheName,
+                                      nsLoadFlags aImportsLoadFlags)
+   : mPrincipal(aPrincipal)
+-  , mDescriptor(GetNextID(), aPrincipal, aScope, ServiceWorkerState::Parsed)
++  , mDescriptor(GetNextID(), aPrincipal, aScope, aScriptSpec,
++                ServiceWorkerState::Parsed)
+   , mScriptSpec(aScriptSpec)
+   , mCacheName(aCacheName)
+   , mImportsLoadFlags(aImportsLoadFlags)
+   , mCreationTime(PR_Now())
+   , mCreationTimeStamp(TimeStamp::Now())
+   , mInstalledTime(0)
+   , mActivatedTime(0)
+   , mRedundantTime(0)
+diff --git a/dom/serviceworkers/ServiceWorkerPrivate.cpp b/dom/serviceworkers/ServiceWorkerPrivate.cpp
+--- a/dom/serviceworkers/ServiceWorkerPrivate.cpp
++++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp
+@@ -1849,20 +1849,17 @@ ServiceWorkerPrivate::SpawnWorkerIfNeede
+   info.mResolvedScriptURI = info.mBaseURI;
+   MOZ_ASSERT(!mInfo->CacheName().IsEmpty());
+   info.mServiceWorkerCacheName = mInfo->CacheName();
+ 
+   PrincipalInfo principalInfo;
+   rv = PrincipalToPrincipalInfo(mInfo->Principal(), &principalInfo);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+-  info.mServiceWorkerDescriptor.emplace(ServiceWorkerDescriptor(mInfo->ID(),
+-                                                                principalInfo,
+-                                                                mInfo->Scope(),
+-                                                                mInfo->State()));
++  info.mServiceWorkerDescriptor.emplace(mInfo->Descriptor());
+ 
+   info.mLoadGroup = aLoadGroup;
+   info.mLoadFailedAsyncRunnable = aLoadFailedRunnable;
+ 
+   // If we are loading a script for a ServiceWorker then we must not
+   // try to intercept it.  If the interception matches the current
+   // ServiceWorker's scope then we could deadlock the load.
+   info.mLoadFlags = mInfo->GetImportsLoadFlags() |

+ 139 - 0
mozilla-release/patches/1433545-2-60a1.patch

@@ -0,0 +1,139 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517416190 28800
+#      Wed Jan 31 08:29:50 2018 -0800
+# Node ID a1b1e70fd362ded0bee1ca7bc540c4459e6edcc8
+# Parent  9be09d7a6297717ff0bf6a8637bc987c73b88658
+Bug 1433545 P2 Remove mScriptSpec from ServiceWorkerInfo and use mDescriptor.ScriptURL() instead. r=asuth
+
+diff --git a/dom/serviceworkers/ServiceWorkerInfo.cpp b/dom/serviceworkers/ServiceWorkerInfo.cpp
+--- a/dom/serviceworkers/ServiceWorkerInfo.cpp
++++ b/dom/serviceworkers/ServiceWorkerInfo.cpp
+@@ -29,17 +29,17 @@ static_assert(nsIServiceWorkerInfo::STAT
+               "ServiceWorkerState enumeration value should match state values from nsIServiceWorkerInfo.");
+ 
+ NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
+ 
+ NS_IMETHODIMP
+ ServiceWorkerInfo::GetScriptSpec(nsAString& aScriptSpec)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+-  CopyUTF8toUTF16(mScriptSpec, aScriptSpec);
++  CopyUTF8toUTF16(mDescriptor.ScriptURL(), aScriptSpec);
+   return NS_OK;
+ }
+ 
+ NS_IMETHODIMP
+ ServiceWorkerInfo::GetCacheName(nsAString& aCacheName)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+   aCacheName = mCacheName;
+@@ -115,32 +115,32 @@ ServiceWorkerInfo::DetachDebugger()
+ 
+ void
+ ServiceWorkerInfo::AppendWorker(ServiceWorker* aWorker)
+ {
+   MOZ_ASSERT(aWorker);
+ #ifdef DEBUG
+   nsAutoString workerURL;
+   aWorker->GetScriptURL(workerURL);
+-  MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mScriptSpec)));
++  MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
+ #endif
+   MOZ_ASSERT(!mInstances.Contains(aWorker));
+ 
+   mInstances.AppendElement(aWorker);
+   aWorker->SetState(State());
+ }
+ 
+ void
+ ServiceWorkerInfo::RemoveWorker(ServiceWorker* aWorker)
+ {
+   MOZ_ASSERT(aWorker);
+ #ifdef DEBUG
+   nsAutoString workerURL;
+   aWorker->GetScriptURL(workerURL);
+-  MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mScriptSpec)));
++  MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
+ #endif
+   MOZ_ASSERT(mInstances.Contains(aWorker));
+ 
+   mInstances.RemoveElement(aWorker);
+ }
+ 
+ namespace {
+ 
+@@ -218,32 +218,31 @@ ServiceWorkerInfo::UpdateState(ServiceWo
+ ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
+                                      const nsACString& aScope,
+                                      const nsACString& aScriptSpec,
+                                      const nsAString& aCacheName,
+                                      nsLoadFlags aImportsLoadFlags)
+   : mPrincipal(aPrincipal)
+   , mDescriptor(GetNextID(), aPrincipal, aScope, aScriptSpec,
+                 ServiceWorkerState::Parsed)
+-  , mScriptSpec(aScriptSpec)
+   , mCacheName(aCacheName)
+   , mImportsLoadFlags(aImportsLoadFlags)
+   , mCreationTime(PR_Now())
+   , mCreationTimeStamp(TimeStamp::Now())
+   , mInstalledTime(0)
+   , mActivatedTime(0)
+   , mRedundantTime(0)
+   , mServiceWorkerPrivate(new ServiceWorkerPrivate(this))
+   , mSkipWaitingFlag(false)
+   , mHandlesFetch(Unknown)
+ {
+   MOZ_ASSERT(mPrincipal);
+   // cache origin attributes so we can use them off main thread
+   mOriginAttributes = mPrincipal->OriginAttributesRef();
+-  MOZ_ASSERT(!mScriptSpec.IsEmpty());
++  MOZ_ASSERT(!mDescriptor.ScriptURL().IsEmpty());
+   MOZ_ASSERT(!mCacheName.IsEmpty());
+ 
+   // Scripts of a service worker should always be loaded bypass service workers.
+   // Otherwise, we might not be able to update a service worker correctly, if
+   // there is a service worker generating the script.
+   MOZ_DIAGNOSTIC_ASSERT(mImportsLoadFlags & nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
+ }
+ 
+diff --git a/dom/serviceworkers/ServiceWorkerInfo.h b/dom/serviceworkers/ServiceWorkerInfo.h
+--- a/dom/serviceworkers/ServiceWorkerInfo.h
++++ b/dom/serviceworkers/ServiceWorkerInfo.h
+@@ -25,17 +25,16 @@ class ServiceWorkerPrivate;
+  * _GetNewestWorker(serviceWorkerRegistration)", we represent the description
+  * by this class and spawn a ServiceWorker in the right global when required.
+  */
+ class ServiceWorkerInfo final : public nsIServiceWorkerInfo
+ {
+ private:
+   nsCOMPtr<nsIPrincipal> mPrincipal;
+   ServiceWorkerDescriptor mDescriptor;
+-  const nsCString mScriptSpec;
+   const nsString mCacheName;
+   OriginAttributes mOriginAttributes;
+ 
+   // This LoadFlags is only applied to imported scripts, since the main script
+   // has already been downloaded when performing the bytecheck. This LoadFlag is
+   // composed of three parts:
+   //   1. nsIChannel::LOAD_BYPASS_SERVICE_WORKER
+   //   2. (Optional) nsIRequest::VALIDATE_ALWAYS
+@@ -91,17 +90,17 @@ public:
+   Principal() const
+   {
+     return mPrincipal;
+   }
+ 
+   const nsCString&
+   ScriptSpec() const
+   {
+-    return mScriptSpec;
++    return mDescriptor.ScriptURL();
+   }
+ 
+   const nsCString&
+   Scope() const
+   {
+     return mDescriptor.Scope();
+   }
+ 

+ 32 - 0
mozilla-release/patches/1433914-60a1.patch

@@ -0,0 +1,32 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1517242121 -3600
+# Node ID 9f7a52c45ad5e54c69a55b773808beb13b79e049
+# Parent  5e78fa0f7d18b0abd9f54d01b057d26c49499c9d
+Bug 1433914 - When workers hang, let's log if the shutting down has started, r=smaug
+
+diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
+--- a/dom/workers/RuntimeService.cpp
++++ b/dom/workers/RuntimeService.cpp
+@@ -2161,18 +2161,18 @@ RuntimeService::CrashIfHanging()
+   }
+ 
+   // We must have something pending...
+   MOZ_DIAGNOSTIC_ASSERT(activeWorkers + activeServiceWorkers + inactiveWorkers);
+ 
+   nsCString msg;
+ 
+   // A: active Workers | S: active ServiceWorkers | Q: queued Workers
+-  msg.AppendPrintf("Workers Hanging - A:%d|S:%d|Q:%d", activeWorkers,
+-                   activeServiceWorkers, inactiveWorkers);
++  msg.AppendPrintf("Workers Hanging - %d|A:%d|S:%d|Q:%d", mShuttingDown ? 1 : 0,
++                   activeWorkers, activeServiceWorkers, inactiveWorkers);
+ 
+   // For each thread, let's print some data to know what is going wrong.
+   for (uint32_t i = 0; i < workers.Length(); ++i) {
+     WorkerPrivate* workerPrivate = workers[i];
+ 
+     // BC: Busy Count
+     msg.AppendPrintf("-BC:%d", workerPrivate->BusyCount());
+ 
+

+ 148 - 0
mozilla-release/patches/1434342-1-60a1.patch

@@ -0,0 +1,148 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517418625 28800
+#      Wed Jan 31 09:10:25 2018 -0800
+# Node ID a246a99f932b26f44c1c691ba741025a5d38c1d3
+# Parent  21fea000a9fadc75f1170337d34065992b7a74fd
+Bug 1434342 P1 Add ServiceWorker::Create() factory method. r=asuth
+
+diff --git a/dom/serviceworkers/ServiceWorker.cpp b/dom/serviceworkers/ServiceWorker.cpp
+--- a/dom/serviceworkers/ServiceWorker.cpp
++++ b/dom/serviceworkers/ServiceWorker.cpp
+@@ -33,19 +33,46 @@ ServiceWorkerVisible(JSContext* aCx, JSO
+ {
+   if (NS_IsMainThread()) {
+     return DOMPrefs::ServiceWorkersEnabled();
+   }
+ 
+   return IS_INSTANCE_OF(ServiceWorkerGlobalScope, aObj);
+ }
+ 
+-ServiceWorker::ServiceWorker(nsPIDOMWindowInner* aWindow,
++// static
++already_AddRefed<ServiceWorker>
++ServiceWorker::Create(nsIGlobalObject* aOwner,
++                      const ServiceWorkerDescriptor& aDescriptor)
++{
++  RefPtr<ServiceWorker> ref;
++
++  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
++  if (!swm) {
++    return ref.forget();
++  }
++
++  RefPtr<ServiceWorkerRegistrationInfo> reg =
++    swm->GetRegistration(aDescriptor.PrincipalInfo(), aDescriptor.Scope());
++  if (!reg) {
++    return ref.forget();
++  }
++
++  RefPtr<ServiceWorkerInfo> info = reg->GetByID(aDescriptor.Id());
++  if (!info) {
++    return ref.forget();
++  }
++
++  ref = new ServiceWorker(aOwner, info);
++  return ref.forget();
++}
++
++ServiceWorker::ServiceWorker(nsIGlobalObject* aGlobal,
+                              ServiceWorkerInfo* aInfo)
+-  : DOMEventTargetHelper(aWindow),
++  : DOMEventTargetHelper(aGlobal),
+     mInfo(aInfo)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+   MOZ_ASSERT(aInfo);
+ 
+   // This will update our state too.
+   mInfo->AppendWorker(this);
+ }
+diff --git a/dom/serviceworkers/ServiceWorker.h b/dom/serviceworkers/ServiceWorker.h
+--- a/dom/serviceworkers/ServiceWorker.h
++++ b/dom/serviceworkers/ServiceWorker.h
+@@ -6,37 +6,39 @@
+ 
+ #ifndef mozilla_dom_serviceworker_h__
+ #define mozilla_dom_serviceworker_h__
+ 
+ #include "mozilla/DOMEventTargetHelper.h"
+ #include "mozilla/dom/BindingDeclarations.h"
+ #include "mozilla/dom/ServiceWorkerBinding.h" // For ServiceWorkerState.
+ 
+-class nsPIDOMWindowInner;
++class nsIGlobalObject;
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ class ServiceWorkerInfo;
+ class ServiceWorkerManager;
+ class SharedWorker;
+ 
+ bool
+ ServiceWorkerVisible(JSContext* aCx, JSObject* aObj);
+ 
+ class ServiceWorker final : public DOMEventTargetHelper
+ {
+-  friend class ServiceWorkerInfo;
+ public:
+   NS_DECL_ISUPPORTS_INHERITED
+ 
+   IMPL_EVENT_HANDLER(statechange)
+   IMPL_EVENT_HANDLER(error)
+ 
++  static already_AddRefed<ServiceWorker>
++  Create(nsIGlobalObject* aOwner, const ServiceWorkerDescriptor& aDescriptor);
++
+   virtual JSObject*
+   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+ 
+   ServiceWorkerState
+   State() const
+   {
+     return mState;
+   }
+@@ -60,18 +62,17 @@ public:
+ #undef PostMessage
+ #endif
+ 
+   void
+   PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+               const Sequence<JSObject*>& aTransferable, ErrorResult& aRv);
+ 
+ private:
+-  // This class can only be created from ServiceWorkerInfo::GetOrCreateInstance().
+-  ServiceWorker(nsPIDOMWindowInner* aWindow, ServiceWorkerInfo* aInfo);
++  ServiceWorker(nsIGlobalObject* aWindow, ServiceWorkerInfo* aInfo);
+ 
+   // This class is reference-counted and will be destroyed from Release().
+   ~ServiceWorker();
+ 
+   ServiceWorkerState mState;
+   const RefPtr<ServiceWorkerInfo> mInfo;
+ };
+ 
+diff --git a/dom/serviceworkers/ServiceWorkerInfo.cpp b/dom/serviceworkers/ServiceWorkerInfo.cpp
+--- a/dom/serviceworkers/ServiceWorkerInfo.cpp
++++ b/dom/serviceworkers/ServiceWorkerInfo.cpp
+@@ -272,17 +272,18 @@ ServiceWorkerInfo::GetOrCreateInstance(n
+     MOZ_ASSERT(mInstances[i]);
+     if (mInstances[i]->GetOwner() == aWindow) {
+       ref = mInstances[i];
+       break;
+     }
+   }
+ 
+   if (!ref) {
+-    ref = new ServiceWorker(aWindow, this);
++    nsCOMPtr<nsIGlobalObject> global(do_QueryInterface(aWindow));
++    ref = ServiceWorker::Create(global, mDescriptor);
+   }
+ 
+   return ref.forget();
+ }
+ 
+ void
+ ServiceWorkerInfo::UpdateInstalledTime()
+ {

+ 159 - 0
mozilla-release/patches/1434342-2-60a1.patch

@@ -0,0 +1,159 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517418626 28800
+#      Wed Jan 31 09:10:26 2018 -0800
+# Node ID bb38a0b7b6dd6a21ad52e8d2722891fcae520f21
+# Parent  a246a99f932b26f44c1c691ba741025a5d38c1d3
+Bug 1434342 P2 Make ServiceWorker store and use a ServiceWorkerDescriptor internally. r=asuth
+
+diff --git a/dom/serviceworkers/ServiceWorker.cpp b/dom/serviceworkers/ServiceWorker.cpp
+--- a/dom/serviceworkers/ServiceWorker.cpp
++++ b/dom/serviceworkers/ServiceWorker.cpp
+@@ -56,24 +56,25 @@ ServiceWorker::Create(nsIGlobalObject* a
+     return ref.forget();
+   }
+ 
+   RefPtr<ServiceWorkerInfo> info = reg->GetByID(aDescriptor.Id());
+   if (!info) {
+     return ref.forget();
+   }
+ 
+-  ref = new ServiceWorker(aOwner, info);
++  ref = new ServiceWorker(aOwner, aDescriptor, info);
+   return ref.forget();
+ }
+ 
+ ServiceWorker::ServiceWorker(nsIGlobalObject* aGlobal,
+                              ServiceWorkerInfo* aInfo)
+-  : DOMEventTargetHelper(aGlobal),
+-    mInfo(aInfo)
++  : DOMEventTargetHelper(aGlobal)
++  , mDescriptor(aDescriptor)
++  , mInfo(aInfo)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+   MOZ_ASSERT(aInfo);
+ 
+   // This will update our state too.
+   mInfo->AppendWorker(this);
+ }
+ 
+@@ -92,20 +93,38 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEvent
+ JSObject*
+ ServiceWorker::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+ 
+   return ServiceWorkerBinding::Wrap(aCx, this, aGivenProto);
+ }
+ 
++ServiceWorkerState
++ServiceWorker::State() const
++{
++  return mDescriptor.State();
++}
++
++void
++ServiceWorker::SetState(ServiceWorkerState aState)
++{
++  mDescriptor.SetState(aState);
++}
++
+ void
+ ServiceWorker::GetScriptURL(nsString& aURL) const
+ {
+-  CopyUTF8toUTF16(mInfo->ScriptSpec(), aURL);
++  CopyUTF8toUTF16(mDescriptor.ScriptURL(), aURL);
++}
++
++void
++ServiceWorker::DispatchStateChange(ServiceWorkerState aState)
++{
++  DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("statechange"));
+ }
+ 
+ void
+ ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+                            const Sequence<JSObject*>& aTransferable,
+                            ErrorResult& aRv)
+ {
+   if (State() == ServiceWorkerState::Redundant) {
+diff --git a/dom/serviceworkers/ServiceWorker.h b/dom/serviceworkers/ServiceWorker.h
+--- a/dom/serviceworkers/ServiceWorker.h
++++ b/dom/serviceworkers/ServiceWorker.h
+@@ -5,16 +5,17 @@
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ #ifndef mozilla_dom_serviceworker_h__
+ #define mozilla_dom_serviceworker_h__
+ 
+ #include "mozilla/DOMEventTargetHelper.h"
+ #include "mozilla/dom/BindingDeclarations.h"
+ #include "mozilla/dom/ServiceWorkerBinding.h" // For ServiceWorkerState.
++#include "mozilla/dom/ServiceWorkerDescriptor.h"
+ 
+ class nsIGlobalObject;
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ class ServiceWorkerInfo;
+ class ServiceWorkerManager;
+@@ -33,50 +34,43 @@ public:
+ 
+   static already_AddRefed<ServiceWorker>
+   Create(nsIGlobalObject* aOwner, const ServiceWorkerDescriptor& aDescriptor);
+ 
+   virtual JSObject*
+   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+ 
+   ServiceWorkerState
+-  State() const
+-  {
+-    return mState;
+-  }
++  State() const;
+ 
+   void
+-  SetState(ServiceWorkerState aState)
+-  {
+-    mState = aState;
+-  }
++  SetState(ServiceWorkerState aState);
+ 
+   void
+   GetScriptURL(nsString& aURL) const;
+ 
+   void
+-  DispatchStateChange(ServiceWorkerState aState)
+-  {
+-    DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("statechange"));
+-  }
++  DispatchStateChange(ServiceWorkerState aState);
+ 
+ #ifdef XP_WIN
+ #undef PostMessage
+ #endif
+ 
+   void
+   PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+               const Sequence<JSObject*>& aTransferable, ErrorResult& aRv);
+ 
+ private:
+-  ServiceWorker(nsIGlobalObject* aWindow, ServiceWorkerInfo* aInfo);
++  ServiceWorker(nsIGlobalObject* aWindow,
++                const ServiceWorkerDescriptor& aDescriptor,
++                ServiceWorkerInfo* aInfo);
+ 
+   // This class is reference-counted and will be destroyed from Release().
+   ~ServiceWorker();
+ 
+-  ServiceWorkerState mState;
++  ServiceWorkerDescriptor mDescriptor;
+   const RefPtr<ServiceWorkerInfo> mInfo;
+ };
+ 
+ } // namespace dom
+ } // namespace mozilla
+ 
+ #endif // mozilla_dom_serviceworker_h__

+ 101 - 0
mozilla-release/patches/1434342-3-60a1.patch

@@ -0,0 +1,101 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517418626 28800
+#      Wed Jan 31 09:10:26 2018 -0800
+# Node ID 6444014a8f9044938eb6a5bece8697b3b6614c40
+# Parent  bb38a0b7b6dd6a21ad52e8d2722891fcae520f21
+Bug 1434342 P3 Make each ServiceWorker DOM object automatically fire its statechange event when appropriate. r=asuth
+
+diff --git a/dom/serviceworkers/ServiceWorker.cpp b/dom/serviceworkers/ServiceWorker.cpp
+--- a/dom/serviceworkers/ServiceWorker.cpp
++++ b/dom/serviceworkers/ServiceWorker.cpp
+@@ -102,32 +102,30 @@ ServiceWorkerState
+ ServiceWorker::State() const
+ {
+   return mDescriptor.State();
+ }
+ 
+ void
+ ServiceWorker::SetState(ServiceWorkerState aState)
+ {
++  ServiceWorkerState oldState = mDescriptor.State();
+   mDescriptor.SetState(aState);
++  if (oldState != aState) {
++    DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("statechange"));
++  }
+ }
+ 
+ void
+ ServiceWorker::GetScriptURL(nsString& aURL) const
+ {
+   CopyUTF8toUTF16(mDescriptor.ScriptURL(), aURL);
+ }
+ 
+ void
+-ServiceWorker::DispatchStateChange(ServiceWorkerState aState)
+-{
+-  DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("statechange"));
+-}
+-
+-void
+ ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+                            const Sequence<JSObject*>& aTransferable,
+                            ErrorResult& aRv)
+ {
+   if (State() == ServiceWorkerState::Redundant) {
+     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+     return;
+   }
+diff --git a/dom/serviceworkers/ServiceWorker.h b/dom/serviceworkers/ServiceWorker.h
+--- a/dom/serviceworkers/ServiceWorker.h
++++ b/dom/serviceworkers/ServiceWorker.h
+@@ -42,19 +42,16 @@ public:
+   State() const;
+ 
+   void
+   SetState(ServiceWorkerState aState);
+ 
+   void
+   GetScriptURL(nsString& aURL) const;
+ 
+-  void
+-  DispatchStateChange(ServiceWorkerState aState);
+-
+ #ifdef XP_WIN
+ #undef PostMessage
+ #endif
+ 
+   void
+   PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+               const Sequence<JSObject*>& aTransferable, ErrorResult& aRv);
+ 
+diff --git a/dom/serviceworkers/ServiceWorkerInfo.cpp b/dom/serviceworkers/ServiceWorkerInfo.cpp
+--- a/dom/serviceworkers/ServiceWorkerInfo.cpp
++++ b/dom/serviceworkers/ServiceWorkerInfo.cpp
+@@ -154,26 +154,19 @@ public:
+   {
+     for (size_t i = 0; i < aInstances.Length(); ++i) {
+       mInstances.AppendElement(aInstances[i]);
+     }
+   }
+ 
+   NS_IMETHOD Run() override
+   {
+-    // We need to update the state of all instances atomically before notifying
+-    // them to make sure that the observed state for all instances inside
+-    // statechange event handlers is correct.
+     for (size_t i = 0; i < mInstances.Length(); ++i) {
+       mInstances[i]->SetState(mState);
+     }
+-    for (size_t i = 0; i < mInstances.Length(); ++i) {
+-      mInstances[i]->DispatchStateChange(mState);
+-    }
+-
+     return NS_OK;
+   }
+ 
+ private:
+   AutoTArray<RefPtr<ServiceWorker>, 1> mInstances;
+   ServiceWorkerState mState;
+ };
+ 

+ 412 - 0
mozilla-release/patches/1434342-4-60a1.patch

@@ -0,0 +1,412 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517418626 28800
+#      Wed Jan 31 09:10:26 2018 -0800
+# Node ID 1cf205e9e3b09713928d85d05c7f13c2f070bda3
+# Parent  6444014a8f9044938eb6a5bece8697b3b6614c40
+Bug 1434342 P4 Make ServiceWorker operate on an abstract Inner interface that ServiceWorkerInfo implements. r=asuth
+
+diff --git a/dom/serviceworkers/ServiceWorker.cpp b/dom/serviceworkers/ServiceWorker.cpp
+--- a/dom/serviceworkers/ServiceWorker.cpp
++++ b/dom/serviceworkers/ServiceWorker.cpp
+@@ -61,32 +61,33 @@ ServiceWorker::Create(nsIGlobalObject* a
+     return ref.forget();
+   }
+ 
+   ref = new ServiceWorker(aOwner, aDescriptor, info);
+   return ref.forget();
+ }
+ 
+ ServiceWorker::ServiceWorker(nsIGlobalObject* aGlobal,
+-                             ServiceWorkerInfo* aInfo)
++                             const ServiceWorkerDescriptor& aDescriptor,
++                             ServiceWorker::Inner* aInner)
+   : DOMEventTargetHelper(aGlobal)
+   , mDescriptor(aDescriptor)
+-  , mInfo(aInfo)
++  , mInner(aInner)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+-  MOZ_ASSERT(aInfo);
++  MOZ_DIAGNOSTIC_ASSERT(mInner);
+ 
+   // This will update our state too.
+-  mInfo->AppendWorker(this);
++  mInner->AddServiceWorker(this);
+ }
+ 
+ ServiceWorker::~ServiceWorker()
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+-  mInfo->RemoveWorker(this);
++  mInner->RemoveServiceWorker(this);
+ }
+ 
+ NS_IMPL_ADDREF_INHERITED(ServiceWorker, DOMEventTargetHelper)
+ NS_IMPL_RELEASE_INHERITED(ServiceWorker, DOMEventTargetHelper)
+ 
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorker)
+ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
+ 
+@@ -125,39 +126,13 @@ ServiceWorker::PostMessage(JSContext* aC
+                            const Sequence<JSObject*>& aTransferable,
+                            ErrorResult& aRv)
+ {
+   if (State() == ServiceWorkerState::Redundant) {
+     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+     return;
+   }
+ 
+-  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetParentObject());
+-  if (!window || !window->GetExtantDoc()) {
+-    NS_WARNING("Trying to call post message from an invalid dom object.");
+-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+-    return;
+-  }
+-
+-  auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window);
+-  if (storageAllowed != nsContentUtils::StorageAccess::eAllow) {
+-    ServiceWorkerManager::LocalizeAndReportToAllClients(
+-      mInfo->Scope(), "ServiceWorkerPostMessageStorageError",
+-      nsTArray<nsString> { NS_ConvertUTF8toUTF16(mInfo->Scope()) });
+-    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+-    return;
+-  }
+-
+-  Maybe<ClientInfo> clientInfo = window->GetClientInfo();
+-  Maybe<ClientState> clientState = window->GetClientState();
+-  if (clientInfo.isNothing() || clientState.isNothing()) {
+-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+-    return;
+-  }
+-
+-  ServiceWorkerPrivate* workerPrivate = mInfo->WorkerPrivate();
+-  aRv = workerPrivate->SendMessageEvent(aCx, aMessage, aTransferable,
+-                                        ClientInfoAndState(clientInfo.ref().ToIPC(),
+-                                                           clientState.ref().ToIPC()));
++  mInner->PostMessage(GetParentObject(), aCx, aMessage, aTransferable, aRv);
+ }
+ 
+ } // namespace dom
+ } // namespace mozilla
+diff --git a/dom/serviceworkers/ServiceWorker.h b/dom/serviceworkers/ServiceWorker.h
+--- a/dom/serviceworkers/ServiceWorker.h
++++ b/dom/serviceworkers/ServiceWorker.h
+@@ -4,34 +4,66 @@
+  * 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_dom_serviceworker_h__
+ #define mozilla_dom_serviceworker_h__
+ 
+ #include "mozilla/DOMEventTargetHelper.h"
+ #include "mozilla/dom/BindingDeclarations.h"
+-#include "mozilla/dom/ServiceWorkerBinding.h" // For ServiceWorkerState.
+ #include "mozilla/dom/ServiceWorkerDescriptor.h"
+ 
++#ifdef XP_WIN
++#undef PostMessage
++#endif
++
+ class nsIGlobalObject;
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+-class ServiceWorkerInfo;
+-class ServiceWorkerManager;
+-class SharedWorker;
+-
+ bool
+ ServiceWorkerVisible(JSContext* aCx, JSObject* aObj);
+ 
+ class ServiceWorker final : public DOMEventTargetHelper
+ {
+ public:
++  // Abstract interface for the internal representation of the
++  // ServiceWorker object.
++  class Inner
++  {
++  public:
++    // This will be called when a DOM ServiceWorker object is
++    // created and takes a strong ref to the Inner object.
++    // RemoveServiceWorker() is guaranteed to be called on the
++    // current thread before the ServiceWorker is destroyed.
++    //
++    // In addition, the Inner object should check to see if
++    // the ServiceWorker's state is correct.  If not, it should
++    // be updated automatically by calling SetState().  This is
++    // necessary to handle race conditions where the DOM
++    // ServiceWorker object is created while the state is being
++    // updated in another process.
++    virtual void
++    AddServiceWorker(ServiceWorker* aWorker) = 0;
++
++    // This is called when the DOM ServiceWorker object is
++    // destroyed and drops its ref to the Inner object.
++    virtual void
++    RemoveServiceWorker(ServiceWorker* aWorker) = 0;
++
++    virtual void
++    PostMessage(nsIGlobalObject* aGlobal,
++                JSContext* aCx, JS::Handle<JS::Value> aMessage,
++                const Sequence<JSObject*>& aTransferable,
++                ErrorResult& aRv) = 0;
++
++    NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
++  };
++
+   NS_DECL_ISUPPORTS_INHERITED
+ 
+   IMPL_EVENT_HANDLER(statechange)
+   IMPL_EVENT_HANDLER(error)
+ 
+   static already_AddRefed<ServiceWorker>
+   Create(nsIGlobalObject* aOwner, const ServiceWorkerDescriptor& aDescriptor);
+ 
+@@ -42,32 +74,28 @@ public:
+   State() const;
+ 
+   void
+   SetState(ServiceWorkerState aState);
+ 
+   void
+   GetScriptURL(nsString& aURL) const;
+ 
+-#ifdef XP_WIN
+-#undef PostMessage
+-#endif
+-
+   void
+   PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+               const Sequence<JSObject*>& aTransferable, ErrorResult& aRv);
+ 
+ private:
+   ServiceWorker(nsIGlobalObject* aWindow,
+                 const ServiceWorkerDescriptor& aDescriptor,
+-                ServiceWorkerInfo* aInfo);
++                Inner* aInner);
+ 
+   // This class is reference-counted and will be destroyed from Release().
+   ~ServiceWorker();
+ 
+   ServiceWorkerDescriptor mDescriptor;
+-  const RefPtr<ServiceWorkerInfo> mInfo;
++  const RefPtr<Inner> mInner;
+ };
+ 
+ } // namespace dom
+ } // namespace mozilla
+ 
+ #endif // mozilla_dom_serviceworker_h__
+diff --git a/dom/serviceworkers/ServiceWorkerInfo.cpp b/dom/serviceworkers/ServiceWorkerInfo.cpp
+--- a/dom/serviceworkers/ServiceWorkerInfo.cpp
++++ b/dom/serviceworkers/ServiceWorkerInfo.cpp
+@@ -108,45 +108,16 @@ ServiceWorkerInfo::AttachDebugger()
+ }
+ 
+ NS_IMETHODIMP
+ ServiceWorkerInfo::DetachDebugger()
+ {
+   return mServiceWorkerPrivate->DetachDebugger();
+ }
+ 
+-void
+-ServiceWorkerInfo::AppendWorker(ServiceWorker* aWorker)
+-{
+-  MOZ_ASSERT(aWorker);
+-#ifdef DEBUG
+-  nsAutoString workerURL;
+-  aWorker->GetScriptURL(workerURL);
+-  MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
+-#endif
+-  MOZ_ASSERT(!mInstances.Contains(aWorker));
+-
+-  mInstances.AppendElement(aWorker);
+-  aWorker->SetState(State());
+-}
+-
+-void
+-ServiceWorkerInfo::RemoveWorker(ServiceWorker* aWorker)
+-{
+-  MOZ_ASSERT(aWorker);
+-#ifdef DEBUG
+-  nsAutoString workerURL;
+-  aWorker->GetScriptURL(workerURL);
+-  MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
+-#endif
+-  MOZ_ASSERT(mInstances.Contains(aWorker));
+-
+-  mInstances.RemoveElement(aWorker);
+-}
+-
+ namespace {
+ 
+ class ChangeStateUpdater final : public Runnable
+ {
+ public:
+   ChangeStateUpdater(const nsTArray<ServiceWorker*>& aInstances,
+                      ServiceWorkerState aState)
+     : Runnable("dom::ChangeStateUpdater")
+@@ -248,16 +219,82 @@ ServiceWorkerInfo::~ServiceWorkerInfo()
+ static uint64_t gServiceWorkerInfoCurrentID = 0;
+ 
+ uint64_t
+ ServiceWorkerInfo::GetNextID() const
+ {
+   return ++gServiceWorkerInfoCurrentID;
+ }
+ 
++void
++ServiceWorkerInfo::AddServiceWorker(ServiceWorker* aWorker)
++{
++  MOZ_DIAGNOSTIC_ASSERT(aWorker);
++#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
++  nsAutoString workerURL;
++  aWorker->GetScriptURL(workerURL);
++  MOZ_DIAGNOSTIC_ASSERT(
++    workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
++#endif
++  MOZ_ASSERT(!mInstances.Contains(aWorker));
++
++  mInstances.AppendElement(aWorker);
++  aWorker->SetState(State());
++}
++
++void
++ServiceWorkerInfo::RemoveServiceWorker(ServiceWorker* aWorker)
++{
++  MOZ_DIAGNOSTIC_ASSERT(aWorker);
++#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
++  nsAutoString workerURL;
++  aWorker->GetScriptURL(workerURL);
++  MOZ_DIAGNOSTIC_ASSERT(
++    workerURL.Equals(NS_ConvertUTF8toUTF16(mDescriptor.ScriptURL())));
++#endif
++  MOZ_ASSERT(mInstances.Contains(aWorker));
++
++  mInstances.RemoveElement(aWorker);
++}
++
++void
++ServiceWorkerInfo::PostMessage(nsIGlobalObject* aGlobal,
++                               JSContext* aCx, JS::Handle<JS::Value> aMessage,
++                               const Sequence<JSObject*>& aTransferable,
++                               ErrorResult& aRv)
++{
++  MOZ_ASSERT(NS_IsMainThread());
++
++  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal);
++  if (NS_WARN_IF(!window || !window->GetExtantDoc())) {
++    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
++    return;
++  }
++
++  auto storageAllowed = nsContentUtils::StorageAllowedForWindow(window);
++  if (storageAllowed != nsContentUtils::StorageAccess::eAllow) {
++    ServiceWorkerManager::LocalizeAndReportToAllClients(
++      Scope(), "ServiceWorkerPostMessageStorageError",
++      nsTArray<nsString> { NS_ConvertUTF8toUTF16(Scope()) });
++    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
++    return;
++  }
++
++  Maybe<ClientInfo> clientInfo = window->GetClientInfo();
++  Maybe<ClientState> clientState = window->GetClientState();
++  if (NS_WARN_IF(clientInfo.isNothing() || clientState.isNothing())) {
++    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
++    return;
++  }
++
++  aRv = mServiceWorkerPrivate->SendMessageEvent(aCx, aMessage, aTransferable,
++                                                ClientInfoAndState(clientInfo.ref().ToIPC(),
++                                                                   clientState.ref().ToIPC()));
++}
++
+ already_AddRefed<ServiceWorker>
+ ServiceWorkerInfo::GetOrCreateInstance(nsPIDOMWindowInner* aWindow)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+   MOZ_ASSERT(aWindow);
+ 
+   RefPtr<ServiceWorker> ref;
+ 
+diff --git a/dom/serviceworkers/ServiceWorkerInfo.h b/dom/serviceworkers/ServiceWorkerInfo.h
+--- a/dom/serviceworkers/ServiceWorkerInfo.h
++++ b/dom/serviceworkers/ServiceWorkerInfo.h
+@@ -7,21 +7,21 @@
+ #ifndef mozilla_dom_serviceworkerinfo_h
+ #define mozilla_dom_serviceworkerinfo_h
+ 
+ #include "MainThreadUtils.h"
+ #include "mozilla/dom/ServiceWorkerBinding.h" // For ServiceWorkerState
+ #include "mozilla/dom/WorkerCommon.h"
+ #include "mozilla/OriginAttributes.h"
+ #include "nsIServiceWorkerManager.h"
++#include "ServiceWorker.h"
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+-class ServiceWorker;
+ class ServiceWorkerPrivate;
+ 
+ /*
+  * Wherever the spec treats a worker instance and a description of said worker
+  * as the same thing; i.e. "Resolve foo with
+  * _GetNewestWorker(serviceWorkerRegistration)", we represent the description
+  * by this class and spawn a ServiceWorker in the right global when required.
+  */
+@@ -70,16 +70,29 @@ private:
+ 
+   ~ServiceWorkerInfo();
+ 
+   // Generates a unique id for the service worker, with zero being treated as
+   // invalid.
+   uint64_t
+   GetNextID() const;
+ 
++  // ServiceWorker::Inner implementation
++  virtual void
++  AddServiceWorker(ServiceWorker* aWorker) override;
++
++  virtual void
++  RemoveServiceWorker(ServiceWorker* aWorker) override;
++
++  virtual void
++  PostMessage(nsIGlobalObject* aGlobal,
++              JSContext* aCx, JS::Handle<JS::Value> aMessage,
++              const Sequence<JSObject*>& aTransferable,
++              ErrorResult& aRv) override;
++
+ public:
+   NS_DECL_ISUPPORTS
+   NS_DECL_NSISERVICEWORKERINFO
+ 
+   class ServiceWorkerPrivate*
+   WorkerPrivate() const
+   {
+     MOZ_ASSERT(mServiceWorkerPrivate);
+@@ -180,22 +193,16 @@ public:
+   bool
+   HandlesFetch() const
+   {
+     MOZ_ASSERT(NS_IsMainThread());
+     MOZ_DIAGNOSTIC_ASSERT(mHandlesFetch != Unknown);
+     return mHandlesFetch != Disabled;
+   }
+ 
+-  void
+-  AppendWorker(ServiceWorker* aWorker);
+-
+-  void
+-  RemoveWorker(ServiceWorker* aWorker);
+-
+   already_AddRefed<ServiceWorker>
+   GetOrCreateInstance(nsPIDOMWindowInner* aWindow);
+ 
+   void
+   UpdateInstalledTime();
+ 
+   void
+   UpdateActivatedTime();

+ 355 - 0
mozilla-release/patches/1434342-5-60a1.patch

@@ -0,0 +1,355 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517418626 28800
+#      Wed Jan 31 09:10:26 2018 -0800
+# Node ID edfc00999a3afac47595e1389f35d8b7903739b6
+# Parent  af4ebf511432483fad19cbfcad601e49454666d8
+Bug 1434342 P5 Support caching the ServiceWorker DOM instance on the global. r=asuth
+
+diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
+--- a/dom/base/nsGlobalWindow.cpp
++++ b/dom/base/nsGlobalWindow.cpp
+@@ -244,16 +244,17 @@
+ #include "mozilla/dom/PrimitiveConversions.h"
+ #include "mozilla/dom/WindowBinding.h"
+ #include "nsITabChild.h"
+ #include "mozilla/dom/MediaQueryList.h"
+ #include "mozilla/dom/ScriptSettings.h"
+ #include "mozilla/dom/NavigatorBinding.h"
+ #include "mozilla/dom/ImageBitmap.h"
+ #include "mozilla/dom/ImageBitmapBinding.h"
++#include "mozilla/dom/ServiceWorker.h"
+ #include "mozilla/dom/ServiceWorkerRegistration.h"
+ #include "mozilla/dom/U2F.h"
+ #include "mozilla/dom/WebIDLGlobalNameHash.h"
+ #include "mozilla/dom/Worklet.h"
+ #include "AccessCheck.h"
+ 
+ #ifdef HAVE_SIDEBAR
+ #include "mozilla/dom/ExternalBinding.h"
+@@ -4503,16 +4504,22 @@ nsPIDOMWindowInner::GetClientState() con
+ }
+ 
+ Maybe<ServiceWorkerDescriptor>
+ nsPIDOMWindowInner::GetController() const
+ {
+   return Move(nsGlobalWindow::Cast(this)->GetController());
+ }
+ 
++RefPtr<mozilla::dom::ServiceWorker>
++nsPIDOMWindowInner::GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor)
++{
++  return Move(nsGlobalWindow::Cast(this)->GetOrCreateServiceWorker(aDescriptor));
++}
++
+ void
+ nsPIDOMWindowInner::NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope)
+ {
+   nsGlobalWindow::Cast(this)->NoteCalledRegisterForServiceWorkerScope(aScope);
+ }
+ 
+ bool
+ nsGlobalWindow::ShouldReportForServiceWorkerScope(const nsAString& aScope)
+@@ -12840,16 +12847,49 @@ nsGlobalWindow::GetController() const
+   MOZ_ASSERT(NS_IsMainThread());
+   Maybe<ServiceWorkerDescriptor> controller;
+   if (mClientSource) {
+     controller = mClientSource->GetController();
+   }
+   return Move(controller);
+ }
+ 
++RefPtr<ServiceWorker>
++nsGlobalWindow::GetOrCreateServiceWorker(const ServiceWorkerDescriptor& aDescriptor)
++{
++  MOZ_ASSERT(NS_IsMainThread());
++  RefPtr<ServiceWorker> ref;
++  for (auto sw : mServiceWorkerList) {
++    if (sw->MatchesDescriptor(aDescriptor)) {
++      ref = sw;
++      return ref.forget();
++    }
++  }
++  ref = ServiceWorker::Create(this, aDescriptor);
++  return ref.forget();
++}
++
++void
++nsGlobalWindow::AddServiceWorker(ServiceWorker* aServiceWorker)
++{
++  MOZ_ASSERT(NS_IsMainThread());
++  MOZ_DIAGNOSTIC_ASSERT(aServiceWorker);
++  MOZ_ASSERT(!mServiceWorkerList.Contains(aServiceWorker));
++  mServiceWorkerList.AppendElement(aServiceWorker);
++}
++
++void
++nsGlobalWindow::RemoveServiceWorker(ServiceWorker* aServiceWorker)
++{
++  MOZ_ASSERT(NS_IsMainThread());
++  MOZ_DIAGNOSTIC_ASSERT(aServiceWorker);
++  MOZ_ASSERT(mServiceWorkerList.Contains(aServiceWorker));
++  mServiceWorkerList.RemoveElement(aServiceWorker);
++}
++
+ nsresult
+ nsGlobalWindow::FireDelayedDOMEvents()
+ {
+   FORWARD_TO_INNER(FireDelayedDOMEvents, (), NS_ERROR_UNEXPECTED);
+ 
+   if (mApplicationCache) {
+     static_cast<nsDOMOfflineResourceList*>(mApplicationCache.get())->FirePendingEvents();
+   }
+diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h
+--- a/dom/base/nsGlobalWindow.h
++++ b/dom/base/nsGlobalWindow.h
+@@ -403,16 +403,25 @@ public:
+   void Thaw();
+   virtual bool IsFrozen() const override;
+   void SyncStateFromParentWindow();
+ 
+   mozilla::Maybe<mozilla::dom::ClientInfo> GetClientInfo() const override;
+   mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
+   mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const override;
+ 
++  virtual RefPtr<mozilla::dom::ServiceWorker>
++  GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor) override;
++
++  virtual void
++  AddServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker) override;
++
++  virtual void
++  RemoveServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker) override;
++
+   void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
+ 
+   virtual nsresult FireDelayedDOMEvents() override;
+ 
+   // Outer windows only.
+   virtual bool WouldReuseInnerWindow(nsIDocument* aNewDocument) override;
+ 
+   virtual void SetDocShell(nsIDocShell* aDocShell) override;
+@@ -2085,16 +2094,20 @@ protected:
+   // begin presentation on.
+   uint32_t mAutoActivateVRDisplayID; // Outer windows only
+   int64_t mBeforeUnloadListenerCount; // Inner windows only
+ 
+   RefPtr<mozilla::dom::IntlUtils> mIntlUtils;
+ 
+   mozilla::UniquePtr<mozilla::dom::ClientSource> mClientSource;
+ 
++  // Weak references added by AddServiceWorker() and cleared by
++  // RemoveServiceWorker() when the ServiceWorker is destroyed.
++  nsTArray<mozilla::dom::ServiceWorker*> mServiceWorkerList;
++
+   nsTArray<RefPtr<mozilla::dom::Promise>> mPendingPromises; // Inner windows only
+ 
+   friend class nsDOMScriptableHelper;
+   friend class nsDOMWindowUtils;
+   friend class mozilla::dom::PostMessageEvent;
+   friend class DesktopNotification;
+   friend class mozilla::dom::TimeoutManager;
+   friend class IdleRequestExecutor;
+diff --git a/dom/base/nsIGlobalObject.cpp b/dom/base/nsIGlobalObject.cpp
+--- a/dom/base/nsIGlobalObject.cpp
++++ b/dom/base/nsIGlobalObject.cpp
+@@ -1,21 +1,24 @@
+ /* -*- 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 "nsIGlobalObject.h"
++
++#include "mozilla/dom/ServiceWorker.h"
+ #include "nsContentUtils.h"
+ #include "nsThreadUtils.h"
+ #include "nsHostObjectProtocolHandler.h"
+ 
+ using mozilla::Maybe;
+ using mozilla::dom::ClientInfo;
++using mozilla::dom::ServiceWorker;
+ using mozilla::dom::ServiceWorkerDescriptor;
+ 
+ nsIGlobalObject::~nsIGlobalObject()
+ {
+   UnlinkHostObjectURIs();
+ }
+ 
+ nsIPrincipal*
+@@ -127,8 +130,27 @@ nsIGlobalObject::GetClientInfo() const
+ 
+ Maybe<ServiceWorkerDescriptor>
+ nsIGlobalObject::GetController() const
+ {
+   // By default globals do not have a service worker controller.  Only real
+   // window and worker globals can currently be controlled as a client.
+   return Maybe<ServiceWorkerDescriptor>();
+ }
++
++RefPtr<ServiceWorker>
++nsIGlobalObject::GetOrCreateServiceWorker(const ServiceWorkerDescriptor& aDescriptor)
++{
++  MOZ_DIAGNOSTIC_ASSERT(false, "this global should not have any service workers");
++  return nullptr;
++}
++
++void
++nsIGlobalObject::AddServiceWorker(ServiceWorker* aServiceWorker)
++{
++  MOZ_DIAGNOSTIC_ASSERT(false, "this global should not have any service workers");
++}
++
++void
++nsIGlobalObject::RemoveServiceWorker(ServiceWorker* aServiceWorker)
++{
++  MOZ_DIAGNOSTIC_ASSERT(false, "this global should not have any service workers");
++}
+diff --git a/dom/base/nsIGlobalObject.h b/dom/base/nsIGlobalObject.h
+--- a/dom/base/nsIGlobalObject.h
++++ b/dom/base/nsIGlobalObject.h
+@@ -18,16 +18,22 @@
+ 
+ #define NS_IGLOBALOBJECT_IID \
+ { 0x11afa8be, 0xd997, 0x4e07, \
+ { 0xa6, 0xa3, 0x6f, 0x87, 0x2e, 0xc3, 0xee, 0x7f } }
+ 
+ class nsCycleCollectionTraversalCallback;
+ class nsIPrincipal;
+ 
++namespace mozilla {
++namespace dom {
++class ServiceWorker;
++} // namespace dom
++} // namespace mozilla
++
+ class nsIGlobalObject : public nsISupports,
+                         public mozilla::dom::DispatcherTrait
+ {
+   nsTArray<nsCString> mHostObjectURIs;
+   bool mIsDying;
+ 
+ protected:
+   nsIGlobalObject()
+@@ -80,16 +86,31 @@ public:
+   virtual bool IsInSyncOperation() { return false; }
+ 
+   virtual mozilla::Maybe<mozilla::dom::ClientInfo>
+   GetClientInfo() const;
+ 
+   virtual mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>
+   GetController() const;
+ 
++  // Get the DOM object for the given descriptor or attempt to create one.
++  // Creation can still fail and return nullptr during shutdown, etc.
++  virtual RefPtr<mozilla::dom::ServiceWorker>
++  GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor);
++
++  // These methods allow the ServiceWorker instances to note their existence
++  // so that the global can use weak references to them.  The global should
++  // not hold a strong reference to the ServiceWorker.
++  virtual void
++  AddServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker);
++
++  // This method must be called by the ServiceWorker before it is destroyed.
++  virtual void
++  RemoveServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker);
++
+ protected:
+   virtual ~nsIGlobalObject();
+ 
+   void
+   StartDying()
+   {
+     mIsDying = true;
+   }
+diff --git a/dom/base/nsPIDOMWindow.h b/dom/base/nsPIDOMWindow.h
+--- a/dom/base/nsPIDOMWindow.h
++++ b/dom/base/nsPIDOMWindow.h
+@@ -46,16 +46,17 @@ class ThrottledEventQueue;
+ namespace dom {
+ class AudioContext;
+ class ClientInfo;
+ class ClientState;
+ class DocGroup;
+ class TabGroup;
+ class Element;
+ class Performance;
++class ServiceWorker;
+ class ServiceWorkerDescriptor;
+ class ServiceWorkerRegistration;
+ class Timeout;
+ class TimeoutManager;
+ class CustomElementRegistry;
+ enum class CallerType : uint32_t;
+ } // namespace dom
+ } // namespace mozilla
+@@ -937,16 +938,19 @@ public:
+   // Return true if there are any open WebSockets that could block
+   // timeout-throttling.
+   bool HasOpenWebSockets() const;
+ 
+   mozilla::Maybe<mozilla::dom::ClientInfo> GetClientInfo() const;
+   mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
+   mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const;
+ 
++  RefPtr<mozilla::dom::ServiceWorker>
++  GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor);
++
+   void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
+ 
+ protected:
+   void CreatePerformanceObjectIfNeeded();
+ };
+ 
+ NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowInner, NS_PIDOMWINDOWINNER_IID)
+ 
+diff --git a/dom/serviceworkers/ServiceWorker.cpp b/dom/serviceworkers/ServiceWorker.cpp
+--- a/dom/serviceworkers/ServiceWorker.cpp
++++ b/dom/serviceworkers/ServiceWorker.cpp
+@@ -129,10 +129,21 @@ ServiceWorker::PostMessage(JSContext* aC
+   if (State() == ServiceWorkerState::Redundant) {
+     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+     return;
+   }
+ 
+   mInner->PostMessage(GetParentObject(), aCx, aMessage, aTransferable, aRv);
+ }
+ 
++bool
++ServiceWorker::MatchesDescriptor(const ServiceWorkerDescriptor& aDescriptor) const
++{
++  // Compare everything in the descriptor except the state.  That is mutable
++  // and may not exactly match.
++  return mDescriptor.PrincipalInfo() == aDescriptor.PrincipalInfo() &&
++         mDescriptor.Scope() == aDescriptor.Scope() &&
++         mDescriptor.ScriptURL() == aDescriptor.ScriptURL() &&
++         mDescriptor.Id() == aDescriptor.Id();
++}
++
+ } // namespace dom
+ } // namespace mozilla
+diff --git a/dom/serviceworkers/ServiceWorker.h b/dom/serviceworkers/ServiceWorker.h
+--- a/dom/serviceworkers/ServiceWorker.h
++++ b/dom/serviceworkers/ServiceWorker.h
+@@ -78,16 +78,19 @@ public:
+ 
+   void
+   GetScriptURL(nsString& aURL) const;
+ 
+   void
+   PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+               const Sequence<JSObject*>& aTransferable, ErrorResult& aRv);
+ 
++  bool
++  MatchesDescriptor(const ServiceWorkerDescriptor& aDescriptor) const;
++
+ private:
+   ServiceWorker(nsIGlobalObject* aWindow,
+                 const ServiceWorkerDescriptor& aDescriptor,
+                 Inner* aInner);
+ 
+   // This class is reference-counted and will be destroyed from Release().
+   ~ServiceWorker();
+ 

+ 89 - 0
mozilla-release/patches/1434342-6-60a1.patch

@@ -0,0 +1,89 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517418626 28800
+#      Wed Jan 31 09:10:26 2018 -0800
+# Node ID 6b5ed759f753d1f204be3826ab56bb33bb2d2611
+# Parent  edfc00999a3afac47595e1389f35d8b7903739b6
+Bug 1434342 P6 Make ServiceWorker call nsIGlobalObject::AddServiceWorker and RemoveServiceWorker. r=asuth
+
+diff --git a/dom/serviceworkers/ServiceWorker.cpp b/dom/serviceworkers/ServiceWorker.cpp
+--- a/dom/serviceworkers/ServiceWorker.cpp
++++ b/dom/serviceworkers/ServiceWorker.cpp
+@@ -68,26 +68,33 @@ ServiceWorker::Create(nsIGlobalObject* a
+ ServiceWorker::ServiceWorker(nsIGlobalObject* aGlobal,
+                              const ServiceWorkerDescriptor& aDescriptor,
+                              ServiceWorker::Inner* aInner)
+   : DOMEventTargetHelper(aGlobal)
+   , mDescriptor(aDescriptor)
+   , mInner(aInner)
+ {
+   MOZ_ASSERT(NS_IsMainThread());
++  MOZ_DIAGNOSTIC_ASSERT(aGlobal);
+   MOZ_DIAGNOSTIC_ASSERT(mInner);
+ 
++  aGlobal->AddServiceWorker(this);
++
+   // This will update our state too.
+   mInner->AddServiceWorker(this);
+ }
+ 
+ ServiceWorker::~ServiceWorker()
+ {
+   MOZ_ASSERT(NS_IsMainThread());
+   mInner->RemoveServiceWorker(this);
++  nsIGlobalObject* global = GetParentObject();
++  if (global) {
++    global->RemoveServiceWorker(this);
++  }
+ }
+ 
+ NS_IMPL_ADDREF_INHERITED(ServiceWorker, DOMEventTargetHelper)
+ NS_IMPL_RELEASE_INHERITED(ServiceWorker, DOMEventTargetHelper)
+ 
+ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorker)
+ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
+ 
+@@ -140,10 +147,20 @@ ServiceWorker::MatchesDescriptor(const S
+   // Compare everything in the descriptor except the state.  That is mutable
+   // and may not exactly match.
+   return mDescriptor.PrincipalInfo() == aDescriptor.PrincipalInfo() &&
+          mDescriptor.Scope() == aDescriptor.Scope() &&
+          mDescriptor.ScriptURL() == aDescriptor.ScriptURL() &&
+          mDescriptor.Id() == aDescriptor.Id();
+ }
+ 
++void
++ServiceWorker::DisconnectFromOwner()
++{
++  nsIGlobalObject* global = GetParentObject();
++  if (global) {
++    global->RemoveServiceWorker(this);
++  }
++  DOMEventTargetHelper::DisconnectFromOwner();
++}
++
+ } // namespace dom
+ } // namespace mozilla
+diff --git a/dom/serviceworkers/ServiceWorker.h b/dom/serviceworkers/ServiceWorker.h
+--- a/dom/serviceworkers/ServiceWorker.h
++++ b/dom/serviceworkers/ServiceWorker.h
+@@ -81,16 +81,19 @@ public:
+ 
+   void
+   PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+               const Sequence<JSObject*>& aTransferable, ErrorResult& aRv);
+ 
+   bool
+   MatchesDescriptor(const ServiceWorkerDescriptor& aDescriptor) const;
+ 
++  void
++  DisconnectFromOwner() override;
++
+ private:
+   ServiceWorker(nsIGlobalObject* aWindow,
+                 const ServiceWorkerDescriptor& aDescriptor,
+                 Inner* aInner);
+ 
+   // This class is reference-counted and will be destroyed from Release().
+   ~ServiceWorker();
+ 

+ 145 - 0
mozilla-release/patches/1434342-7-60a1.patch

@@ -0,0 +1,145 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517418627 28800
+#      Wed Jan 31 09:10:27 2018 -0800
+# Node ID cd5241785aca69261dc6a1693fe57a1fba8f8bcd
+# Parent  6b5ed759f753d1f204be3826ab56bb33bb2d2611
+Bug 1434342 P7 Use the global to GetOrCreate the ServiceWorker DOM instance. r=asuth
+
+diff --git a/dom/clients/manager/ClientSource.cpp b/dom/clients/manager/ClientSource.cpp
+--- a/dom/clients/manager/ClientSource.cpp
++++ b/dom/clients/manager/ClientSource.cpp
+@@ -567,18 +567,19 @@ ClientSource::PostMessage(const ClientPo
+     return ref.forget();
+   }
+ 
+   RefPtr<ServiceWorkerRegistrationInfo> reg =
+     swm->GetRegistration(principal, source.Scope());
+   if (reg) {
+     RefPtr<ServiceWorkerInfo> serviceWorker = reg->GetByID(source.Id());
+     if (serviceWorker) {
+-      init.mSource.SetValue().SetAsServiceWorker() =
+-        serviceWorker->GetOrCreateInstance(GetInnerWindow());
++      RefPtr<ServiceWorker> instance =
++        globalObject->GetOrCreateServiceWorker(source);
++      init.mSource.SetValue().SetAsServiceWorker() = instance;
+     }
+   }
+ 
+   RefPtr<MessageEvent> event =
+     MessageEvent::Constructor(target, NS_LITERAL_STRING("message"), init);
+   event->SetTrusted(true);
+ 
+   bool preventDefaultCalled = false;
+diff --git a/dom/serviceworkers/ServiceWorkerContainer.cpp b/dom/serviceworkers/ServiceWorkerContainer.cpp
+--- a/dom/serviceworkers/ServiceWorkerContainer.cpp
++++ b/dom/serviceworkers/ServiceWorkerContainer.cpp
+@@ -246,17 +246,17 @@ ServiceWorkerContainer::GetController()
+     NS_ENSURE_TRUE(info, nullptr);
+ 
+     nsCOMPtr<nsPIDOMWindowInner> inner = do_QueryInterface(owner);
+     NS_ENSURE_TRUE(inner, nullptr);
+ 
+     // Right now we only know how to create ServiceWorker DOM objects on
+     // the main thread with a window.  In the future this should operate
+     // on only nsIGlobalObject somehow.
+-    mControllerWorker = info->GetOrCreateInstance(inner);
++    mControllerWorker = inner->GetOrCreateServiceWorker(info->Descriptor());
+   }
+ 
+   RefPtr<ServiceWorker> ref = mControllerWorker;
+   return ref.forget();
+ }
+ 
+ already_AddRefed<Promise>
+ ServiceWorkerContainer::GetRegistrations(ErrorResult& aRv)
+diff --git a/dom/serviceworkers/ServiceWorkerInfo.cpp b/dom/serviceworkers/ServiceWorkerInfo.cpp
+--- a/dom/serviceworkers/ServiceWorkerInfo.cpp
++++ b/dom/serviceworkers/ServiceWorkerInfo.cpp
+@@ -285,40 +285,16 @@ ServiceWorkerInfo::PostMessage(nsIGlobal
+     return;
+   }
+ 
+   aRv = mServiceWorkerPrivate->SendMessageEvent(aCx, aMessage, aTransferable,
+                                                 ClientInfoAndState(clientInfo.ref().ToIPC(),
+                                                                    clientState.ref().ToIPC()));
+ }
+ 
+-already_AddRefed<ServiceWorker>
+-ServiceWorkerInfo::GetOrCreateInstance(nsPIDOMWindowInner* aWindow)
+-{
+-  MOZ_ASSERT(NS_IsMainThread());
+-  MOZ_ASSERT(aWindow);
+-
+-  RefPtr<ServiceWorker> ref;
+-
+-  for (uint32_t i = 0; i < mInstances.Length(); ++i) {
+-    MOZ_ASSERT(mInstances[i]);
+-    if (mInstances[i]->GetOwner() == aWindow) {
+-      ref = mInstances[i];
+-      break;
+-    }
+-  }
+-
+-  if (!ref) {
+-    nsCOMPtr<nsIGlobalObject> global(do_QueryInterface(aWindow));
+-    ref = ServiceWorker::Create(global, mDescriptor);
+-  }
+-
+-  return ref.forget();
+-}
+-
+ void
+ ServiceWorkerInfo::UpdateInstalledTime()
+ {
+   MOZ_ASSERT(State() == ServiceWorkerState::Installed);
+   MOZ_ASSERT(mInstalledTime == 0);
+ 
+   mInstalledTime =
+     mCreationTime + static_cast<PRTime>((TimeStamp::Now() -
+diff --git a/dom/serviceworkers/ServiceWorkerInfo.h b/dom/serviceworkers/ServiceWorkerInfo.h
+--- a/dom/serviceworkers/ServiceWorkerInfo.h
++++ b/dom/serviceworkers/ServiceWorkerInfo.h
+@@ -193,19 +193,16 @@ public:
+   bool
+   HandlesFetch() const
+   {
+     MOZ_ASSERT(NS_IsMainThread());
+     MOZ_DIAGNOSTIC_ASSERT(mHandlesFetch != Unknown);
+     return mHandlesFetch != Disabled;
+   }
+ 
+-  already_AddRefed<ServiceWorker>
+-  GetOrCreateInstance(nsPIDOMWindowInner* aWindow);
+-
+   void
+   UpdateInstalledTime();
+ 
+   void
+   UpdateActivatedTime();
+ 
+   void
+   UpdateRedundantTime();
+diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/ServiceWorkerManager.cpp
+--- a/dom/serviceworkers/ServiceWorkerManager.cpp
++++ b/dom/serviceworkers/ServiceWorkerManager.cpp
+@@ -2361,17 +2361,18 @@ ServiceWorkerManager::GetServiceWorkerFo
+   } else {
+     MOZ_CRASH("Invalid worker type");
+   }
+ 
+   if (NS_WARN_IF(!info)) {
+     return NS_ERROR_DOM_NOT_FOUND_ERR;
+   }
+ 
+-  RefPtr<ServiceWorker> serviceWorker = info->GetOrCreateInstance(aWindow);
++  RefPtr<ServiceWorker> serviceWorker =
++    aWindow->GetOrCreateServiceWorker(info->Descriptor());
+ 
+   serviceWorker->SetState(info->State());
+   serviceWorker.forget(aServiceWorker);
+   return NS_OK;
+ }
+ 
+ namespace {
+ 

+ 29 - 0
mozilla-release/patches/1434342-8-60a1.patch

@@ -0,0 +1,29 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1517419641 28800
+#      Wed Jan 31 09:27:21 2018 -0800
+# Node ID 6776907cc2aac11365065221eca463320729752c
+# Parent  8cba4fe278078537b6922e62250344d0030177d5
+Bug 1434342 Follow-up to fix bustage on a CLOSED TREE. r=me
+
+diff --git a/dom/serviceworkers/ServiceWorkerInfo.h b/dom/serviceworkers/ServiceWorkerInfo.h
+--- a/dom/serviceworkers/ServiceWorkerInfo.h
++++ b/dom/serviceworkers/ServiceWorkerInfo.h
+@@ -21,16 +21,17 @@ class ServiceWorkerPrivate;
+ 
+ /*
+  * Wherever the spec treats a worker instance and a description of said worker
+  * as the same thing; i.e. "Resolve foo with
+  * _GetNewestWorker(serviceWorkerRegistration)", we represent the description
+  * by this class and spawn a ServiceWorker in the right global when required.
+  */
+ class ServiceWorkerInfo final : public nsIServiceWorkerInfo
++                              , public ServiceWorker::Inner
+ {
+ private:
+   nsCOMPtr<nsIPrincipal> mPrincipal;
+   ServiceWorkerDescriptor mDescriptor;
+   const nsString mCacheName;
+   OriginAttributes mOriginAttributes;
+ 
+   // This LoadFlags is only applied to imported scripts, since the main script

+ 104 - 0
mozilla-release/patches/1434599-60a1.patch

@@ -0,0 +1,104 @@
+# HG changeset patch
+# User Catalin Badea <catalin.badea392@gmail.com>
+# Date 1517544720 -7200
+# Node ID 66a85897ecb2d7b1a8b533a657b6767b117a262e
+# Parent  a7f88998e959dd94f9050371824b1e9a379cc705
+Bug 1434599 - Enable test_workerupdatefoundevent.html. r=bkelly
+
+diff --git a/dom/serviceworkers/test/mochitest.ini b/dom/serviceworkers/test/mochitest.ini
+--- a/dom/serviceworkers/test/mochitest.ini
++++ b/dom/serviceworkers/test/mochitest.ini
+@@ -336,16 +336,15 @@ tags = openwindow
+ [test_strict_mode_warning.html]
+ [test_third_party_iframes.html]
+ [test_unregister.html]
+ [test_unresolved_fetch_interception.html]
+ [test_update_missing_imported_script.html]
+ [test_workerUnregister.html]
+ [test_workerUpdate.html]
+ [test_workerupdatefoundevent.html]
+-skip-if = !e10s # Bug 1433276
+ [test_xslt.html]
+ [test_async_waituntil.html]
+ [test_worker_reference_gc_timeout.html]
+ [test_nofetch_handler.html]
+ [test_bad_script_cache.html]
+ [test_file_upload.html]
+ support-files = script_file_upload.js sw_file_upload.js server_file_upload.sjs
+diff --git a/dom/serviceworkers/test/test_workerupdatefoundevent.html b/dom/serviceworkers/test/test_workerupdatefoundevent.html
+--- a/dom/serviceworkers/test/test_workerupdatefoundevent.html
++++ b/dom/serviceworkers/test/test_workerupdatefoundevent.html
+@@ -17,37 +17,43 @@
+ <script class="testbody" type="text/javascript">
+   var registration;
+   var promise;
+ 
+   async function start() {
+     registration = await navigator.serviceWorker.register("worker_updatefoundevent.js",
+                                                           { scope: "./updatefoundevent.html" })
+     await waitForState(registration.installing, 'activated');
++
++    content = document.getElementById("content");
++    iframe = document.createElement("iframe");
++    content.appendChild(iframe);
++    iframe.setAttribute("src", "./updatefoundevent.html");
++
++    await new Promise(function(resolve) { iframe.onload = resolve; });
++    ok(iframe.contentWindow.navigator.serviceWorker.controller, "Controlled client.");
++
++    return Promise.resolve();
++
+   }
+ 
+   function startWaitForUpdateFound() {
+     registration.onupdatefound = function(e) {
+     }
+ 
+     promise = new Promise(function(resolve, reject) {
+       window.onmessage = function(e) {
+ 
+         if (e.data == "finish") {
+           ok(true, "Received updatefound");
+           resolve();
+         }
+       }
+     });
+ 
+-    content = document.getElementById("content");
+-    iframe = document.createElement("iframe");
+-    content.appendChild(iframe);
+-    iframe.setAttribute("src", "./updatefoundevent.html");
+-
+     return Promise.resolve();
+   }
+ 
+   function registerNext() {
+     return navigator.serviceWorker.register("worker_updatefoundevent2.js",
+                                             { scope: "./updatefoundevent.html" });
+   }
+ 
+diff --git a/dom/serviceworkers/test/worker_updatefoundevent.js b/dom/serviceworkers/test/worker_updatefoundevent.js
+--- a/dom/serviceworkers/test/worker_updatefoundevent.js
++++ b/dom/serviceworkers/test/worker_updatefoundevent.js
+@@ -1,17 +1,19 @@
+ /**
+  * Any copyright is dedicated to the Public Domain.
+  * http://creativecommons.org/publicdomain/zero/1.0/
+  */
+ 
+ registration.onupdatefound = function(e) {
+   clients.matchAll().then(function(clients) {
+     if (!clients.length) {
+-      reject("No clients found");
++      // We don't control any clients when the first update event is fired
++      // because we haven't reached the 'activated' state.
++      return;
+     }
+ 
+     if (registration.scope.match(/updatefoundevent\.html$/)) {
+       clients[0].postMessage("finish");
+     } else {
+       dump("Scope did not match");
+     }
+   });
+

+ 328 - 0
mozilla-release/patches/1434934-60a1.patch

@@ -0,0 +1,328 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1517506448 -3600
+# Node ID 4191749c26091da969f8d5772fc46aa7fc83ad97
+# Parent  9acde3d589c48999d6dd7b18a2e1caf89f4a8b6e
+Bug 1434934 - Remove dom.workers.enabled pref, r=bkelly
+
+diff --git a/dom/webidl/Worker.webidl b/dom/webidl/Worker.webidl
+--- a/dom/webidl/Worker.webidl
++++ b/dom/webidl/Worker.webidl
+@@ -8,17 +8,16 @@
+  *
+  * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera
+  * Software ASA.
+  * You are granted a license to use, reproduce and create derivative works of
+  * this document.
+  */
+ 
+ [Constructor(USVString scriptURL, optional WorkerOptions options),
+- Func="mozilla::dom::WorkerPrivate::WorkerAvailable",
+  Exposed=(Window,DedicatedWorker,SharedWorker,System)]
+ interface Worker : EventTarget {
+   void terminate();
+ 
+   [Throws]
+   void postMessage(any message, optional sequence<object> transfer = []);
+ 
+   attribute EventHandler onmessage;
+diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
+--- a/dom/workers/WorkerPrivate.cpp
++++ b/dom/workers/WorkerPrivate.cpp
+@@ -68,18 +68,16 @@
+ #endif
+ 
+ // JS_MaybeGC will run once every second during normal execution.
+ #define PERIODIC_GC_TIMER_DELAY_SEC 1
+ 
+ // A shrinking GC will run five seconds after the last event is processed.
+ #define IDLE_GC_TIMER_DELAY_SEC 5
+ 
+-#define PREF_WORKERS_ENABLED "dom.workers.enabled"
+-
+ static mozilla::LazyLogModule sWorkerPrivateLog("WorkerPrivate");
+ static mozilla::LazyLogModule sWorkerTimeoutsLog("WorkerTimeouts");
+ 
+ mozilla::LogModule*
+ WorkerLog()
+ {
+   return sWorkerPrivateLog;
+ }
+@@ -2967,34 +2965,16 @@ WorkerPrivate::Constructor(const GlobalO
+                            ErrorResult& aRv)
+ {
+   return WorkerPrivate::Constructor(aGlobal, aScriptURL, false,
+                                     WorkerTypeDedicated,
+                                     aOptions.mName, nullptr, aRv);
+ }
+ 
+ // static
+-bool
+-WorkerPrivate::WorkerAvailable(JSContext* aCx, JSObject* /* unused */)
+-{
+-  // If we're already on a worker workers are clearly enabled.
+-  if (!NS_IsMainThread()) {
+-    return true;
+-  }
+-
+-  // If our caller is chrome, workers are always available.
+-  if (nsContentUtils::IsSystemCaller(aCx)) {
+-    return true;
+-  }
+-
+-  // Else check the pref.
+-  return Preferences::GetBool(PREF_WORKERS_ENABLED);
+-}
+-
+-// static
+ already_AddRefed<ChromeWorkerPrivate>
+ ChromeWorkerPrivate::Constructor(const GlobalObject& aGlobal,
+                                  const nsAString& aScriptURL,
+                                  ErrorResult& aRv)
+ {
+   return WorkerPrivate::Constructor(aGlobal, aScriptURL, true,
+                                     WorkerTypeDedicated, EmptyString(),
+                                     nullptr, aRv)
+diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
+--- a/dom/workers/WorkerPrivate.h
++++ b/dom/workers/WorkerPrivate.h
+@@ -973,19 +973,16 @@ public:
+               WorkerLoadInfo* aLoadInfo, ErrorResult& aRv);
+ 
+   static already_AddRefed<WorkerPrivate>
+   Constructor(JSContext* aCx, const nsAString& aScriptURL, bool aIsChromeWorker,
+               WorkerType aWorkerType, const nsAString& aWorkerName,
+               const nsACString& aServiceWorkerScope,
+               WorkerLoadInfo* aLoadInfo, ErrorResult& aRv);
+ 
+-  static bool
+-  WorkerAvailable(JSContext* /* unused */, JSObject* /* unused */);
+-
+   enum LoadGroupBehavior
+   {
+     InheritLoadGroup,
+     OverrideLoadGroup
+   };
+ 
+   static nsresult
+   GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
+diff --git a/dom/workers/test/chrome.ini b/dom/workers/test/chrome.ini
+--- a/dom/workers/test/chrome.ini
++++ b/dom/workers/test/chrome.ini
+@@ -47,17 +47,16 @@ support-files =
+   filePosting_worker.js
+   fileReadSlice_worker.js
+   fileReaderSyncErrors_worker.js
+   fileReaderSync_worker.js
+   fileSlice_worker.js
+   fileSubWorker_worker.js
+   file_worker.js
+   sharedWorker_privateBrowsing.js
+-  workersDisabled_worker.js
+ 
+ [test_WorkerDebugger.initialize.xul]
+ [test_WorkerDebugger.postMessage.xul]
+ [test_WorkerDebugger.xul]
+ [test_WorkerDebuggerGlobalScope.createSandbox.xul]
+ [test_WorkerDebuggerGlobalScope.enterEventLoop.xul]
+ [test_WorkerDebuggerGlobalScope.reportError.xul]
+ skip-if = (os == 'linux') # Bug 1244697
+@@ -76,11 +75,10 @@ skip-if = (os == 'linux') # Bug 1244409
+ [test_fileBlobPosting.xul]
+ [test_fileBlobSubWorker.xul]
+ [test_filePosting.xul]
+ [test_fileReadSlice.xul]
+ [test_fileReaderSync.xul]
+ [test_fileReaderSyncErrors.xul]
+ [test_fileSlice.xul]
+ [test_fileSubWorker.xul]
+-[test_workersDisabled.xul]
+ [test_bug1062920.xul]
+ [test_sharedWorker_privateBrowsing.html]
+diff --git a/dom/workers/test/mochitest.ini b/dom/workers/test/mochitest.ini
+--- a/dom/workers/test/mochitest.ini
++++ b/dom/workers/test/mochitest.ini
+@@ -67,17 +67,16 @@ support-files =
+   threadErrors_worker1.js
+   threadErrors_worker2.js
+   threadErrors_worker3.js
+   threadErrors_worker4.js
+   threadTimeouts_worker.js
+   throwingOnerror_worker.js
+   timeoutTracing_worker.js
+   transferable_worker.js
+-  workersDisabled_worker.js
+   test_worker_interfaces.js
+   worker_driver.js
+   worker_wrapper.js
+   bug1060621_worker.js
+   bug1062920_worker.js
+   bug1104064_worker.js
+   worker_consoleAndBlobs.js
+   bug1132395_sharedWorker.js
+@@ -180,17 +179,16 @@ support-files =
+ [test_threadErrors.html]
+ [test_threadTimeouts.html]
+ [test_throwingOnerror.html]
+ [test_timeoutTracing.html]
+ [test_transferable.html]
+ [test_worker_interfaces.html]
+ [test_worker_interfaces_secureContext.html]
+ scheme=https
+-[test_workersDisabled.html]
+ [test_referrer.html]
+ [test_referrer_header_worker.html]
+ [test_importScripts_3rdparty.html]
+ [test_sharedWorker_ports.html]
+ [test_sharedWorker_lifetime.html]
+ [test_navigator_workers_hardwareConcurrency.html]
+ [test_bug1278777.html]
+ [test_setTimeoutWith0.html]
+diff --git a/dom/workers/test/test_workersDisabled.html b/dom/workers/test/test_workersDisabled.html
+deleted file mode 100644
+--- a/dom/workers/test/test_workersDisabled.html
++++ /dev/null
+@@ -1,54 +0,0 @@
+-<!--
+-  Any copyright is dedicated to the Public Domain.
+-  http://creativecommons.org/publicdomain/zero/1.0/
+--->
+-<!DOCTYPE HTML>
+-<html>
+-  <head>
+-    <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js">
+-    </script>
+-    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+-  </head>
+-  <body>
+-    <script type="text/javascript">
+-      SimpleTest.waitForExplicitFinish();
+-
+-      const enabledPref = "dom.workers.enabled";
+-
+-      is(SpecialPowers.getBoolPref(enabledPref), true,
+-         "Workers should be enabled.");
+-
+-      SpecialPowers.pushPrefEnv({"set": [[enabledPref, false]]}, test1);
+-
+-      function test1() {
+-        ok(!("Worker" in window), "Worker constructor should not be available.");
+-
+-        var exception;
+-        try {
+-          var worker = new Worker("workersDisabled_worker.js");
+-        }
+-        catch(e) {
+-          exception = e;
+-        }
+-
+-        ok(exception, "Shouldn't be able to make a worker.");
+-
+-        SpecialPowers.pushPrefEnv({"set": [[enabledPref, true]]}, test2);
+-      }
+-
+-      function test2() {
+-        ok(("Worker" in window), "Worker constructor should be available.");
+-
+-        const message = "Hi";
+-
+-        var worker = new Worker("workersDisabled_worker.js");
+-        worker.onmessage = function(event) {
+-          is(event.data, message, "Good message.");
+-          SimpleTest.finish();
+-        }
+-        worker.postMessage(message);
+-      }
+-    </script>
+-  </body>
+-</html>
+-
+diff --git a/dom/workers/test/test_workersDisabled.xul b/dom/workers/test/test_workersDisabled.xul
+deleted file mode 100644
+--- a/dom/workers/test/test_workersDisabled.xul
++++ /dev/null
+@@ -1,49 +0,0 @@
+-<?xml version="1.0"?>
+-<!--
+-  Any copyright is dedicated to the Public Domain.
+-  http://creativecommons.org/publicdomain/zero/1.0/
+--->
+-<window title="DOM Worker Threads Test"
+-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+-        onload="test();">
+-  <script type="application/javascript"
+-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+-  <script type="application/javascript" src="dom_worker_helper.js"/>
+-
+-  <script type="application/javascript">
+-  <![CDATA[
+-    function test()
+-    {
+-      const enabledPref = "dom.workers.enabled";
+-      const message = "Hi";
+-
+-      var prefs = Cc["@mozilla.org/preferences-service;1"]
+-                    .getService(Ci.nsIPrefBranch);
+-      is(prefs.getBoolPref(enabledPref), true, "Workers should be enabled.");
+-
+-      prefs.setBoolPref(enabledPref, false);
+-
+-      ok("Worker" in window, "Worker constructor should be available.");
+-      ok("ChromeWorker" in window,
+-         "ChromeWorker constructor should be available.");
+-
+-      var worker = new ChromeWorker("workersDisabled_worker.js");
+-      worker.onmessage = function(event) {
+-        is(event.data, message, "Good message.");
+-        prefs.clearUserPref(enabledPref);
+-        finish();
+-      }
+-      worker.postMessage(message);
+-
+-      waitForWorkerFinish();
+-    }
+-  ]]>
+-  </script>
+-
+-  <body xmlns="http://www.w3.org/1999/xhtml">
+-    <p id="display"></p>
+-    <div id="content" style="display:none;"></div>
+-    <pre id="test"></pre>
+-  </body>
+-  <label id="test-result"/>
+-</window>
+diff --git a/dom/workers/test/workersDisabled_worker.js b/dom/workers/test/workersDisabled_worker.js
+deleted file mode 100644
+--- a/dom/workers/test/workersDisabled_worker.js
++++ /dev/null
+@@ -1,7 +0,0 @@
+-/**
+- * Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/publicdomain/zero/1.0/
+- */
+-onmessage = function(event) {
+-  postMessage(event.data);
+-}
+diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
+--- a/modules/libpref/init/all.js
++++ b/modules/libpref/init/all.js
+@@ -136,19 +136,16 @@ pref("dom.select_events.enabled", true);
+ 
+ // Whether or not selection events on text controls are enabled
+ #ifdef NIGHTLY_BUILD
+ pref("dom.select_events.textcontrols.enabled", true);
+ #else
+ pref("dom.select_events.textcontrols.enabled", false);
+ #endif
+ 
+-// Whether or not Web Workers are enabled.
+-pref("dom.workers.enabled", true);
+-
+ // The number of workers per domain allowed to run concurrently.
+ // We're going for effectively infinite, while preventing abuse.
+ pref("dom.workers.maxPerDomain", 512);
+ 
+ pref("dom.serviceWorkers.enabled", false);
+ 
+ // The amount of time (milliseconds) service workers keep running after each event.
+ pref("dom.serviceWorkers.idle_timeout", 30000);

+ 5 - 5
mozilla-release/patches/1461181-62a1.patch

@@ -2,13 +2,13 @@
 # User Ben Kelly <ben@wanderview.com>
 # Date 1526919227 25200
 # Node ID d5ec7b9c344ae2475ff6c411c3776c7c33353ec5
-# Parent  8de806ff35346971b1fb89ed836cc33501b9233d
+# Parent  d3cb10254ce32407365aae87f584318219a27050
 Bug 1461181 Don't call ServiceWorkerManager::StartControllingClient() if there is no active worker. r=asuth
 
 diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/ServiceWorkerManager.cpp
 --- a/dom/serviceworkers/ServiceWorkerManager.cpp
 +++ b/dom/serviceworkers/ServiceWorkerManager.cpp
-@@ -308,17 +308,17 @@ ServiceWorkerManager::Init(ServiceWorker
+@@ -306,17 +306,17 @@ ServiceWorkerManager::Init(ServiceWorker
  
    mActor = static_cast<ServiceWorkerManagerChild*>(actor);
  }
@@ -27,7 +27,7 @@ diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/Se
  
    auto entry = mControlledClients.LookupForAdd(aClientInfo.Id());
    if (entry) {
-@@ -2172,16 +2172,17 @@ ServiceWorkerManager::StartControlling(c
+@@ -2170,16 +2170,17 @@ ServiceWorkerManager::StartControlling(c
    nsCOMPtr<nsIURI> scope;
    nsresult rv =
      NS_NewURI(getter_AddRefs(scope), aServiceWorker.Scope(), nullptr, nullptr);
@@ -45,7 +45,7 @@ diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/Se
  
  void
  ServiceWorkerManager::MaybeCheckNavigationUpdate(const ClientInfo& aClientInfo)
-@@ -2920,20 +2921,25 @@ ServiceWorkerManager::UpdateInternal(nsI
+@@ -2919,20 +2920,25 @@ ServiceWorkerManager::UpdateInternal(nsI
    queue->ScheduleJob(job);
  }
  
@@ -65,7 +65,7 @@ diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/Se
 +  }
 +
    // Same origin check
-   if (!aWorkerRegistration->mPrincipal->Equals(aDocument->NodePrincipal())) {
+   if (!aWorkerRegistration->Principal()->Equals(aDocument->NodePrincipal())) {
      ref = GenericPromise::CreateAndReject(NS_ERROR_DOM_SECURITY_ERR, __func__);
      return ref.forget();
    }

+ 3 - 3
mozilla-release/patches/1463048-64a1.patch

@@ -2,7 +2,7 @@
 # User Gabriele Svelto <gsvelto@mozilla.com>
 # Date 1537217505 0
 # Node ID 588d96e4eec804258700aed86937c5ac1bfcab51
-# Parent  b6c4c753fad0b3df4ea5fecaaa62c670fcb80b2c
+# Parent  8581be9848a635c91fe8ee40a759be35f30e7cf7
 Bug 1463048 - Remove asynchronous minidump generation r=ted
 
 This reverts the changes in bug 1360308, bug 1390143 and bug 1469603. Minidump
@@ -16,7 +16,7 @@ Differential Revision: https://phabricator.services.mozilla.com/D5147
 diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
 --- a/dom/ipc/ContentParent.cpp
 +++ b/dom/ipc/ContentParent.cpp
-@@ -3047,43 +3047,26 @@ ContentParent::KillHard(const char* aRea
+@@ -3060,43 +3060,26 @@ ContentParent::KillHard(const char* aRea
      // it exists and is being appended.
      nsAutoCString additionalDumps("browser");
      mCrashReporter->AddAnnotation(
@@ -43,7 +43,7 @@ diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
 -    mCrashReporter->GenerateMinidumpAndPair(Process(),
 -                                            nullptr,
 -                                            NS_LITERAL_CSTRING("browser"),
--                                            Move(callback),
+-                                            std::move(callback),
 -                                            true);
 -    return;
 -  }

+ 184 - 516
mozilla-release/patches/1465060-1-std-62a1.patch

@@ -2,7 +2,7 @@
 # User Miko Mynttinen <mikokm@gmail.com>
 # Date 1527868747 -7200
 # Node ID a0d11b55d5957a488b41420c4f6cc178df7cd2e7
-# Parent  6c7be6261c6a2811dcc547aeb244dd0bfc3375cf
+# Parent  e4c9452bebcac5f0468b43afcc0cbad9e66c3bf7
 Bug 1465060 - Part 1: Fix warnings for std::move() use r=froydnj
 
 MozReview-Commit-ID: HpdFXqQdIOO
@@ -264,7 +264,7 @@ diff --git a/dom/base/nsContentPermissionHelper.cpp b/dom/base/nsContentPermissi
 diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
 --- a/dom/base/nsDocument.cpp
 +++ b/dom/base/nsDocument.cpp
-@@ -5671,39 +5671,39 @@ nsIDocument::GetAnonRootIfInAnonymousCon
+@@ -5693,39 +5693,39 @@ nsIDocument::GetAnonRootIfInAnonymousCon
    return nullptr;
  }
  
@@ -316,7 +316,7 @@ diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
 diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
 --- a/dom/base/nsGlobalWindow.cpp
 +++ b/dom/base/nsGlobalWindow.cpp
-@@ -4488,29 +4488,29 @@ void
+@@ -4489,35 +4489,35 @@ void
  nsPIDOMWindowInner::SyncStateFromParentWindow()
  {
    nsGlobalWindow::Cast(this)->SyncStateFromParentWindow();
@@ -343,13 +343,20 @@ diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
 +  return nsGlobalWindow::Cast(this)->GetController();
  }
  
+ RefPtr<mozilla::dom::ServiceWorker>
+ nsPIDOMWindowInner::GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor)
+ {
+-  return std::move(nsGlobalWindow::Cast(this)->GetOrCreateServiceWorker(aDescriptor));
++  return nsGlobalWindow::Cast(this)->GetOrCreateServiceWorker(aDescriptor);
+ }
+ 
  void
  nsPIDOMWindowInner::NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope)
  {
    nsGlobalWindow::Cast(this)->NoteCalledRegisterForServiceWorkerScope(aScope);
  }
  
-@@ -11958,17 +11958,17 @@ nsGlobalWindow::ShowSlowScriptDialog(con
+@@ -11965,17 +11965,17 @@ nsGlobalWindow::ShowSlowScriptDialog(con
    auto getString = [&] (const char* name,
                          nsContentUtils::PropertiesFile propFile = nsContentUtils::eDOM_PROPERTIES) {
      nsAutoString result;
@@ -368,7 +375,7 @@ diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
    // Get localizable strings
  
    nsAutoString title, checkboxMsg, debugButton, msg;
-@@ -12812,43 +12812,43 @@ nsGlobalWindow::CallOnChildren(Method aM
+@@ -12819,43 +12819,43 @@ nsGlobalWindow::CallOnChildren(Method aM
  Maybe<ClientInfo>
  nsGlobalWindow::GetClientInfo() const
  {
@@ -409,16 +416,16 @@ diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
 +  return controller;
  }
  
- nsresult
- nsGlobalWindow::FireDelayedDOMEvents()
+ RefPtr<ServiceWorker>
+ nsGlobalWindow::GetOrCreateServiceWorker(const ServiceWorkerDescriptor& aDescriptor)
  {
-   FORWARD_TO_INNER(FireDelayedDOMEvents, (), NS_ERROR_UNEXPECTED);
- 
-   if (mApplicationCache) {
+   MOZ_ASSERT(NS_IsMainThread());
+   RefPtr<ServiceWorker> ref;
+   for (auto sw : mServiceWorkerList) {
 diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp
 --- a/dom/canvas/ImageBitmap.cpp
 +++ b/dom/canvas/ImageBitmap.cpp
-@@ -792,17 +792,17 @@ ImageBitmap::ToCloneData() const
+@@ -790,17 +790,17 @@ ImageBitmap::ToCloneData() const
    UniquePtr<ImageBitmapCloneData> result(new ImageBitmapCloneData());
    result->mPictureRect = mPictureRect;
    result->mAlphaType = mAlphaType;
@@ -558,7 +565,7 @@ diff --git a/dom/clients/manager/ClientInfo.cpp b/dom/clients/manager/ClientInfo
 diff --git a/dom/clients/manager/ClientManager.cpp b/dom/clients/manager/ClientManager.cpp
 --- a/dom/clients/manager/ClientManager.cpp
 +++ b/dom/clients/manager/ClientManager.cpp
-@@ -109,30 +109,30 @@ ClientManager::CreateSourceInternal(Clie
+@@ -106,30 +106,30 @@ ClientManager::CreateSourceInternal(Clie
    if (NS_WARN_IF(NS_FAILED(rv))) {
      // If we can't even get a UUID, at least make sure not to use a garbage
      // value.  Instead return a shutdown ClientSource with a zero'd id.
@@ -619,7 +626,7 @@ diff --git a/dom/clients/manager/ClientManagerService.cpp b/dom/clients/manager/
 diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
 --- a/dom/console/Console.cpp
 +++ b/dom/console/Console.cpp
-@@ -2506,36 +2506,36 @@ Console::MonotonicTimer(JSContext* aCx, 
+@@ -2505,36 +2505,36 @@ Console::MonotonicTimer(JSContext* aCx, 
          return false;
        }
  
@@ -906,142 +913,6 @@ diff --git a/dom/media/eme/MediaKeySystemAccess.cpp b/dom/media/eme/MediaKeySyst
  // a single function.
  static bool
  CheckRequirement(const MediaKeysRequirement aRequirement,
-diff --git a/dom/media/fake-cdm/cdm-test-decryptor.cpp b/dom/media/fake-cdm/cdm-test-decryptor.cpp
---- a/dom/media/fake-cdm/cdm-test-decryptor.cpp
-+++ b/dom/media/fake-cdm/cdm-test-decryptor.cpp
-@@ -106,17 +106,17 @@ Tokenize(const std::string& aString)
- static const string TruncateRecordId = "truncate-record-id";
- static const string TruncateRecordData = "I will soon be truncated";
- 
- template<class Continuation>
- class WriteRecordSuccessTask {
- public:
-   WriteRecordSuccessTask(string aId, Continuation aThen)
-     : mId(aId)
--    , mThen(move(aThen))
-+    , mThen(std::move(aThen))
-   {}
- 
-   void operator()()
-   {
-     ReadRecord(FakeDecryptor::sInstance->mHost, mId, mThen);
-   }
- 
-   string mId;
-diff --git a/dom/media/fake-cdm/cdm-test-storage.cpp b/dom/media/fake-cdm/cdm-test-storage.cpp
---- a/dom/media/fake-cdm/cdm-test-storage.cpp
-+++ b/dom/media/fake-cdm/cdm-test-storage.cpp
-@@ -14,18 +14,18 @@ using namespace std;
- 
- class WriteRecordClient : public FileIOClient
- {
- public:
-   WriteRecordClient(function<void()>&& aOnSuccess,
-                     function<void()>&& aOnFailure,
-                     const uint8_t* aData,
-                     uint32_t aDataSize)
--    : mOnSuccess(move(aOnSuccess))
--    , mOnFailure(move(aOnFailure))
-+    : mOnSuccess(std::move(aOnSuccess))
-+    , mOnFailure(std::move(aOnFailure))
-   {
-     mData.insert(mData.end(), aData, aData + aDataSize);
-   }
- 
-   void OnOpenComplete(Status aStatus) override
-   {
-     // If we hit an error, fail.
-     if (aStatus != Status::kSuccess) {
-@@ -85,43 +85,43 @@ void
- WriteRecord(Host_9* aHost,
-             const std::string& aRecordName,
-             const uint8_t* aData,
-             uint32_t aNumBytes,
-             function<void()>&& aOnSuccess,
-             function<void()>&& aOnFailure)
- {
-   // client will be delete in WriteRecordClient::Done
--  WriteRecordClient* client = new WriteRecordClient(move(aOnSuccess),
--                                                    move(aOnFailure),
-+  WriteRecordClient* client = new WriteRecordClient(std::move(aOnSuccess),
-+                                                    std::move(aOnFailure),
-                                                     aData,
-                                                     aNumBytes);
-   client->Do(aRecordName, aHost);
- }
- 
- void
- WriteRecord(Host_9* aHost,
-             const std::string& aRecordName,
-             const std::string& aData,
-             function<void()> &&aOnSuccess,
-             function<void()>&& aOnFailure)
- {
-   return WriteRecord(aHost,
-                      aRecordName,
-                      (const uint8_t*)aData.c_str(),
-                      aData.size(),
--                     move(aOnSuccess),
--                     move(aOnFailure));
-+                     std::move(aOnSuccess),
-+                     std::move(aOnFailure));
- }
- 
- class ReadRecordClient : public FileIOClient
- {
- public:
-   explicit ReadRecordClient(function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete)
--    : mOnReadComplete(move(aOnReadComplete))
-+    : mOnReadComplete(std::move(aOnReadComplete))
-   {
-   }
- 
-   void OnOpenComplete(Status aStatus) override
-   {
-     auto err = aStatus;
-     if (aStatus != Status::kSuccess) {
-       Done(err, reinterpret_cast<const uint8_t*>(""), 0);
-@@ -176,25 +176,25 @@ private:
- };
- 
- void
- ReadRecord(Host_9* aHost,
-            const std::string& aRecordName,
-            function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete)
- {
-   // client will be delete in ReadRecordClient::Done
--  ReadRecordClient* client = new ReadRecordClient(move(aOnReadComplete));
-+  ReadRecordClient* client = new ReadRecordClient(std::move(aOnReadComplete));
-   client->Do(aRecordName, aHost);
- }
- 
- class OpenRecordClient : public FileIOClient
- {
- public:
-   explicit OpenRecordClient(function<void(bool)>&& aOpenComplete)
--    : mOpenComplete(move(aOpenComplete))
-+    : mOpenComplete(std::move(aOpenComplete))
-   {
-   }
- 
-   void OnOpenComplete(Status aStatus) override
-   {
-     Done(aStatus);
-   }
- 
-@@ -242,11 +242,11 @@ private:
- };
- 
- void
- OpenRecord(Host_9* aHost,
-            const std::string& aRecordName,
-            function<void(bool)>&& aOpenComplete)
- {
-   // client will be delete in OpenRecordClient::Done
--  OpenRecordClient* client = new OpenRecordClient(move(aOpenComplete));
-+  OpenRecordClient* client = new OpenRecordClient(std::move(aOpenComplete));
-   client->Do(aRecordName, aHost);
- }
 diff --git a/dom/media/gmp/ChromiumCDMParent.cpp b/dom/media/gmp/ChromiumCDMParent.cpp
 --- a/dom/media/gmp/ChromiumCDMParent.cpp
 +++ b/dom/media/gmp/ChromiumCDMParent.cpp
@@ -1215,6 +1086,65 @@ diff --git a/dom/media/platforms/omx/OmxPlatformLayer.cpp b/dom/media/platforms/
    MOZ_ASSERT(mInfo);
  
    OMX_PORT_PARAM_TYPE portParam;
+diff --git a/dom/serviceworkers/ServiceWorkerManager.cpp b/dom/serviceworkers/ServiceWorkerManager.cpp
+--- a/dom/serviceworkers/ServiceWorkerManager.cpp
++++ b/dom/serviceworkers/ServiceWorkerManager.cpp
+@@ -318,51 +318,51 @@ ServiceWorkerManager::StartControllingCl
+   const ServiceWorkerDescriptor& active =
+     aRegistrationInfo->GetActive()->Descriptor();
+ 
+   auto entry = mControlledClients.LookupForAdd(aClientInfo.Id());
+   if (entry) {
+     RefPtr<ServiceWorkerRegistrationInfo> old =
+       entry.Data()->mRegistrationInfo.forget();
+ 
+-    ref = std::move(entry.Data()->mClientHandle->Control(active));
++    ref = entry.Data()->mClientHandle->Control(active);
+     entry.Data()->mRegistrationInfo = aRegistrationInfo;
+ 
+     if (old != aRegistrationInfo) {
+       StopControllingRegistration(old);
+       aRegistrationInfo->StartControllingClient();
+     }
+ 
+     Telemetry::Accumulate(Telemetry::SERVICE_WORKER_CONTROLLED_DOCUMENTS, 1);
+ 
+-    return std::move(ref);
++    return ref;
+   }
+ 
+   RefPtr<ClientHandle> clientHandle =
+     ClientManager::CreateHandle(aClientInfo,
+                                 SystemGroup::EventTargetFor(TaskCategory::Other));
+ 
+-  ref = std::move(clientHandle->Control(active));
++  ref = clientHandle->Control(active);
+ 
+   aRegistrationInfo->StartControllingClient();
+ 
+   entry.OrInsert([&] {
+     return new ControlledClientData(clientHandle, aRegistrationInfo);
+   });
+ 
+   RefPtr<ServiceWorkerManager> self(this);
+   clientHandle->OnDetach()->Then(
+     SystemGroup::EventTargetFor(TaskCategory::Other), __func__,
+     [self = std::move(self), aClientInfo] {
+       self->StopControllingClient(aClientInfo);
+     });
+ 
+   Telemetry::Accumulate(Telemetry::SERVICE_WORKER_CONTROLLED_DOCUMENTS, 1);
+ 
+-  return std::move(ref);
++  return ref;
+ }
+ 
+ void
+ ServiceWorkerManager::StopControllingClient(const ClientInfo& aClientInfo)
+ {
+   auto entry = mControlledClients.Lookup(aClientInfo.Id());
+   if (!entry) {
+     return;
 diff --git a/dom/serviceworkers/ServiceWorkerRegistrar.cpp b/dom/serviceworkers/ServiceWorkerRegistrar.cpp
 --- a/dom/serviceworkers/ServiceWorkerRegistrar.cpp
 +++ b/dom/serviceworkers/ServiceWorkerRegistrar.cpp
@@ -1237,6 +1167,87 @@ diff --git a/dom/serviceworkers/ServiceWorkerRegistrar.cpp b/dom/serviceworkers/
  ServiceWorkerRegistrar::Shutdown()
  {
    AssertIsOnBackgroundThread();
+diff --git a/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp
+--- a/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp
++++ b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp
+@@ -17,17 +17,17 @@ ServiceWorkerRegistrationDescriptor::New
+   Maybe<IPCServiceWorkerDescriptor> result;
+   if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(mData->installing().get_IPCServiceWorkerDescriptor());
+   } else if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(mData->waiting().get_IPCServiceWorkerDescriptor());
+   } else if (mData->active().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(mData->active().get_IPCServiceWorkerDescriptor());
+   }
+-  return std::move(result);
++  return result;
+ }
+ 
+ ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
+                                     nsIPrincipal* aPrincipal,
+                                     const nsACString& aScope,
+                                     ServiceWorkerUpdateViaCache aUpdateViaCache)
+   : mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>())
+ {
+@@ -121,54 +121,54 @@ ServiceWorkerRegistrationDescriptor::Get
+ {
+   Maybe<ServiceWorkerDescriptor> result;
+ 
+   if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(ServiceWorkerDescriptor(
+       mData->installing().get_IPCServiceWorkerDescriptor()));
+   }
+ 
+-  return std::move(result);
++  return result;
+ }
+ 
+ Maybe<ServiceWorkerDescriptor>
+ ServiceWorkerRegistrationDescriptor::GetWaiting() const
+ {
+   Maybe<ServiceWorkerDescriptor> result;
+ 
+   if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(ServiceWorkerDescriptor(
+       mData->waiting().get_IPCServiceWorkerDescriptor()));
+   }
+ 
+-  return std::move(result);
++  return result;
+ }
+ 
+ Maybe<ServiceWorkerDescriptor>
+ ServiceWorkerRegistrationDescriptor::GetActive() const
+ {
+   Maybe<ServiceWorkerDescriptor> result;
+ 
+   if (mData->active().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(ServiceWorkerDescriptor(
+       mData->active().get_IPCServiceWorkerDescriptor()));
+   }
+ 
+-  return std::move(result);
++  return result;
+ }
+ 
+ Maybe<ServiceWorkerDescriptor>
+ ServiceWorkerRegistrationDescriptor::Newest() const
+ {
+   Maybe<ServiceWorkerDescriptor> result;
+   Maybe<IPCServiceWorkerDescriptor> newest(NewestInternal());
+   if (newest.isSome()) {
+     result.emplace(ServiceWorkerDescriptor(newest.ref()));
+   }
+-  return std::move(result);
++  return result;
+ }
+ 
+ namespace {
+ 
+ bool
+ IsValidWorker(const OptionalIPCServiceWorkerDescriptor& aWorker,
+               const nsACString& aScope,
+               const mozilla::ipc::ContentPrincipalInfo& aContentPrincipal)
 diff --git a/dom/u2f/U2F.cpp b/dom/u2f/U2F.cpp
 --- a/dom/u2f/U2F.cpp
 +++ b/dom/u2f/U2F.cpp
@@ -1278,6 +1289,28 @@ diff --git a/dom/u2f/U2F.cpp b/dom/u2f/U2F.cpp
                          const WebAuthnGetAssertionResult& aResult)
  {
    MOZ_ASSERT(NS_IsMainThread());
+diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp
+--- a/dom/workers/WorkerScope.cpp
++++ b/dom/workers/WorkerScope.cpp
+@@ -524,17 +524,17 @@ WorkerGlobalScope::GetClientInfo() const
+   return std::move(info);
+ }
+ 
+ Maybe<ClientState>
+ WorkerGlobalScope::GetClientState() const
+ {
+   Maybe<ClientState> state;
+   state.emplace(mWorkerPrivate->GetClientState());
+-  return std::move(state);
++  return state;
+ }
+ 
+ Maybe<ServiceWorkerDescriptor>
+ WorkerGlobalScope::GetController() const
+ {
+   return mWorkerPrivate->GetController();
+ }
+ 
 diff --git a/editor/libeditor/HTMLAnonymousNodeEditor.cpp b/editor/libeditor/HTMLAnonymousNodeEditor.cpp
 --- a/editor/libeditor/HTMLAnonymousNodeEditor.cpp
 +++ b/editor/libeditor/HTMLAnonymousNodeEditor.cpp
@@ -2137,7 +2170,7 @@ diff --git a/image/test/gtest/TestSurfacePipeIntegration.cpp b/image/test/gtest/
 diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp
 --- a/js/src/builtin/TestingFunctions.cpp
 +++ b/js/src/builtin/TestingFunctions.cpp
-@@ -3384,17 +3384,17 @@ struct FindPathHandler {
+@@ -3383,17 +3383,17 @@ struct FindPathHandler {
          if (!first)
              return true;
  
@@ -2414,7 +2447,7 @@ diff --git a/js/xpconnect/loader/URLPreloader.cpp b/js/xpconnect/loader/URLPrelo
 diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
 --- a/layout/base/PresShell.cpp
 +++ b/layout/base/PresShell.cpp
-@@ -6227,17 +6227,17 @@ PresShell::Paint(nsView*         aViewTo
+@@ -6268,17 +6268,17 @@ PresShell::Paint(nsView*         aViewTo
        bool computeInvalidRect = computeInvalidFunc ||
                                  (layerManager->GetBackendType() == LayersBackend::LAYERS_BASIC);
  
@@ -2559,371 +2592,6 @@ diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionMan
  }
  
  static nsTArray<Keyframe>
-diff --git a/media/gmp-clearkey/0.1/ClearKeyPersistence.cpp b/media/gmp-clearkey/0.1/ClearKeyPersistence.cpp
---- a/media/gmp-clearkey/0.1/ClearKeyPersistence.cpp
-+++ b/media/gmp-clearkey/0.1/ClearKeyPersistence.cpp
-@@ -59,17 +59,17 @@ ClearKeyPersistence::ReadAllRecordsFromI
-     [self, aOnComplete] ()
-   {
-     CK_LOGD("ClearKeyPersistence: Failed to load index file (it might not exist");
-     self->mPersistentKeyState = PersistentKeyState::LOADED;
-     aOnComplete();
-   };
- 
-   string filename = "index";
--  ReadData(mHost, filename, move(onIndexSuccess), move(onIndexFailed));
-+  ReadData(mHost, filename, std::move(onIndexSuccess), std::move(onIndexFailed));
- }
- 
- void
- ClearKeyPersistence::WriteIndex() {
-   function <void()> onIndexSuccess =
-     [] ()
-   {
-     CK_LOGD("ClearKeyPersistence: Wrote index file");
-@@ -91,34 +91,34 @@ ClearKeyPersistence::WriteIndex() {
-   string dataString = ss.str();
-   uint8_t* dataArray = (uint8_t*)dataString.data();
-   vector<uint8_t> data(dataArray, dataArray + dataString.size());
- 
-   string filename = "index";
-   WriteData(mHost,
-             filename,
-             data,
--            move(onIndexSuccess),
--            move(onIndexFail));
-+            std::move(onIndexSuccess),
-+            std::move(onIndexFail));
- }
- 
- 
- ClearKeyPersistence::ClearKeyPersistence(Host_9* aHost)
- {
-   this->mHost = aHost;
- }
- 
- void
- ClearKeyPersistence::EnsureInitialized(bool aPersistentStateAllowed,
-                                        function<void()>&& aOnInitialized)
- {
-   if (aPersistentStateAllowed &&
-       mPersistentKeyState == PersistentKeyState::UNINITIALIZED) {
-     mPersistentKeyState = LOADING;
--    ReadAllRecordsFromIndex(move(aOnInitialized));
-+    ReadAllRecordsFromIndex(std::move(aOnInitialized));
-   } else {
-     mPersistentKeyState = PersistentKeyState::LOADED;
-     aOnInitialized();
-   }
- }
- 
- bool ClearKeyPersistence::IsLoaded() const
- {
-diff --git a/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp b/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp
---- a/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp
-+++ b/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp
-@@ -62,17 +62,17 @@ ClearKeySessionManager::Init(bool aDisti
-       function<void()> func = self->mDeferredInitialize.front();
-       self->mDeferredInitialize.pop();
- 
-       func();
-     }
-   };
- 
-   mPersistence->EnsureInitialized(aPersistentStateAllowed,
--                                  move(onPersistentStateLoaded));
-+                                  std::move(onPersistentStateLoaded));
- }
- 
- void
- ClearKeySessionManager::CreateSession(uint32_t aPromiseId,
-                                       InitDataType aInitDataType,
-                                       const uint8_t* aInitData,
-                                       uint32_t aInitDataSize,
-                                       SessionType aSessionType)
-@@ -89,17 +89,17 @@ ClearKeySessionManager::CreateSession(ui
-     self->CreateSession(aPromiseId,
-                         aInitDataType,
-                         initData.data(),
-                         initData.size(),
-                         aSessionType);
-   };
- 
-   // If we haven't loaded, don't do this yet
--  if (MaybeDeferTillInitialized(move(deferrer))) {
-+  if (MaybeDeferTillInitialized(std::move(deferrer))) {
-     CK_LOGD("Deferring CreateSession");
-     return;
-   }
- 
-   CK_LOGARRAY("ClearKeySessionManager::CreateSession initdata: ",
-               aInitData,
-               aInitDataSize);
- 
-@@ -195,17 +195,17 @@ ClearKeySessionManager::LoadSession(uint
-   // we try to use it.
-   RefPtr<ClearKeySessionManager> self(this);
-   function<void()> deferrer =
-     [self, aPromiseId, sessionId] ()
-   {
-     self->LoadSession(aPromiseId, sessionId.data(), sessionId.size());
-   };
- 
--  if (MaybeDeferTillInitialized(move(deferrer))) {
-+  if (MaybeDeferTillInitialized(std::move(deferrer))) {
-     CK_LOGD("Deferring LoadSession");
-     return;
-   }
- 
-   // If the SessionManager has been shutdown mHost will be null and we won't
-   // be able to resolve the promise.
-   if (!mHost) {
-     return;
-@@ -233,17 +233,17 @@ ClearKeySessionManager::LoadSession(uint
-   function<void()> failure = [self, aPromiseId] {
-     if (!self->mHost) {
-       return;
-     }
-     // As per the API described in ContentDecryptionModule_8
-     self->mHost->OnResolveNewSessionPromise(aPromiseId, nullptr, 0);
-   };
- 
--  ReadData(mHost, sessionId, move(success), move(failure));
-+  ReadData(mHost, sessionId, std::move(success), std::move(failure));
- }
- 
- void
- ClearKeySessionManager::PersistentSessionDataLoaded(uint32_t aPromiseId,
-                                                     const string& aSessionId,
-                                                     const uint8_t* aKeyData,
-                                                     uint32_t aKeyDataSize)
- {
-@@ -331,17 +331,17 @@ ClearKeySessionManager::UpdateSession(ui
-     self->UpdateSession(aPromiseId,
-                         sessionId.data(),
-                         sessionId.size(),
-                         response.data(),
-                         response.size());
-   };
- 
-   // If we haven't fully loaded, defer calling this method
--  if (MaybeDeferTillInitialized(move(deferrer))) {
-+  if (MaybeDeferTillInitialized(std::move(deferrer))) {
-     CK_LOGD("Deferring LoadSession");
-     return;
-   }
- 
-   // Make sure the SessionManager has not been shutdown before we try and
-   // resolve any promises.
-   if (!mHost) {
-     return;
-@@ -441,17 +441,17 @@ ClearKeySessionManager::UpdateSession(ui
-     static const char* message = "Couldn't store cenc key init data";
-     self->mHost->OnRejectPromise(aPromiseId,
-                                  Exception::kExceptionInvalidStateError,
-                                  0,
-                                  message,
-                                  strlen(message));
-   };
- 
--  WriteData(mHost, sessionId, keydata, move(resolve), move(reject));
-+  WriteData(mHost, sessionId, keydata, std::move(resolve), std::move(reject));
- }
- 
- void
- ClearKeySessionManager::Serialize(const ClearKeySession* aSession,
-                                   std::vector<uint8_t>& aOutKeyData)
- {
-   const std::vector<KeyId>& keyIds = aSession->GetKeyIds();
-   for (size_t i = 0; i < keyIds.size(); i++) {
-@@ -481,17 +481,17 @@ ClearKeySessionManager::CloseSession(uin
-   RefPtr<ClearKeySessionManager> self(this);
-   function<void()> deferrer =
-     [self, aPromiseId, sessionId] ()
-   {
-     self->CloseSession(aPromiseId, sessionId.data(), sessionId.size());
-   };
- 
-   // If we haven't loaded, call this method later.
--  if (MaybeDeferTillInitialized(move(deferrer))) {
-+  if (MaybeDeferTillInitialized(std::move(deferrer))) {
-     CK_LOGD("Deferring CloseSession");
-     return;
-   }
- 
-   // If DecryptingComplete has been called mHost will be null and we won't
-   // be able to resolve our promise.
-   if (!mHost) {
-     return;
-@@ -540,17 +540,17 @@ ClearKeySessionManager::RemoveSession(ui
-   RefPtr<ClearKeySessionManager> self(this);
-   function<void()> deferrer =
-     [self, aPromiseId, sessionId] ()
-   {
-     self->RemoveSession(aPromiseId, sessionId.data(), sessionId.size());
-   };
- 
-   // If we haven't fully loaded, defer calling this method.
--  if (MaybeDeferTillInitialized(move(deferrer))) {
-+  if (MaybeDeferTillInitialized(std::move(deferrer))) {
-     CK_LOGD("Deferring RemoveSession");
-     return;
-   }
- 
-   // Check that the SessionManager has not been shutdown before we try and
-   // resolve any promises.
-   if (!mHost) {
-     return;
-@@ -600,17 +600,17 @@ ClearKeySessionManager::RemoveSession(ui
-     static const char* message = "Could not remove session";
-     self->mHost->OnRejectPromise(aPromiseId,
-                                  Exception::kExceptionTypeError,
-                                  0,
-                                  message,
-                                  strlen(message));
-   };
- 
--  WriteData(mHost, sessionId, emptyKeydata, move(resolve), move(reject));
-+  WriteData(mHost, sessionId, emptyKeydata, std::move(resolve), std::move(reject));
- }
- 
- void
- ClearKeySessionManager::SetServerCertificate(uint32_t aPromiseId,
-                                              const uint8_t* aServerCert,
-                                              uint32_t aServerCertSize)
- {
-   // ClearKey CDM doesn't support this method by spec.
-@@ -669,11 +669,11 @@ ClearKeySessionManager::DecryptingComple
- }
- 
- bool ClearKeySessionManager::MaybeDeferTillInitialized(function<void()>&& aMaybeDefer)
- {
-   if (mPersistence->IsLoaded()) {
-     return false;
-   }
- 
--  mDeferredInitialize.emplace(move(aMaybeDefer));
-+  mDeferredInitialize.emplace(std::move(aMaybeDefer));
-   return true;
- }
-diff --git a/media/gmp-clearkey/0.1/ClearKeyStorage.cpp b/media/gmp-clearkey/0.1/ClearKeyStorage.cpp
---- a/media/gmp-clearkey/0.1/ClearKeyStorage.cpp
-+++ b/media/gmp-clearkey/0.1/ClearKeyStorage.cpp
-@@ -39,18 +39,18 @@ public:
-    */
-   static void Write(Host_9* aHost,
-                     string& aRecordName,
-                     const vector<uint8_t>& aData,
-                     function<void()>&& aOnSuccess,
-                     function<void()>&& aOnFailure)
- {
-     WriteRecordClient* client = new WriteRecordClient(aData,
--                                                      move(aOnSuccess),
--                                                      move(aOnFailure));
-+                                                      std::move(aOnSuccess),
-+                                                      std::move(aOnFailure));
-     client->Do(aRecordName, aHost);
-   }
- 
-   void OnOpenComplete(Status aStatus) override
-   {
-     // If we hit an error, fail.
-     if (aStatus != Status::kSuccess) {
-       Done(aStatus);
-@@ -73,18 +73,18 @@ public:
-     Done(aStatus);
-   }
- 
- private:
-   explicit WriteRecordClient(const vector<uint8_t>& aData,
-                              function<void()>&& aOnSuccess,
-                              function<void()>&& aOnFailure)
-     : mFileIO(nullptr)
--    , mOnSuccess(move(aOnSuccess))
--    , mOnFailure(move(aOnFailure))
-+    , mOnSuccess(std::move(aOnSuccess))
-+    , mOnFailure(std::move(aOnFailure))
-     , mData(aData) {}
- 
-   void Do(const string& aName, Host_9* aHost)
-   {
-     // Initialize the FileIO.
-     mFileIO = aHost->CreateFileIO(this);
-     mFileIO->Open(aName.c_str(), aName.size());
-   }
-@@ -122,34 +122,34 @@ WriteData(Host_9* aHost,
-           string& aRecordName,
-           const vector<uint8_t>& aData,
-           function<void()>&& aOnSuccess,
-           function<void()>&& aOnFailure)
- {
-   WriteRecordClient::Write(aHost,
-                            aRecordName,
-                            aData,
--                           move(aOnSuccess),
--                           move(aOnFailure));
-+                           std::move(aOnSuccess),
-+                           std::move(aOnFailure));
- }
- 
- class ReadRecordClient : public FileIOClient
- {
- public:
-   /*
-    * This function will take the memory ownership of the parameters and
-    * delete them when done.
-    */
-   static void Read(Host_9* aHost,
-                    string& aRecordName,
-                    function<void(const uint8_t*, uint32_t)>&& aOnSuccess,
-                    function<void()>&& aOnFailure)
-   {
- 
--    (new ReadRecordClient(move(aOnSuccess), move(aOnFailure)))->
-+    (new ReadRecordClient(std::move(aOnSuccess), std::move(aOnFailure)))->
-       Do(aRecordName, aHost);
-   }
- 
-   void OnOpenComplete(Status aStatus) override
-   {
-     auto err = aStatus;
-     if (aStatus != Status::kSuccess) {
-       Done(err, nullptr, 0);
-@@ -170,18 +170,18 @@ public:
-     // We should never reach here, this client only ever reads data.
-     assert(false);
-   }
- 
- private:
-   explicit ReadRecordClient(function<void(const uint8_t*, uint32_t)>&& aOnSuccess,
-                             function<void()>&& aOnFailure)
-     : mFileIO(nullptr)
--    , mOnSuccess(move(aOnSuccess))
--    , mOnFailure(move(aOnFailure))
-+    , mOnSuccess(std::move(aOnSuccess))
-+    , mOnFailure(std::move(aOnFailure))
-   {}
- 
-   void Do(const string& aName, Host_9* aHost)
-   {
-     mFileIO = aHost->CreateFileIO(this);
-     mFileIO->Open(aName.c_str(), aName.size());
-   }
- 
-@@ -216,11 +216,11 @@ private:
- void
- ReadData(Host_9* mHost,
-          string& aRecordName,
-          function<void(const uint8_t*, uint32_t)>&& aOnSuccess,
-          function<void()>&& aOnFailure)
- {
-   ReadRecordClient::Read(mHost,
-                          aRecordName,
--                         move(aOnSuccess),
--                         move(aOnFailure));
-+                         std::move(aOnSuccess),
-+                         std::move(aOnFailure));
- }
 diff --git a/media/webrtc/signaling/gtest/sdp_unittests.cpp.1465060.later b/media/webrtc/signaling/gtest/sdp_unittests.cpp.1465060.later
 new file mode 100644
 --- /dev/null

+ 164 - 28
mozilla-release/patches/1465585-3-std-62a1.patch

@@ -2,7 +2,7 @@
 # User Emilio Cobos Alvarez <emilio@crisal.io>
 # Date 1527707735 -7200
 # Node ID b54db66223586b4e04f5cb926fccdacf8a176b91
-# Parent  d602326c54e6ef5cb413805b8d764304eb6effd5
+# Parent  b64991489d0f4edc23c977362a8170a785f1b4d6
 Bug 1465585: Switch from mozilla::Move to std::move. r=froydnj
 
 This was done automatically replacing:
@@ -3426,7 +3426,7 @@ diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp
 diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
 --- a/dom/base/nsGlobalWindow.cpp
 +++ b/dom/base/nsGlobalWindow.cpp
-@@ -3499,29 +3499,29 @@ nsGlobalWindow::EnsureClientSource()
+@@ -3500,29 +3500,29 @@ nsGlobalWindow::EnsureClientSource()
    // Try to get the reserved client from the LoadInfo.  A Client is
    // reserved at the start of the channel load if there is not an
    // initial about:blank document that will be reused.  It is also
@@ -3458,7 +3458,7 @@ diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
    // Verify the final ClientSource principal matches the final document
    // principal.  The ClientChannelHelper handles things like network
    // redirects, but there are other ways the document principal can change.
-@@ -4488,29 +4488,29 @@ void
+@@ -4489,35 +4489,35 @@ void
  nsPIDOMWindowInner::SyncStateFromParentWindow()
  {
    nsGlobalWindow::Cast(this)->SyncStateFromParentWindow();
@@ -3485,13 +3485,20 @@ diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
 +  return std::move(nsGlobalWindow::Cast(this)->GetController());
  }
  
+ RefPtr<mozilla::dom::ServiceWorker>
+ nsPIDOMWindowInner::GetOrCreateServiceWorker(const mozilla::dom::ServiceWorkerDescriptor& aDescriptor)
+ {
+-  return Move(nsGlobalWindow::Cast(this)->GetOrCreateServiceWorker(aDescriptor));
++  return std::move(nsGlobalWindow::Cast(this)->GetOrCreateServiceWorker(aDescriptor));
+ }
+ 
  void
  nsPIDOMWindowInner::NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope)
  {
    nsGlobalWindow::Cast(this)->NoteCalledRegisterForServiceWorkerScope(aScope);
  }
  
-@@ -11958,17 +11958,17 @@ nsGlobalWindow::ShowSlowScriptDialog(con
+@@ -11965,17 +11965,17 @@ nsGlobalWindow::ShowSlowScriptDialog(con
    auto getString = [&] (const char* name,
                          nsContentUtils::PropertiesFile propFile = nsContentUtils::eDOM_PROPERTIES) {
      nsAutoString result;
@@ -3510,7 +3517,7 @@ diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
    // Get localizable strings
  
    nsAutoString title, checkboxMsg, debugButton, msg;
-@@ -12812,43 +12812,43 @@ nsGlobalWindow::CallOnChildren(Method aM
+@@ -12819,43 +12819,43 @@ nsGlobalWindow::CallOnChildren(Method aM
  Maybe<ClientInfo>
  nsGlobalWindow::GetClientInfo() const
  {
@@ -3551,13 +3558,13 @@ diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
 +  return std::move(controller);
  }
  
- nsresult
- nsGlobalWindow::FireDelayedDOMEvents()
+ RefPtr<ServiceWorker>
+ nsGlobalWindow::GetOrCreateServiceWorker(const ServiceWorkerDescriptor& aDescriptor)
  {
-   FORWARD_TO_INNER(FireDelayedDOMEvents, (), NS_ERROR_UNEXPECTED);
- 
-   if (mApplicationCache) {
-@@ -15185,19 +15185,19 @@ nsPIDOMWindow<T>::GetDocGroup() const
+   MOZ_ASSERT(NS_IsMainThread());
+   RefPtr<ServiceWorker> ref;
+   for (auto sw : mServiceWorkerList) {
+@@ -15225,19 +15225,19 @@ nsPIDOMWindow<T>::GetDocGroup() const
  }
  
  nsresult
@@ -8638,6 +8645,25 @@ diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
  
  mozilla::jsipc::PJavaScriptParent *
  ContentParent::AllocPJavaScriptParent()
+@@ -3072,17 +3072,17 @@ ContentParent::KillHard(const char* aRea
+     RefPtr<ContentParent> self = this;
+     std::function<void(bool)> callback = [self](bool aResult) {
+       self->OnGenerateMinidumpComplete(aResult);
+     };
+     // Generate the report and insert into the queue for submittal.
+     mCrashReporter->GenerateMinidumpAndPair(Process(),
+                                             nullptr,
+                                             NS_LITERAL_CSTRING("browser"),
+-                                            Move(callback),
++                                            std::move(callback),
+                                             true);
+     return;
+   }
+ 
+   OnGenerateMinidumpComplete(false);
+ }
+ 
+ void
 @@ -3319,17 +3319,17 @@ ContentParent::GetPrintingParent()
  mozilla::ipc::IPCResult
  ContentParent::RecvInitStreamFilter(const uint64_t& aChannelId,
@@ -17229,7 +17255,7 @@ diff --git a/dom/security/nsCSPUtils.cpp b/dom/security/nsCSPUtils.cpp
 diff --git a/dom/serviceworkers/ServiceWorkerDescriptor.cpp b/dom/serviceworkers/ServiceWorkerDescriptor.cpp
 --- a/dom/serviceworkers/ServiceWorkerDescriptor.cpp
 +++ b/dom/serviceworkers/ServiceWorkerDescriptor.cpp
-@@ -49,25 +49,25 @@ ServiceWorkerDescriptor&
+@@ -53,25 +53,25 @@ ServiceWorkerDescriptor&
  ServiceWorkerDescriptor::operator=(const ServiceWorkerDescriptor& aRight)
  {
    mData.reset();
@@ -17456,6 +17482,116 @@ diff --git a/dom/serviceworkers/ServiceWorkerRegistrar.cpp b/dom/serviceworkers/
  ServiceWorkerRegistrar::Shutdown()
  {
    AssertIsOnBackgroundThread();
+diff --git a/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp
+--- a/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp
++++ b/dom/serviceworkers/ServiceWorkerRegistrationDescriptor.cpp
+@@ -17,17 +17,17 @@ ServiceWorkerRegistrationDescriptor::New
+   Maybe<IPCServiceWorkerDescriptor> result;
+   if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(mData->installing().get_IPCServiceWorkerDescriptor());
+   } else if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(mData->waiting().get_IPCServiceWorkerDescriptor());
+   } else if (mData->active().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(mData->active().get_IPCServiceWorkerDescriptor());
+   }
+-  return Move(result);
++  return std::move(result);
+ }
+ 
+ ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
+                                     nsIPrincipal* aPrincipal,
+                                     const nsACString& aScope,
+                                     ServiceWorkerUpdateViaCache aUpdateViaCache)
+   : mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>())
+ {
+@@ -73,26 +73,26 @@ ServiceWorkerRegistrationDescriptor::ope
+ {
+   mData.reset();
+   mData = MakeUnique<IPCServiceWorkerRegistrationDescriptor>(*aRight.mData);
+   MOZ_DIAGNOSTIC_ASSERT(IsValid());
+   return *this;
+ }
+ 
+ ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(ServiceWorkerRegistrationDescriptor&& aRight)
+-  : mData(Move(aRight.mData))
++  : mData(std::move(aRight.mData))
+ {
+   MOZ_DIAGNOSTIC_ASSERT(IsValid());
+ }
+ 
+ ServiceWorkerRegistrationDescriptor&
+ ServiceWorkerRegistrationDescriptor::operator=(ServiceWorkerRegistrationDescriptor&& aRight)
+ {
+   mData.reset();
+-  mData = Move(aRight.mData);
++  mData = std::move(aRight.mData);
+   MOZ_DIAGNOSTIC_ASSERT(IsValid());
+   return *this;
+ }
+ 
+ bool
+ ServiceWorkerRegistrationDescriptor::operator==(const ServiceWorkerRegistrationDescriptor& aRight) const
+ {
+   return *mData == *aRight.mData;
+@@ -121,54 +121,54 @@ ServiceWorkerRegistrationDescriptor::Get
+ {
+   Maybe<ServiceWorkerDescriptor> result;
+ 
+   if (mData->installing().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(ServiceWorkerDescriptor(
+       mData->installing().get_IPCServiceWorkerDescriptor()));
+   }
+ 
+-  return Move(result);
++  return std::move(result);
+ }
+ 
+ Maybe<ServiceWorkerDescriptor>
+ ServiceWorkerRegistrationDescriptor::GetWaiting() const
+ {
+   Maybe<ServiceWorkerDescriptor> result;
+ 
+   if (mData->waiting().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(ServiceWorkerDescriptor(
+       mData->waiting().get_IPCServiceWorkerDescriptor()));
+   }
+ 
+-  return Move(result);
++  return std::move(result);
+ }
+ 
+ Maybe<ServiceWorkerDescriptor>
+ ServiceWorkerRegistrationDescriptor::GetActive() const
+ {
+   Maybe<ServiceWorkerDescriptor> result;
+ 
+   if (mData->active().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
+     result.emplace(ServiceWorkerDescriptor(
+       mData->active().get_IPCServiceWorkerDescriptor()));
+   }
+ 
+-  return Move(result);
++  return std::move(result);
+ }
+ 
+ Maybe<ServiceWorkerDescriptor>
+ ServiceWorkerRegistrationDescriptor::Newest() const
+ {
+   Maybe<ServiceWorkerDescriptor> result;
+   Maybe<IPCServiceWorkerDescriptor> newest(NewestInternal());
+   if (newest.isSome()) {
+     result.emplace(ServiceWorkerDescriptor(newest.ref()));
+   }
+-  return Move(result);
++  return std::move(result);
+ }
+ 
+ namespace {
+ 
+ bool
+ IsValidWorker(const OptionalIPCServiceWorkerDescriptor& aWorker,
+               const nsACString& aScope,
+               const mozilla::ipc::ContentPrincipalInfo& aContentPrincipal)
 diff --git a/dom/serviceworkers/ServiceWorkerScriptCache.cpp b/dom/serviceworkers/ServiceWorkerScriptCache.cpp
 --- a/dom/serviceworkers/ServiceWorkerScriptCache.cpp
 +++ b/dom/serviceworkers/ServiceWorkerScriptCache.cpp
@@ -18233,7 +18369,7 @@ diff --git a/dom/websocket/WebSocket.cpp b/dom/websocket/WebSocket.cpp
 diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
 --- a/dom/workers/RuntimeService.cpp
 +++ b/dom/workers/RuntimeService.cpp
-@@ -1405,17 +1405,17 @@ RuntimeService::RegisterWorker(WorkerPri
+@@ -1407,17 +1407,17 @@ RuntimeService::RegisterWorker(WorkerPri
             MOZ_CRASH("We should not instantiate a new SharedWorker!");
           }
        }
@@ -18334,7 +18470,7 @@ diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
 diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
 --- a/dom/workers/WorkerPrivate.cpp
 +++ b/dom/workers/WorkerPrivate.cpp
-@@ -3100,17 +3100,17 @@ WorkerPrivate::Constructor(JSContext* aC
+@@ -3080,17 +3080,17 @@ WorkerPrivate::Constructor(JSContext* aC
    // WorkerThreadPrimaryRunnable::Run for workers just before running worker
    // code), so this is never SpiderMonkey's builtin default locale.
    JS::UniqueChars defaultLocale = JS_GetDefaultLocale(aCx);
@@ -18353,7 +18489,7 @@ diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
  
    worker->EnableDebugger();
  
-@@ -3657,17 +3657,17 @@ WorkerPrivate::DispatchToMainThread(nsIR
+@@ -3637,17 +3637,17 @@ WorkerPrivate::DispatchToMainThread(nsIR
    nsCOMPtr<nsIRunnable> r = aRunnable;
    return DispatchToMainThread(r.forget(), aFlags);
  }
@@ -18372,7 +18508,7 @@ diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
    return mWorkerControlEventTarget;
  }
  
-@@ -3745,17 +3745,17 @@ WorkerPrivate::GetClientInfo() const
+@@ -3725,17 +3725,17 @@ WorkerPrivate::GetClientInfo() const
  
  const ClientState
  WorkerPrivate::GetClientState() const
@@ -18391,7 +18527,7 @@ diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
    AssertIsOnWorkerThread();
    MOZ_DIAGNOSTIC_ASSERT(mClientSource);
    return mClientSource->GetController();
-@@ -5454,17 +5454,17 @@ WorkerPrivate::GetOrCreateGlobalScope(JS
+@@ -5434,17 +5434,17 @@ WorkerPrivate::GetOrCreateGlobalScope(JS
  
      JS::Rooted<JSObject*> global(aCx);
      NS_ENSURE_TRUE(globalScope->WrapGlobalObject(aCx, &global), nullptr);
@@ -18410,7 +18546,7 @@ diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
  
      JS_FireOnNewGlobalObject(aCx, global);
    }
-@@ -5485,17 +5485,17 @@ WorkerPrivate::CreateDebuggerGlobalScope
+@@ -5465,17 +5465,17 @@ WorkerPrivate::CreateDebuggerGlobalScope
    JS::Rooted<JSObject*> global(aCx);
    NS_ENSURE_TRUE(globalScope->WrapGlobalObject(aCx, &global), nullptr);
  
@@ -18451,7 +18587,7 @@ diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h
    nsresult
    DispatchDebuggerRunnable(already_AddRefed<WorkerRunnable> aDebuggerRunnable);
  
-@@ -1062,17 +1062,17 @@ public:
+@@ -1059,17 +1059,17 @@ public:
    }
  
    JS::UniqueChars
@@ -40634,7 +40770,7 @@ diff --git a/layout/base/GeckoRestyleManager.cpp b/layout/base/GeckoRestyleManag
 diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
 --- a/layout/base/PresShell.cpp
 +++ b/layout/base/PresShell.cpp
-@@ -4172,17 +4172,17 @@ PresShell::DoFlushPendingNotifications(m
+@@ -4171,17 +4171,17 @@ PresShell::DoFlushPendingNotifications(m
          mPresContext->EffectCompositor()->PostRestyleForThrottledAnimations();
        }
  
@@ -40653,7 +40789,7 @@ diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
      }
  
      // Process whatever XBL constructors those restyles queued up.  This
-@@ -4198,17 +4198,17 @@ PresShell::DoFlushPendingNotifications(m
+@@ -4197,17 +4197,17 @@ PresShell::DoFlushPendingNotifications(m
      // date.  If it's not, then style context reparenting, which can
      // happen during reflow, might suddenly pick up the new rules and
      // we'll end up with frames whose style doesn't match the frame
@@ -40672,7 +40808,7 @@ diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
  
      didStyleFlush = true;
  
-@@ -4218,17 +4218,17 @@ PresShell::DoFlushPendingNotifications(m
+@@ -4217,17 +4217,17 @@ PresShell::DoFlushPendingNotifications(m
      // be good.
  
      if (flushType >= (SuppressInterruptibleReflows()
@@ -40691,7 +40827,7 @@ diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
        if (ProcessReflowCommands(flushType < FlushType::Layout) &&
            mContentToScrollTo) {
          // We didn't get interrupted.  Go ahead and scroll to our content
-@@ -5140,17 +5140,17 @@ PresShell::RenderNode(nsIDOMNode* aNode,
+@@ -5139,17 +5139,17 @@ PresShell::RenderNode(nsIDOMNode* aNode,
    if (!node->IsInUncomposedDoc())
      return nullptr;
  
@@ -40710,7 +40846,7 @@ diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
      nsIntRect rrectPixels = aRegion->GetBounds();
  
      nsRect rrect = ToAppUnits(rrectPixels, nsPresContext::AppUnitsPerCSSPixel());
-@@ -5188,17 +5188,17 @@ PresShell::RenderSelection(nsISelection*
+@@ -5187,17 +5187,17 @@ PresShell::RenderSelection(nsISelection*
    NS_ASSERTION(numRanges > 0, "RenderSelection called with no selection");
  
    for (int32_t r = 0; r < numRanges; r++)
@@ -40729,7 +40865,7 @@ diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
                               aScreenRect, aFlags);
  }
  
-@@ -5532,17 +5532,17 @@ void PresShell::SynthesizeMouseMove(bool
+@@ -5531,17 +5531,17 @@ void PresShell::SynthesizeMouseMove(bool
          new nsSynthMouseMoveEvent(this, aFromScroll);
  
      if (!GetPresContext()->RefreshDriver()
@@ -40748,7 +40884,7 @@ diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
   * view tree that contains the point. Thus more deeply nested floating views
   * are preferred over their ancestors, and floating views earlier in the
   * view hierarchy (i.e., added later) are preferred over their siblings.
-@@ -6085,17 +6085,17 @@ PresShell::ScheduleApproximateFrameVisib
+@@ -6084,17 +6084,17 @@ PresShell::ScheduleApproximateFrameVisib
    RefPtr<nsRunnableMethod<PresShell>> event =
      NewRunnableMethod("PresShell::UpdateApproximateFrameVisibility",
                        this,
@@ -40767,7 +40903,7 @@ diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
  {
    if (!aFrame->TrackingVisibility()) {
      return;
-@@ -6269,17 +6269,17 @@ PresShell::Paint(nsView*         aViewTo
+@@ -6268,17 +6268,17 @@ PresShell::Paint(nsView*         aViewTo
        bool computeInvalidRect = computeInvalidFunc ||
                                  (layerManager->GetBackendType() == LayersBackend::LAYERS_BASIC);
  
@@ -51915,7 +52051,7 @@ diff --git a/xpcom/base/CycleCollectedJSContext.cpp b/xpcom/base/CycleCollectedJ
 diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp
 --- a/xpcom/base/CycleCollectedJSRuntime.cpp
 +++ b/xpcom/base/CycleCollectedJSRuntime.cpp
-@@ -907,17 +907,17 @@ public:
+@@ -914,17 +914,17 @@ public:
      }
    }
  

+ 21 - 23
mozilla-release/patches/1480236-PARTIAL-notests-69a1.patch

@@ -2,13 +2,13 @@
 # User Olli Pettay <Olli.Pettay@helsinki.fi>
 # Date 1558686423 -10800
 # Node ID 574e6b299f2d8683fa071ddee27c32ebb61dbc80
-# Parent  cf6919e788e54e0cdd7105dec5b3a4a08fca9d82
+# Parent  0774f7f3a00adef4af01cdbe350eb3fdba540998
 Bug 1480236 - Implement queueMicrotask(), r=baku
 
 diff --git a/dom/base/nsIGlobalObject.cpp b/dom/base/nsIGlobalObject.cpp
 --- a/dom/base/nsIGlobalObject.cpp
 +++ b/dom/base/nsIGlobalObject.cpp
-@@ -1,22 +1,30 @@
+@@ -1,25 +1,32 @@
  /* -*- 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
@@ -16,8 +16,10 @@ diff --git a/dom/base/nsIGlobalObject.cpp b/dom/base/nsIGlobalObject.cpp
   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
  #include "nsIGlobalObject.h"
+-
 +#include "mozilla/CycleCollectedJSContext.h"
 +#include "mozilla/dom/FunctionBinding.h"
+ #include "mozilla/dom/ServiceWorker.h"
  #include "nsContentUtils.h"
  #include "nsThreadUtils.h"
  #include "nsHostObjectProtocolHandler.h"
@@ -29,6 +31,7 @@ diff --git a/dom/base/nsIGlobalObject.cpp b/dom/base/nsIGlobalObject.cpp
  using mozilla::Maybe;
 +using mozilla::MicroTaskRunnable;
  using mozilla::dom::ClientInfo;
+ using mozilla::dom::ServiceWorker;
  using mozilla::dom::ServiceWorkerDescriptor;
 +using mozilla::dom::VoidFunction;
  
@@ -39,7 +42,7 @@ diff --git a/dom/base/nsIGlobalObject.cpp b/dom/base/nsIGlobalObject.cpp
  
  nsIPrincipal*
  nsIGlobalObject::PrincipalOrNull()
-@@ -112,16 +120,42 @@ nsIGlobalObject::TraverseHostObjectURIs(
+@@ -115,16 +122,42 @@ nsIGlobalObject::TraverseHostObjectURIs(
      return;
    }
  
@@ -85,37 +88,32 @@ diff --git a/dom/base/nsIGlobalObject.cpp b/dom/base/nsIGlobalObject.cpp
 diff --git a/dom/base/nsIGlobalObject.h b/dom/base/nsIGlobalObject.h
 --- a/dom/base/nsIGlobalObject.h
 +++ b/dom/base/nsIGlobalObject.h
-@@ -18,16 +18,22 @@
- 
- #define NS_IGLOBALOBJECT_IID \
+@@ -20,16 +20,17 @@
  { 0x11afa8be, 0xd997, 0x4e07, \
  { 0xa6, 0xa3, 0x6f, 0x87, 0x2e, 0xc3, 0xee, 0x7f } }
  
  class nsCycleCollectionTraversalCallback;
  class nsIPrincipal;
  
-+namespace mozilla {
-+namespace dom {
+ namespace mozilla {
+ namespace dom {
 +class VoidFunction;
-+}  // namespace dom
-+}  // namespace mozilla
-+
+ class ServiceWorker;
+ } // namespace dom
+ } // namespace mozilla
+ 
  class nsIGlobalObject : public nsISupports,
                          public mozilla::dom::DispatcherTrait
  {
    nsTArray<nsCString> mHostObjectURIs;
-   bool mIsDying;
- 
- protected:
-   nsIGlobalObject()
-@@ -80,16 +86,18 @@ public:
-   virtual bool IsInSyncOperation() { return false; }
- 
-   virtual mozilla::Maybe<mozilla::dom::ClientInfo>
-   GetClientInfo() const;
- 
-   virtual mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>
-   GetController() const;
+@@ -101,16 +102,18 @@ public:
+   // not hold a strong reference to the ServiceWorker.
+   virtual void
+   AddServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker);
+ 
+   // This method must be called by the ServiceWorker before it is destroyed.
+   virtual void
+   RemoveServiceWorker(mozilla::dom::ServiceWorker* aServiceWorker);
  
 +  void QueueMicrotask(mozilla::dom::VoidFunction& aCallback);
 +

+ 730 - 0
mozilla-release/patches/1577934-70a1.patch

@@ -0,0 +1,730 @@
+# HG changeset patch
+# User Eric Rahm <erahm@mozilla.com>
+# Date 1567320446 0
+# Node ID e714dd56f2de11115529a26112a4013a4b2726af
+# Parent  b52c0c6ad6e2bf7bd7958726f6e8966d6f1ce964
+Bug 1577934 - Remove using namespace std from dom/media audio tests r=gerald
+
+Differential Revision: https://phabricator.services.mozilla.com/D44290
+
+diff --git a/dom/media/fake-cdm/cdm-test-decryptor.cpp b/dom/media/fake-cdm/cdm-test-decryptor.cpp
+--- a/dom/media/fake-cdm/cdm-test-decryptor.cpp
++++ b/dom/media/fake-cdm/cdm-test-decryptor.cpp
+@@ -15,39 +15,37 @@
+ #include <iterator>
+ #include <sstream>
+ #include <set>
+ #include <thread>
+ 
+ #include "mozilla/Assertions.h"
+ #include "mozilla/Attributes.h"
+ 
+-using namespace std;
+-
+ FakeDecryptor* FakeDecryptor::sInstance = nullptr;
+ 
+ class TestManager {
+  public:
+   TestManager() = default;
+ 
+   // Register a test with the test manager.
+-  void BeginTest(const string& aTestID) {
++  void BeginTest(const std::string& aTestID) {
+     std::lock_guard<std::mutex> lock(mMutex);
+     auto found = mTestIDs.find(aTestID);
+     if (found == mTestIDs.end()) {
+       mTestIDs.insert(aTestID);
+     } else {
+       Error("FAIL BeginTest test already existed: " + aTestID);
+     }
+   }
+ 
+   // Notify the test manager that the test is finished. If all tests are done,
+   // test manager will send "test-storage complete" to notify the parent that
+   // all tests are finished and also delete itself.
+-  void EndTest(const string& aTestID) {
++  void EndTest(const std::string& aTestID) {
+     bool isEmpty = false;
+     {
+       std::lock_guard<std::mutex> lock(mMutex);
+       auto found = mTestIDs.find(aTestID);
+       if (found != mTestIDs.end()) {
+         mTestIDs.erase(aTestID);
+         isEmpty = mTestIDs.empty();
+       } else {
+@@ -59,22 +57,22 @@ class TestManager {
+       Finish();
+       delete this;
+     }
+   }
+ 
+  private:
+   ~TestManager() = default;
+ 
+-  static void Error(const string& msg) { FakeDecryptor::Message(msg); }
++  static void Error(const std::string& msg) { FakeDecryptor::Message(msg); }
+ 
+   static void Finish() { FakeDecryptor::Message("test-storage complete"); }
+ 
+   std::mutex mMutex;
+-  set<string> mTestIDs;
++  std::set<std::string> mTestIDs;
+ };
+ 
+ FakeDecryptor::FakeDecryptor(cdm::Host_9* aHost) : mHost(aHost) {
+   MOZ_ASSERT(!sInstance);
+   sInstance = this;
+ }
+ 
+ void FakeDecryptor::Message(const std::string& aMessage) {
+@@ -86,248 +84,253 @@ void FakeDecryptor::Message(const std::s
+ }
+ 
+ std::vector<std::string> Tokenize(const std::string& aString) {
+   std::stringstream strstr(aString);
+   std::istream_iterator<std::string> it(strstr), end;
+   return std::vector<std::string>(it, end);
+ }
+ 
+-static const string TruncateRecordId = "truncate-record-id";
+-static const string TruncateRecordData = "I will soon be truncated";
++static const std::string TruncateRecordId = "truncate-record-id";
++static const std::string TruncateRecordData = "I will soon be truncated";
+ 
+ template <class Continuation>
+ class WriteRecordSuccessTask {
+  public:
+-  WriteRecordSuccessTask(string aId, Continuation aThen)
+-      : mId(aId), mThen(move(aThen)) {}
++  WriteRecordSuccessTask(std::string aId, Continuation aThen)
++      : mId(aId), mThen(std::move(aThen)) {}
+ 
+   void operator()() { ReadRecord(FakeDecryptor::sInstance->mHost, mId, mThen); }
+ 
+-  string mId;
++  std::string mId;
+   Continuation mThen;
+ };
+ 
+ class WriteRecordFailureTask {
+  public:
+-  explicit WriteRecordFailureTask(const string& aMessage,
++  explicit WriteRecordFailureTask(const std::string& aMessage,
+                                   TestManager* aTestManager = nullptr,
+-                                  const string& aTestID = "")
++                                  const std::string& aTestID = "")
+       : mMessage(aMessage), mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+   void operator()() {
+     FakeDecryptor::Message(mMessage);
+     if (mTestmanager) {
+       mTestmanager->EndTest(mTestID);
+     }
+   }
+ 
+  private:
+-  string mMessage;
++  std::string mMessage;
+   TestManager* const mTestmanager;
+-  const string mTestID;
++  const std::string mTestID;
+ };
+ 
+ class TestEmptyContinuation : public ReadContinuation {
+  public:
+-  TestEmptyContinuation(TestManager* aTestManager, const string& aTestID)
++  TestEmptyContinuation(TestManager* aTestManager, const std::string& aTestID)
+       : mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+   virtual void operator()(bool aSuccess, const uint8_t* aData,
+                           uint32_t aDataSize) override {
+     if (aDataSize) {
+       FakeDecryptor::Message(
+           "FAIL TestEmptyContinuation record was not truncated");
+     }
+     mTestmanager->EndTest(mTestID);
+   }
+ 
+  private:
+   TestManager* const mTestmanager;
+-  const string mTestID;
++  const std::string mTestID;
+ };
+ 
+ class TruncateContinuation : public ReadContinuation {
+  public:
+-  TruncateContinuation(const string& aID, TestManager* aTestManager,
+-                       const string& aTestID)
++  TruncateContinuation(const std::string& aID, TestManager* aTestManager,
++                       const std::string& aTestID)
+       : mID(aID), mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+   virtual void operator()(bool aSuccess, const uint8_t* aData,
+                           uint32_t aDataSize) override {
+-    if (string(reinterpret_cast<const char*>(aData), aDataSize) !=
++    if (std::string(reinterpret_cast<const char*>(aData), aDataSize) !=
+         TruncateRecordData) {
+       FakeDecryptor::Message(
+           "FAIL TruncateContinuation read data doesn't match written data");
+     }
+     auto cont = TestEmptyContinuation(mTestmanager, mTestID);
+     auto msg = "FAIL in TruncateContinuation write.";
+     WriteRecord(FakeDecryptor::sInstance->mHost, mID, nullptr, 0,
+                 WriteRecordSuccessTask<TestEmptyContinuation>(mID, cont),
+                 WriteRecordFailureTask(msg, mTestmanager, mTestID));
+   }
+ 
+  private:
+-  const string mID;
++  const std::string mID;
+   TestManager* const mTestmanager;
+-  const string mTestID;
++  const std::string mTestID;
+ };
+ 
+ class VerifyAndFinishContinuation : public ReadContinuation {
+  public:
+-  explicit VerifyAndFinishContinuation(string aValue, TestManager* aTestManager,
+-                                       const string& aTestID)
++  explicit VerifyAndFinishContinuation(std::string aValue,
++                                       TestManager* aTestManager,
++                                       const std::string& aTestID)
+       : mValue(aValue), mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+   virtual void operator()(bool aSuccess, const uint8_t* aData,
+                           uint32_t aDataSize) override {
+-    if (string(reinterpret_cast<const char*>(aData), aDataSize) != mValue) {
++    if (std::string(reinterpret_cast<const char*>(aData), aDataSize) !=
++        mValue) {
+       FakeDecryptor::Message(
+           "FAIL VerifyAndFinishContinuation read data doesn't match expected "
+           "data");
+     }
+     mTestmanager->EndTest(mTestID);
+   }
+ 
+  private:
+-  string mValue;
++  std::string mValue;
+   TestManager* const mTestmanager;
+-  const string mTestID;
++  const std::string mTestID;
+ };
+ 
+ class VerifyAndOverwriteContinuation : public ReadContinuation {
+  public:
+-  VerifyAndOverwriteContinuation(string aId, string aValue, string aOverwrite,
++  VerifyAndOverwriteContinuation(std::string aId, std::string aValue,
++                                 std::string aOverwrite,
+                                  TestManager* aTestManager,
+-                                 const string& aTestID)
++                                 const std::string& aTestID)
+       : mId(aId),
+         mValue(aValue),
+         mOverwrite(aOverwrite),
+         mTestmanager(aTestManager),
+         mTestID(aTestID) {}
+ 
+   virtual void operator()(bool aSuccess, const uint8_t* aData,
+                           uint32_t aDataSize) override {
+-    if (string(reinterpret_cast<const char*>(aData), aDataSize) != mValue) {
++    if (std::string(reinterpret_cast<const char*>(aData), aDataSize) !=
++        mValue) {
+       FakeDecryptor::Message(
+           "FAIL VerifyAndOverwriteContinuation read data doesn't match "
+           "expected data");
+     }
+     auto cont = VerifyAndFinishContinuation(mOverwrite, mTestmanager, mTestID);
+     auto msg = "FAIL in VerifyAndOverwriteContinuation write.";
+     WriteRecord(FakeDecryptor::sInstance->mHost, mId, mOverwrite,
+                 WriteRecordSuccessTask<VerifyAndFinishContinuation>(mId, cont),
+                 WriteRecordFailureTask(msg, mTestmanager, mTestID));
+   }
+ 
+  private:
+-  string mId;
+-  string mValue;
+-  string mOverwrite;
++  std::string mId;
++  std::string mValue;
++  std::string mOverwrite;
+   TestManager* const mTestmanager;
+-  const string mTestID;
++  const std::string mTestID;
+ };
+ 
+-static const string OpenAgainRecordId = "open-again-record-id";
++static const std::string OpenAgainRecordId = "open-again-record-id";
+ 
+ class OpenedSecondTimeContinuation : public OpenContinuation {
+  public:
+   explicit OpenedSecondTimeContinuation(TestManager* aTestManager,
+-                                        const string& aTestID)
++                                        const std::string& aTestID)
+       : mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+   void operator()(bool aSuccess) override {
+     if (!aSuccess) {
+       FakeDecryptor::Message(
+           "FAIL OpenSecondTimeContinuation should not be able to re-open "
+           "record.");
+     }
+     // Succeeded, open should have failed.
+     mTestmanager->EndTest(mTestID);
+   }
+ 
+  private:
+   TestManager* const mTestmanager;
+-  const string mTestID;
++  const std::string mTestID;
+ };
+ 
+ class OpenedFirstTimeContinuation : public OpenContinuation {
+  public:
+-  OpenedFirstTimeContinuation(const string& aID, TestManager* aTestManager,
+-                              const string& aTestID)
++  OpenedFirstTimeContinuation(const std::string& aID, TestManager* aTestManager,
++                              const std::string& aTestID)
+       : mID(aID), mTestmanager(aTestManager), mTestID(aTestID) {}
+ 
+   void operator()(bool aSuccess) override {
+     if (!aSuccess) {
+       FakeDecryptor::Message(
+           "FAIL OpenAgainContinuation to open record initially.");
+       mTestmanager->EndTest(mTestID);
+       return;
+     }
+ 
+     auto cont = OpenedSecondTimeContinuation(mTestmanager, mTestID);
+     OpenRecord(FakeDecryptor::sInstance->mHost, mID, cont);
+   }
+ 
+  private:
+-  const string mID;
++  const std::string mID;
+   TestManager* const mTestmanager;
+-  const string mTestID;
++  const std::string mTestID;
+ };
+ 
+-static void DoTestStorage(const string& aPrefix, TestManager* aTestManager) {
++static void DoTestStorage(const std::string& aPrefix,
++                          TestManager* aTestManager) {
+   MOZ_ASSERT(FakeDecryptor::sInstance->mHost,
+              "FakeDecryptor::sInstance->mHost should not be null");
+   // Basic I/O tests. We run three cases concurrently. The tests, like
+   // CDMStorage run asynchronously. When they've all passed, we send
+   // a message back to the parent process, or a failure message if not.
+ 
+   // Test 1: Basic I/O test, and test that writing 0 bytes in a record
+   // deletes record.
+   //
+   // Write data to truncate record, then
+   // read data, verify that we read what we wrote, then
+   // write 0 bytes to truncate record, then
+   // read data, verify that 0 bytes was read
+-  const string id1 = aPrefix + TruncateRecordId;
+-  const string testID1 = aPrefix + "write-test-1";
++  const std::string id1 = aPrefix + TruncateRecordId;
++  const std::string testID1 = aPrefix + "write-test-1";
+   aTestManager->BeginTest(testID1);
+   auto cont1 = TruncateContinuation(id1, aTestManager, testID1);
+   auto msg1 = "FAIL in TestStorage writing TruncateRecord.";
+   WriteRecord(FakeDecryptor::sInstance->mHost, id1, TruncateRecordData,
+               WriteRecordSuccessTask<TruncateContinuation>(id1, cont1),
+               WriteRecordFailureTask(msg1, aTestManager, testID1));
+ 
+   // Test 2: Test that overwriting a record with a shorter record truncates
+   // the record to the shorter record.
+   //
+   // Write record, then
+   // read and verify record, then
+   // write a shorter record to same record.
+   // read and verify
+-  string id2 = aPrefix + "record1";
+-  string record1 = "This is the first write to a record.";
+-  string overwrite = "A shorter record";
+-  const string testID2 = aPrefix + "write-test-2";
++  std::string id2 = aPrefix + "record1";
++  std::string record1 = "This is the first write to a record.";
++  std::string overwrite = "A shorter record";
++  const std::string testID2 = aPrefix + "write-test-2";
+   aTestManager->BeginTest(testID2);
+   auto task2 = VerifyAndOverwriteContinuation(id2, record1, overwrite,
+                                               aTestManager, testID2);
+   auto msg2 = "FAIL in TestStorage writing record1.";
+   WriteRecord(
+       FakeDecryptor::sInstance->mHost, id2, record1,
+       WriteRecordSuccessTask<VerifyAndOverwriteContinuation>(id2, task2),
+       WriteRecordFailureTask(msg2, aTestManager, testID2));
+ 
+   // Test 3: Test that opening a record while it's already open fails.
+   //
+   // Open record1, then
+   // open record1, should fail.
+   // close record1
+-  const string id3 = aPrefix + OpenAgainRecordId;
+-  const string testID3 = aPrefix + "open-test-1";
++  const std::string id3 = aPrefix + OpenAgainRecordId;
++  const std::string testID3 = aPrefix + "open-test-1";
+   aTestManager->BeginTest(testID3);
+   auto task3 = OpenedFirstTimeContinuation(id3, aTestManager, testID3);
+   OpenRecord(FakeDecryptor::sInstance->mHost, id3, task3);
+ }
+ 
+ void FakeDecryptor::TestStorage() {
+   auto* testManager = new TestManager();
+   // Main thread tests.
+@@ -335,93 +338,93 @@ void FakeDecryptor::TestStorage() {
+   DoTestStorage("mt2-", testManager);
+ 
+   // Note: Once all tests finish, TestManager will dispatch "test-pass" message,
+   // which ends the test for the parent.
+ }
+ 
+ class ReportWritten {
+  public:
+-  ReportWritten(const string& aRecordId, const string& aValue)
++  ReportWritten(const std::string& aRecordId, const std::string& aValue)
+       : mRecordId(aRecordId), mValue(aValue) {}
+   void operator()() {
+     FakeDecryptor::Message("stored " + mRecordId + " " + mValue);
+   }
+ 
+-  const string mRecordId;
+-  const string mValue;
++  const std::string mRecordId;
++  const std::string mValue;
+ };
+ 
+ class ReportReadStatusContinuation : public ReadContinuation {
+  public:
+-  explicit ReportReadStatusContinuation(const string& aRecordId)
++  explicit ReportReadStatusContinuation(const std::string& aRecordId)
+       : mRecordId(aRecordId) {}
+   void operator()(bool aSuccess, const uint8_t* aData,
+                   uint32_t aDataSize) override {
+     if (!aSuccess) {
+       FakeDecryptor::Message("retrieve " + mRecordId + " failed");
+     } else {
+-      stringstream ss;
++      std::stringstream ss;
+       ss << aDataSize;
+-      string len;
++      std::string len;
+       ss >> len;
+       FakeDecryptor::Message("retrieve " + mRecordId + " succeeded (length " +
+                              len + " bytes)");
+     }
+   }
+-  string mRecordId;
++  std::string mRecordId;
+ };
+ 
+ class ReportReadRecordContinuation : public ReadContinuation {
+  public:
+-  explicit ReportReadRecordContinuation(const string& aRecordId)
++  explicit ReportReadRecordContinuation(const std::string& aRecordId)
+       : mRecordId(aRecordId) {}
+   void operator()(bool aSuccess, const uint8_t* aData,
+                   uint32_t aDataSize) override {
+     if (!aSuccess) {
+       FakeDecryptor::Message("retrieved " + mRecordId + " failed");
+     } else {
+       FakeDecryptor::Message(
+           "retrieved " + mRecordId + " " +
+-          string(reinterpret_cast<const char*>(aData), aDataSize));
++          std::string(reinterpret_cast<const char*>(aData), aDataSize));
+     }
+   }
+-  string mRecordId;
++  std::string mRecordId;
+ };
+ 
+ enum ShutdownMode { ShutdownNormal, ShutdownTimeout, ShutdownStoreToken };
+ 
+ static ShutdownMode sShutdownMode = ShutdownNormal;
+-static string sShutdownToken;
++static std::string sShutdownToken;
+ 
+ void FakeDecryptor::UpdateSession(uint32_t aPromiseId, const char* aSessionId,
+                                   uint32_t aSessionIdLength,
+                                   const uint8_t* aResponse,
+                                   uint32_t aResponseSize) {
+   MOZ_ASSERT(FakeDecryptor::sInstance->mHost,
+              "FakeDecryptor::sInstance->mHost should not be null");
+   std::string response((const char*)aResponse,
+                        (const char*)(aResponse) + aResponseSize);
+   std::vector<std::string> tokens = Tokenize(response);
+-  const string& task = tokens[0];
++  const std::string& task = tokens[0];
+   if (task == "test-storage") {
+     TestStorage();
+   } else if (task == "store") {
+     // send "stored record" message on complete.
+-    const string& id = tokens[1];
+-    const string& value = tokens[2];
++    const std::string& id = tokens[1];
++    const std::string& value = tokens[2];
+     WriteRecord(FakeDecryptor::sInstance->mHost, id, value,
+                 ReportWritten(id, value),
+                 WriteRecordFailureTask("FAIL in writing record."));
+   } else if (task == "retrieve") {
+-    const string& id = tokens[1];
++    const std::string& id = tokens[1];
+     ReadRecord(FakeDecryptor::sInstance->mHost, id,
+                ReportReadStatusContinuation(id));
+   } else if (task == "shutdown-mode") {
+-    const string& mode = tokens[1];
++    const std::string& mode = tokens[1];
+     if (mode == "timeout") {
+       sShutdownMode = ShutdownTimeout;
+     } else if (mode == "token") {
+       sShutdownMode = ShutdownStoreToken;
+       sShutdownToken = tokens[2];
+       Message("shutdown-token received " + sShutdownToken);
+     }
+   } else if (task == "retrieve-shutdown-token") {
+diff --git a/dom/media/fake-cdm/cdm-test-storage.cpp b/dom/media/fake-cdm/cdm-test-storage.cpp
+--- a/dom/media/fake-cdm/cdm-test-storage.cpp
++++ b/dom/media/fake-cdm/cdm-test-storage.cpp
+@@ -5,22 +5,21 @@
+ 
+ #include "cdm-test-storage.h"
+ #include <vector>
+ 
+ #include "mozilla/Assertions.h"
+ #include "mozilla/Attributes.h"
+ 
+ using namespace cdm;
+-using namespace std;
+ 
+ class WriteRecordClient : public FileIOClient {
+  public:
+-  WriteRecordClient(function<void()>&& aOnSuccess,
+-                    function<void()>&& aOnFailure, const uint8_t* aData,
++  WriteRecordClient(std::function<void()>&& aOnSuccess,
++                    std::function<void()>&& aOnFailure, const uint8_t* aData,
+                     uint32_t aDataSize)
+       : mOnSuccess(move(aOnSuccess)), mOnFailure(move(aOnFailure)) {
+     mData.insert(mData.end(), aData, aData + aDataSize);
+   }
+ 
+   void OnOpenComplete(Status aStatus) override {
+     // If we hit an error, fail.
+     if (aStatus != Status::kSuccess) {
+@@ -30,17 +29,17 @@ class WriteRecordClient : public FileIOC
+     }
+   }
+ 
+   void OnReadComplete(Status aStatus, const uint8_t* aData,
+                       uint32_t aDataSize) override {}
+ 
+   void OnWriteComplete(Status aStatus) override { Done(aStatus); }
+ 
+-  void Do(const string& aName, Host_9* aHost) {
++  void Do(const std::string& aName, Host_9* aHost) {
+     // Initialize the FileIO.
+     mFileIO = aHost->CreateFileIO(this);
+     mFileIO->Open(aName.c_str(), aName.size());
+   }
+ 
+  private:
+   void Done(cdm::FileIOClient::Status aStatus) {
+     // Note: Call Close() before running continuation, in case the
+@@ -58,41 +57,42 @@ class WriteRecordClient : public FileIOC
+     } else {
+       mOnFailure();
+     }
+ 
+     delete this;
+   }
+ 
+   FileIO* mFileIO = nullptr;
+-  function<void()> mOnSuccess;
+-  function<void()> mOnFailure;
++  std::function<void()> mOnSuccess;
++  std::function<void()> mOnFailure;
+   std::vector<uint8_t> mData;
+ };
+ 
+ void WriteRecord(Host_9* aHost, const std::string& aRecordName,
+                  const uint8_t* aData, uint32_t aNumBytes,
+-                 function<void()>&& aOnSuccess, function<void()>&& aOnFailure) {
++                 std::function<void()>&& aOnSuccess,
++                 std::function<void()>&& aOnFailure) {
+   // client will be delete in WriteRecordClient::Done
+   WriteRecordClient* client = new WriteRecordClient(
+       move(aOnSuccess), move(aOnFailure), aData, aNumBytes);
+   client->Do(aRecordName, aHost);
+ }
+ 
+ void WriteRecord(Host_9* aHost, const std::string& aRecordName,
+-                 const std::string& aData, function<void()>&& aOnSuccess,
+-                 function<void()>&& aOnFailure) {
++                 const std::string& aData, std::function<void()>&& aOnSuccess,
++                 std::function<void()>&& aOnFailure) {
+   return WriteRecord(aHost, aRecordName, (const uint8_t*)aData.c_str(),
+                      aData.size(), move(aOnSuccess), move(aOnFailure));
+ }
+ 
+ class ReadRecordClient : public FileIOClient {
+  public:
+   explicit ReadRecordClient(
+-      function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete)
++      std::function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete)
+       : mOnReadComplete(move(aOnReadComplete)) {}
+ 
+   void OnOpenComplete(Status aStatus) override {
+     auto err = aStatus;
+     if (aStatus != Status::kSuccess) {
+       Done(err, reinterpret_cast<const uint8_t*>(""), 0);
+     } else {
+       mFileIO->Read();
+@@ -101,17 +101,17 @@ class ReadRecordClient : public FileIOCl
+ 
+   void OnReadComplete(Status aStatus, const uint8_t* aData,
+                       uint32_t aDataSize) override {
+     Done(aStatus, aData, aDataSize);
+   }
+ 
+   void OnWriteComplete(Status aStatus) override {}
+ 
+-  void Do(const string& aName, Host_9* aHost) {
++  void Do(const std::string& aName, Host_9* aHost) {
+     mFileIO = aHost->CreateFileIO(this);
+     mFileIO->Open(aName.c_str(), aName.size());
+   }
+ 
+  private:
+   void Done(cdm::FileIOClient::Status aStatus, const uint8_t* aData,
+             uint32_t aDataSize) {
+     // Note: Call Close() before running continuation, in case the
+@@ -129,40 +129,40 @@ class ReadRecordClient : public FileIOCl
+     } else {
+       mOnReadComplete(false, reinterpret_cast<const uint8_t*>(""), 0);
+     }
+ 
+     delete this;
+   }
+ 
+   FileIO* mFileIO = nullptr;
+-  function<void(bool, const uint8_t*, uint32_t)> mOnReadComplete;
++  std::function<void(bool, const uint8_t*, uint32_t)> mOnReadComplete;
+ };
+ 
+ void ReadRecord(
+     Host_9* aHost, const std::string& aRecordName,
+-    function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete) {
++    std::function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete) {
+   // client will be delete in ReadRecordClient::Done
+   ReadRecordClient* client = new ReadRecordClient(move(aOnReadComplete));
+   client->Do(aRecordName, aHost);
+ }
+ 
+ class OpenRecordClient : public FileIOClient {
+  public:
+-  explicit OpenRecordClient(function<void(bool)>&& aOpenComplete)
++  explicit OpenRecordClient(std::function<void(bool)>&& aOpenComplete)
+       : mOpenComplete(move(aOpenComplete)) {}
+ 
+   void OnOpenComplete(Status aStatus) override { Done(aStatus); }
+ 
+   void OnReadComplete(Status aStatus, const uint8_t* aData,
+                       uint32_t aDataSize) override {}
+ 
+   void OnWriteComplete(Status aStatus) override {}
+ 
+-  void Do(const string& aName, Host_9* aHost) {
++  void Do(const std::string& aName, Host_9* aHost) {
+     // Initialize the FileIO.
+     mFileIO = aHost->CreateFileIO(this);
+     mFileIO->Open(aName.c_str(), aName.size());
+   }
+ 
+  private:
+   void Done(cdm::FileIOClient::Status aStatus) {
+     // Note: Call Close() before running continuation, in case the
+@@ -180,18 +180,18 @@ class OpenRecordClient : public FileIOCl
+     } else {
+       mOpenComplete(false);
+     }
+ 
+     delete this;
+   }
+ 
+   FileIO* mFileIO = nullptr;
+-  function<void(bool)> mOpenComplete;
++  std::function<void(bool)> mOpenComplete;
+   ;
+ };
+ 
+ void OpenRecord(Host_9* aHost, const std::string& aRecordName,
+-                function<void(bool)>&& aOpenComplete) {
++                std::function<void(bool)>&& aOpenComplete) {
+   // client will be delete in OpenRecordClient::Done
+   OpenRecordClient* client = new OpenRecordClient(move(aOpenComplete));
+   client->Do(aRecordName, aHost);
+ }
+diff --git a/dom/media/gtest/TestGMPCrossOrigin.cpp b/dom/media/gtest/TestGMPCrossOrigin.cpp
+--- a/dom/media/gtest/TestGMPCrossOrigin.cpp
++++ b/dom/media/gtest/TestGMPCrossOrigin.cpp
+@@ -13,18 +13,16 @@
+ #include "GMPVideoEncoderProxy.h"
+ #include "GMPServiceParent.h"
+ #include "MediaPrefs.h"
+ #include "nsAppDirectoryServiceDefs.h"
+ #include "mozilla/Atomics.h"
+ #include "mozilla/DebugOnly.h"
+ #include "nsThreadUtils.h"
+ 
+-using namespace std;
+-
+ using namespace mozilla;
+ using namespace mozilla::gmp;
+ 
+ struct GMPTestRunner
+ {
+   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPTestRunner)
+ 
+   GMPTestRunner() { MediaPrefs::GetSingleton(); }
+diff --git a/dom/media/gtest/TestGMPUtils.cpp b/dom/media/gtest/TestGMPUtils.cpp
+--- a/dom/media/gtest/TestGMPUtils.cpp
++++ b/dom/media/gtest/TestGMPUtils.cpp
+@@ -7,17 +7,16 @@
+ #include "gtest/gtest.h"
+ #include "GMPUtils.h"
+ #include "nsString.h"
+ #include "MediaPrefs.h"
+ 
+ #include <string>
+ #include <vector>
+ 
+-using namespace std;
+ using namespace mozilla;
+ 
+ void TestSplitAt(const char* aInput,
+                  const char* aDelims,
+                  size_t aNumExpectedTokens,
+                  const char* aExpectedTokens[])
+ {
+   // Initialize media preferences.
+@@ -58,17 +57,17 @@ TEST(GeckoMediaPlugins, TestSplitAt) {
+     const char* tokens[] = { "line1", "line2", "line3", "line4" };
+     TestSplitAt(input, delims, MOZ_ARRAY_LENGTH(tokens), tokens);
+   }
+ }
+ 
+ TEST(GeckoMediaPlugins, ToHexString) {
+   struct Test {
+     nsTArray<uint8_t> bytes;
+-    string hex;
++    std::string hex;
+   };
+ 
+   static const Test tests[] = {
+     { {0x00, 0x00}, "0000" },
+     { {0xff, 0xff}, "ffff" },
+     { {0xff, 0x00}, "ff00" },
+     { {0x00, 0xff}, "00ff" },
+     { {0xf0, 0x10}, "f010" },

+ 1118 - 0
mozilla-release/patches/1757122-99a1.patch

@@ -0,0 +1,1118 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1646108126 0
+# Node ID 145ea24af3f1a54da30fd38e3828f6648b89f52f
+# Parent  bcaf12cff4db3d495fdfdc24c1ba67f21a26b782
+Bug 1757122 - Replace unqualified uses of std::move. r=xpcom-reviewers,media-playback-reviewers,mccr8,bryce
+
+Clang trunk added a warning about unqualified uses of std::move.
+https://reviews.llvm.org/D119670
+
+Differential Revision: https://phabricator.services.mozilla.com/D139681
+
+diff --git a/dom/media/MediaTrackGraph.cpp.1757122.later b/dom/media/MediaTrackGraph.cpp.1757122.later
+new file mode 100644
+--- /dev/null
++++ b/dom/media/MediaTrackGraph.cpp.1757122.later
+@@ -0,0 +1,430 @@
++--- MediaTrackGraph.cpp
+++++ MediaTrackGraph.cpp
++@@ -39,17 +39,16 @@
++ #include "Tracing.h"
++ #include "UnderrunHandler.h"
++ #include "mozilla/CycleCollectedJSRuntime.h"
++ #include "mozilla/Preferences.h"
++ 
++ #include "webaudio/blink/DenormalDisabler.h"
++ #include "webaudio/blink/HRTFDatabaseLoader.h"
++ 
++-using std::move;
++ using namespace mozilla::layers;
++ using namespace mozilla::dom;
++ using namespace mozilla::gfx;
++ using namespace mozilla::media;
++ 
++ namespace mozilla {
++ 
++ LazyLogModule gMediaTrackGraphLog("MediaTrackGraph");
++@@ -876,17 +875,17 @@ void MediaTrackGraphImpl::DeviceChanged(
++   MOZ_ASSERT(NS_IsMainThread());
++   mAudioOutputLatency = 0.0;
++ 
++   // Dispatch to the bg thread to do the (potentially expensive) query of the
++   // maximum channel count, and then dispatch back to the main thread, then to
++   // the graph, with the new info.
++   RefPtr<MediaTrackGraphImpl> self = this;
++   NS_DispatchBackgroundTask(NS_NewRunnableFunction(
++-      "MaxChannelCountUpdateOnBgThread", [self{move(self)}]() {
+++      "MaxChannelCountUpdateOnBgThread", [self{std::move(self)}]() {
++         uint32_t maxChannelCount = CubebUtils::MaxNumberOfChannels();
++         self->Dispatch(NS_NewRunnableFunction(
++             "MaxChannelCountUpdateToMainThread",
++             [self{self}, maxChannelCount]() {
++               class MessageToGraph : public ControlMessage {
++                public:
++                 explicit MessageToGraph(MediaTrackGraph* aGraph,
++                                         uint32_t aMaxChannelCount)
++@@ -1010,17 +1009,17 @@ void MediaTrackGraphImpl::PrepareUpdates
++       // tracks that are removed from the graph.
++       MOZ_ASSERT(!track || track->GraphImpl() == this);
++       if (!track || track->MainThreadNeedsUpdates()) {
++         // Discard this update as it has either been cleared when the track
++         // was destroyed or there will be a newer update below.
++         continue;
++       }
++       if (keptUpdateCount != i) {
++-        mTrackUpdates[keptUpdateCount] = move(mTrackUpdates[i]);
+++        mTrackUpdates[keptUpdateCount] = std::move(mTrackUpdates[i]);
++         MOZ_ASSERT(!mTrackUpdates[i].mTrack);
++       }
++       ++keptUpdateCount;
++     }
++     mTrackUpdates.TruncateLength(keptUpdateCount);
++ 
++     mTrackUpdates.SetCapacity(mTrackUpdates.Length() + mTracks.Length() +
++                               mSuspendedTracks.Length());
++@@ -1033,17 +1032,17 @@ void MediaTrackGraphImpl::PrepareUpdates
++       // No blocking to worry about here, since we've passed
++       // UpdateCurrentTimeForTracks.
++       update->mNextMainThreadCurrentTime =
++           track->GraphTimeToTrackTime(mProcessedTime);
++       update->mNextMainThreadEnded = track->mNotifiedEnded;
++     }
++     mNextMainThreadGraphTime = mProcessedTime;
++     if (!mPendingUpdateRunnables.IsEmpty()) {
++-      mUpdateRunnables.AppendElements(move(mPendingUpdateRunnables));
+++      mUpdateRunnables.AppendElements(std::move(mPendingUpdateRunnables));
++     }
++   }
++ 
++   // If this is the final update, then a stable state event will soon be
++   // posted just before this thread finishes, and so there is no need to also
++   // post here.
++   if (!aFinalUpdate &&
++       // Don't send the message to the main thread if it's not going to have
++@@ -1102,17 +1101,17 @@ void MediaTrackGraphImpl::RunMessageAfte
++   MOZ_ASSERT(OnGraphThread());
++ 
++   if (mFrontMessageQueue.IsEmpty()) {
++     mFrontMessageQueue.AppendElement();
++   }
++ 
++   // Only one block is used for messages from the graph thread.
++   MOZ_ASSERT(mFrontMessageQueue.Length() == 1);
++-  mFrontMessageQueue[0].mMessages.AppendElement(move(aMessage));
+++  mFrontMessageQueue[0].mMessages.AppendElement(std::move(aMessage));
++ }
++ 
++ void MediaTrackGraphImpl::RunMessagesInQueue() {
++   TRACE("MTG::RunMessagesInQueue");
++   MOZ_ASSERT(OnGraphThread());
++   // Calculate independent action times for each batch of messages (each
++   // batch corresponding to an event loop task). This isolates the performance
++   // of different scripts to some extent.
++@@ -1399,17 +1398,17 @@ auto MediaTrackGraphImpl::OneIterationIm
++       SwitchAtNextIteration(nullptr);
++     }
++     return IterationResult::CreateStop(
++         NewRunnableMethod("MediaTrackGraphImpl::SignalMainThreadCleanup", this,
++                           &MediaTrackGraphImpl::SignalMainThreadCleanup));
++   }
++ 
++   if (Switching()) {
++-    RefPtr<GraphDriver> nextDriver = move(mNextDriver);
+++    RefPtr<GraphDriver> nextDriver = std::move(mNextDriver);
++     return IterationResult::CreateSwitchDriver(
++         nextDriver, NewRunnableMethod<StoreRefPtrPassByPtr<GraphDriver>>(
++                         "MediaTrackGraphImpl::SetCurrentDriver", this,
++                         &MediaTrackGraphImpl::SetCurrentDriver, nextDriver));
++   }
++ 
++   return IterationResult::CreateStillProcessing();
++ }
++@@ -1763,17 +1762,18 @@ void MediaTrackGraphImpl::RunInStableSta
++     }
++ 
++     if (LifecycleStateRef() == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP &&
++         mForceShutDownReceived) {
++       // Defer calls to RunDuringShutdown() to happen while mMonitor is not
++       // held.
++       for (uint32_t i = 0; i < mBackMessageQueue.Length(); ++i) {
++         MessageBlock& mb = mBackMessageQueue[i];
++-        controlMessagesToRunDuringShutdown.AppendElements(move(mb.mMessages));
+++        controlMessagesToRunDuringShutdown.AppendElements(
+++            std::move(mb.mMessages));
++       }
++       mBackMessageQueue.Clear();
++       MOZ_ASSERT(mCurrentTaskMessageQueue.IsEmpty());
++       // Stop MediaTrackGraph threads.
++       LifecycleStateRef() = LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN;
++       nsCOMPtr<nsIRunnable> event = new MediaTrackGraphShutDownRunnable(this);
++       mMainThread->Dispatch(event.forget());
++     }
++@@ -1860,22 +1860,22 @@ void MediaTrackGraphImpl::AppendMessage(
++ #endif
++     if (IsEmpty() &&
++         LifecycleStateRef() >= LIFECYCLE_WAITING_FOR_TRACK_DESTRUCTION) {
++       Destroy();
++     }
++     return;
++   }
++ 
++-  mCurrentTaskMessageQueue.AppendElement(move(aMessage));
+++  mCurrentTaskMessageQueue.AppendElement(std::move(aMessage));
++   EnsureRunInStableState();
++ }
++ 
++ void MediaTrackGraphImpl::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable) {
++-  mMainThread->Dispatch(move(aRunnable));
+++  mMainThread->Dispatch(std::move(aRunnable));
++ }
++ 
++ MediaTrack::MediaTrack(TrackRate aSampleRate, MediaSegment::Type aType,
++                        MediaSegment* aSegment)
++     : mSampleRate(aSampleRate),
++       mType(aType),
++       mSegment(aSegment),
++       mStartTime(0),
++@@ -2168,17 +2168,17 @@ void MediaTrack::Resume() {
++     return;
++   }
++   GraphImpl()->AppendMessage(MakeUnique<Message>(this));
++ }
++ 
++ void MediaTrack::AddListenerImpl(
++     already_AddRefed<MediaTrackListener> aListener) {
++   RefPtr<MediaTrackListener> l(aListener);
++-  mTrackListeners.AppendElement(move(l));
+++  mTrackListeners.AppendElement(std::move(l));
++ 
++   PrincipalHandle lastPrincipalHandle = mSegment->GetLastPrincipalHandle();
++   mTrackListeners.LastElement()->NotifyPrincipalHandleChanged(
++       Graph(), lastPrincipalHandle);
++   if (mNotifiedEnded) {
++     mTrackListeners.LastElement()->NotifyEnded(Graph());
++   }
++   if (CombinedDisabledMode() == DisabledTrackMode::SILENCE_BLACK) {
++@@ -2235,17 +2235,17 @@ RefPtr<GenericPromise> MediaTrack::Remov
++   };
++ 
++   UniquePtr<Message> message = MakeUnique<Message>(this, aListener);
++   RefPtr<GenericPromise> p = message->mRemovedPromise.Ensure(__func__);
++   if (mMainThreadDestroyed) {
++     message->mRemovedPromise.Reject(NS_ERROR_FAILURE, __func__);
++     return p;
++   }
++-  GraphImpl()->AppendMessage(move(message));
+++  GraphImpl()->AppendMessage(std::move(message));
++   return p;
++ }
++ 
++ void MediaTrack::AddDirectListenerImpl(
++     already_AddRefed<DirectMediaTrackListener> aListener) {
++   // Base implementation, for tracks that don't support direct track listeners.
++   RefPtr<DirectMediaTrackListener> listener = aListener;
++   listener->NotifyDirectListenerInstalled(
++@@ -3295,34 +3295,34 @@ void MediaTrackGraphImpl::CollectSizesFo
++         already_AddRefed<nsISupports> aHandlerData)
++         : mozilla::Runnable("FinishCollectRunnable"),
++           mHandleReport(aHandleReport),
++           mHandlerData(aHandlerData) {}
++ 
++     NS_IMETHOD Run() override {
++       TRACE("MTG::FinishCollectReports ControlMessage");
++       MediaTrackGraphImpl::FinishCollectReports(mHandleReport, mHandlerData,
++-                                                move(mAudioTrackSizes));
+++                                                std::move(mAudioTrackSizes));
++       return NS_OK;
++     }
++ 
++     nsTArray<AudioNodeSizes> mAudioTrackSizes;
++ 
++    private:
++     ~FinishCollectRunnable() = default;
++ 
++     // Avoiding nsCOMPtr because NSCAP_ASSERT_NO_QUERY_NEEDED in its
++     // constructor modifies the ref-count, which cannot be done off main
++     // thread.
++     RefPtr<nsIHandleReportCallback> mHandleReport;
++     RefPtr<nsISupports> mHandlerData;
++   };
++ 
++-  RefPtr<FinishCollectRunnable> runnable =
++-      new FinishCollectRunnable(move(aHandleReport), move(aHandlerData));
+++  RefPtr<FinishCollectRunnable> runnable = new FinishCollectRunnable(
+++      std::move(aHandleReport), std::move(aHandlerData));
++ 
++   auto audioTrackSizes = &runnable->mAudioTrackSizes;
++ 
++   for (MediaTrack* t : AllTracks()) {
++     AudioNodeTrack* track = t->AsAudioNodeTrack();
++     if (track) {
++       AudioNodeSizes* usage = audioTrackSizes->AppendElement();
++       track->SizeOfAudioNodesIncludingThis(MallocSizeOf, *usage);
++@@ -3449,88 +3449,88 @@ void MediaTrackGraphImpl::RemoveTrack(Me
++   }
++ }
++ 
++ auto MediaTrackGraph::NotifyWhenDeviceStarted(MediaTrack* aTrack)
++     -> RefPtr<GraphStartedPromise> {
++   MOZ_ASSERT(NS_IsMainThread());
++   MozPromiseHolder<GraphStartedPromise> h;
++   RefPtr<GraphStartedPromise> p = h.Ensure(__func__);
++-  aTrack->GraphImpl()->NotifyWhenGraphStarted(aTrack, move(h));
+++  aTrack->GraphImpl()->NotifyWhenGraphStarted(aTrack, std::move(h));
++   return p;
++ }
++ 
++ void MediaTrackGraphImpl::NotifyWhenGraphStarted(
++     RefPtr<MediaTrack> aTrack,
++     MozPromiseHolder<GraphStartedPromise>&& aHolder) {
++   class GraphStartedNotificationControlMessage : public ControlMessage {
++     RefPtr<MediaTrack> mMediaTrack;
++     MozPromiseHolder<GraphStartedPromise> mHolder;
++ 
++    public:
++     GraphStartedNotificationControlMessage(
++         RefPtr<MediaTrack> aTrack,
++         MozPromiseHolder<GraphStartedPromise>&& aHolder)
++         : ControlMessage(nullptr),
++-          mMediaTrack(move(aTrack)),
++-          mHolder(move(aHolder)) {}
+++          mMediaTrack(std::move(aTrack)),
+++          mHolder(std::move(aHolder)) {}
++     void Run() override {
++       TRACE("MTG::GraphStartedNotificationControlMessage ControlMessage");
++       // This runs on the graph thread, so when this runs, and the current
++       // driver is an AudioCallbackDriver, we know the audio hardware is
++       // started. If not, we are going to switch soon, keep reposting this
++       // ControlMessage.
++       MediaTrackGraphImpl* graphImpl = mMediaTrack->GraphImpl();
++       if (graphImpl->CurrentDriver()->AsAudioCallbackDriver() &&
++           graphImpl->CurrentDriver()->ThreadRunning() &&
++           !graphImpl->CurrentDriver()->AsAudioCallbackDriver()->OnFallback()) {
++         // Avoid Resolve's locking on the graph thread by doing it on main.
++         graphImpl->Dispatch(NS_NewRunnableFunction(
++             "MediaTrackGraphImpl::NotifyWhenGraphStarted::Resolver",
++-            [holder = move(mHolder)]() mutable {
+++            [holder = std::move(mHolder)]() mutable {
++               holder.Resolve(true, __func__);
++             }));
++       } else {
++         graphImpl->DispatchToMainThreadStableState(
++             NewRunnableMethod<
++                 StoreCopyPassByRRef<RefPtr<MediaTrack>>,
++                 StoreCopyPassByRRef<MozPromiseHolder<GraphStartedPromise>>>(
++                 "MediaTrackGraphImpl::NotifyWhenGraphStarted", graphImpl,
++-                &MediaTrackGraphImpl::NotifyWhenGraphStarted, move(mMediaTrack),
++-                move(mHolder)));
+++                &MediaTrackGraphImpl::NotifyWhenGraphStarted,
+++                std::move(mMediaTrack), std::move(mHolder)));
++       }
++     }
++     void RunDuringShutdown() override {
++       mHolder.Reject(NS_ERROR_ILLEGAL_DURING_SHUTDOWN, __func__);
++     }
++   };
++ 
++   if (aTrack->IsDestroyed()) {
++     aHolder.Reject(NS_ERROR_NOT_AVAILABLE, __func__);
++     return;
++   }
++ 
++   MediaTrackGraphImpl* graph = aTrack->GraphImpl();
++   graph->AppendMessage(MakeUnique<GraphStartedNotificationControlMessage>(
++-      move(aTrack), move(aHolder)));
+++      std::move(aTrack), std::move(aHolder)));
++ }
++ 
++ class AudioContextOperationControlMessage : public ControlMessage {
++   using AudioContextOperationPromise =
++       MediaTrackGraph::AudioContextOperationPromise;
++ 
++  public:
++   AudioContextOperationControlMessage(
++       MediaTrack* aDestinationTrack, nsTArray<RefPtr<MediaTrack>> aTracks,
++       AudioContextOperation aOperation,
++       MozPromiseHolder<AudioContextOperationPromise>&& aHolder)
++       : ControlMessage(aDestinationTrack),
++-        mTracks(move(aTracks)),
+++        mTracks(std::move(aTracks)),
++         mAudioContextOperation(aOperation),
++-        mHolder(move(aHolder)) {}
+++        mHolder(std::move(aHolder)) {}
++   void Run() override {
++     TRACE_COMMENT("MTG::ApplyAudioContextOperationImpl ControlMessage",
++                   kAudioContextOptionsStrings[static_cast<uint8_t>(
++                       mAudioContextOperation)]);
++     mTrack->GraphImpl()->ApplyAudioContextOperationImpl(this);
++   }
++   void RunDuringShutdown() override {
++     MOZ_ASSERT(mAudioContextOperation == AudioContextOperation::Close,
++@@ -3573,52 +3573,52 @@ void MediaTrackGraphImpl::ApplyAudioCont
++   auto moveDest = mPendingResumeOperations.begin();
++   for (PendingResumeOperation& op : mPendingResumeOperations) {
++     if (op.DestinationTrack() == destinationTrack) {
++       op.Apply(this);
++       shrinking = true;
++       continue;
++     }
++     if (shrinking) {  // Fill-in gaps in the array.
++-      *moveDest = move(op);
+++      *moveDest = std::move(op);
++     }
++     ++moveDest;
++   }
++   mPendingResumeOperations.TruncateLength(moveDest -
++                                           mPendingResumeOperations.begin());
++ 
++   for (MediaTrack* track : aMessage->mTracks) {
++     track->IncrementSuspendCount();
++   }
++   // Resolve after main thread state is up to date with completed processing.
++   DispatchToMainThreadStableState(NS_NewRunnableFunction(
++       "MediaTrackGraphImpl::ApplyAudioContextOperationImpl",
++-      [holder = move(aMessage->mHolder), state]() mutable {
+++      [holder = std::move(aMessage->mHolder), state]() mutable {
++         holder.Resolve(state, __func__);
++       }));
++ }
++ 
++ MediaTrackGraphImpl::PendingResumeOperation::PendingResumeOperation(
++     AudioContextOperationControlMessage* aMessage)
++     : mDestinationTrack(aMessage->GetTrack()),
++-      mTracks(move(aMessage->mTracks)),
++-      mHolder(move(aMessage->mHolder)) {
+++      mTracks(std::move(aMessage->mTracks)),
+++      mHolder(std::move(aMessage->mHolder)) {
++   MOZ_ASSERT(aMessage->mAudioContextOperation == AudioContextOperation::Resume);
++ }
++ 
++ void MediaTrackGraphImpl::PendingResumeOperation::Apply(
++     MediaTrackGraphImpl* aGraph) {
++   MOZ_ASSERT(aGraph->OnGraphThread());
++   for (MediaTrack* track : mTracks) {
++     track->DecrementSuspendCount();
++   }
++   // The graph is provided through the parameter so that it is available even
++   // when the track is destroyed.
++   aGraph->DispatchToMainThreadStableState(NS_NewRunnableFunction(
++-      "PendingResumeOperation::Apply", [holder = move(mHolder)]() mutable {
+++      "PendingResumeOperation::Apply", [holder = std::move(mHolder)]() mutable {
++         holder.Resolve(AudioContextState::Running, __func__);
++       }));
++ }
++ 
++ void MediaTrackGraphImpl::PendingResumeOperation::Abort() {
++   // The graph is shutting down before the operation completed.
++ #ifdef DEBUG
++   {
++@@ -3633,17 +3633,17 @@ void MediaTrackGraphImpl::PendingResumeO
++ 
++ auto MediaTrackGraph::ApplyAudioContextOperation(
++     MediaTrack* aDestinationTrack, nsTArray<RefPtr<MediaTrack>> aTracks,
++     AudioContextOperation aOperation) -> RefPtr<AudioContextOperationPromise> {
++   MozPromiseHolder<AudioContextOperationPromise> holder;
++   RefPtr<AudioContextOperationPromise> p = holder.Ensure(__func__);
++   MediaTrackGraphImpl* graphImpl = static_cast<MediaTrackGraphImpl*>(this);
++   graphImpl->AppendMessage(MakeUnique<AudioContextOperationControlMessage>(
++-      aDestinationTrack, move(aTracks), aOperation, move(holder)));
+++      aDestinationTrack, std::move(aTracks), aOperation, std::move(holder)));
++   return p;
++ }
++ 
++ uint32_t MediaTrackGraphImpl::AudioOutputChannelCount() const {
++   MOZ_ASSERT(OnGraphThread());
++   // The audio output channel count for a graph is the maximum of the output
++   // channel count of all the tracks that are in mAudioOutputs, or the max audio
++   // output channel count the machine can do, whichever is smaller.
++@@ -3829,17 +3829,17 @@ already_AddRefed<MediaInputPort> MediaTr
++   }
++   return nullptr;
++ }
++ 
++ void MediaTrackGraph::DispatchToMainThreadStableState(
++     already_AddRefed<nsIRunnable> aRunnable) {
++   AssertOnGraphThreadOrNotRunning();
++   static_cast<MediaTrackGraphImpl*>(this)
++-      ->mPendingUpdateRunnables.AppendElement(move(aRunnable));
+++      ->mPendingUpdateRunnables.AppendElement(std::move(aRunnable));
++ }
++ 
++ Watchable<mozilla::GraphTime>& MediaTrackGraphImpl::CurrentTime() {
++   MOZ_ASSERT(NS_IsMainThread());
++   return mMainThreadGraphTime;
++ }
++ 
++ GraphTime MediaTrackGraph::ProcessedTime() const {
+diff --git a/dom/media/fake-cdm/cdm-test-storage.cpp b/dom/media/fake-cdm/cdm-test-storage.cpp
+--- a/dom/media/fake-cdm/cdm-test-storage.cpp
++++ b/dom/media/fake-cdm/cdm-test-storage.cpp
+@@ -11,17 +11,17 @@
+ 
+ using namespace cdm;
+ 
+ class WriteRecordClient : public FileIOClient {
+  public:
+   WriteRecordClient(std::function<void()>&& aOnSuccess,
+                     std::function<void()>&& aOnFailure, const uint8_t* aData,
+                     uint32_t aDataSize)
+-      : mOnSuccess(move(aOnSuccess)), mOnFailure(move(aOnFailure)) {
++      : mOnSuccess(std::move(aOnSuccess)), mOnFailure(std::move(aOnFailure)) {
+     mData.insert(mData.end(), aData, aData + aDataSize);
+   }
+ 
+   void OnOpenComplete(Status aStatus) override {
+     // If we hit an error, fail.
+     if (aStatus != Status::kSuccess) {
+       Done(aStatus);
+     } else if (mFileIO) {  // Otherwise, write our data to the file.
+@@ -68,32 +68,33 @@ class WriteRecordClient : public FileIOC
+ };
+ 
+ void WriteRecord(Host_9* aHost, const std::string& aRecordName,
+                  const uint8_t* aData, uint32_t aNumBytes,
+                  std::function<void()>&& aOnSuccess,
+                  std::function<void()>&& aOnFailure) {
+   // client will be delete in WriteRecordClient::Done
+   WriteRecordClient* client = new WriteRecordClient(
+-      move(aOnSuccess), move(aOnFailure), aData, aNumBytes);
++      std::move(aOnSuccess), std::move(aOnFailure), aData, aNumBytes);
+   client->Do(aRecordName, aHost);
+ }
+ 
+ void WriteRecord(Host_9* aHost, const std::string& aRecordName,
+                  const std::string& aData, std::function<void()>&& aOnSuccess,
+                  std::function<void()>&& aOnFailure) {
+   return WriteRecord(aHost, aRecordName, (const uint8_t*)aData.c_str(),
+-                     aData.size(), move(aOnSuccess), move(aOnFailure));
++                     aData.size(), std::move(aOnSuccess),
++                     std::move(aOnFailure));
+ }
+ 
+ class ReadRecordClient : public FileIOClient {
+  public:
+   explicit ReadRecordClient(
+       std::function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete)
+-      : mOnReadComplete(move(aOnReadComplete)) {}
++      : mOnReadComplete(std::move(aOnReadComplete)) {}
+ 
+   void OnOpenComplete(Status aStatus) override {
+     auto err = aStatus;
+     if (aStatus != Status::kSuccess) {
+       Done(err, reinterpret_cast<const uint8_t*>(""), 0);
+     } else {
+       mFileIO->Read();
+     }
+@@ -136,24 +137,24 @@ class ReadRecordClient : public FileIOCl
+   FileIO* mFileIO = nullptr;
+   std::function<void(bool, const uint8_t*, uint32_t)> mOnReadComplete;
+ };
+ 
+ void ReadRecord(
+     Host_9* aHost, const std::string& aRecordName,
+     std::function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete) {
+   // client will be delete in ReadRecordClient::Done
+-  ReadRecordClient* client = new ReadRecordClient(move(aOnReadComplete));
++  ReadRecordClient* client = new ReadRecordClient(std::move(aOnReadComplete));
+   client->Do(aRecordName, aHost);
+ }
+ 
+ class OpenRecordClient : public FileIOClient {
+  public:
+   explicit OpenRecordClient(std::function<void(bool)>&& aOpenComplete)
+-      : mOpenComplete(move(aOpenComplete)) {}
++      : mOpenComplete(std::move(aOpenComplete)) {}
+ 
+   void OnOpenComplete(Status aStatus) override { Done(aStatus); }
+ 
+   void OnReadComplete(Status aStatus, const uint8_t* aData,
+                       uint32_t aDataSize) override {}
+ 
+   void OnWriteComplete(Status aStatus) override {}
+ 
+@@ -187,11 +188,11 @@ class OpenRecordClient : public FileIOCl
+   FileIO* mFileIO = nullptr;
+   std::function<void(bool)> mOpenComplete;
+   ;
+ };
+ 
+ void OpenRecord(Host_9* aHost, const std::string& aRecordName,
+                 std::function<void(bool)>&& aOpenComplete) {
+   // client will be delete in OpenRecordClient::Done
+-  OpenRecordClient* client = new OpenRecordClient(move(aOpenComplete));
++  OpenRecordClient* client = new OpenRecordClient(std::move(aOpenComplete));
+   client->Do(aRecordName, aHost);
+ }
+diff --git a/dom/media/webaudio/AudioContext.cpp.1757122.later b/dom/media/webaudio/AudioContext.cpp.1757122.later
+new file mode 100644
+--- /dev/null
++++ b/dom/media/webaudio/AudioContext.cpp.1757122.later
+@@ -0,0 +1,137 @@
++--- AudioContext.cpp
+++++ AudioContext.cpp
++@@ -84,18 +84,16 @@
++ #include "WaveShaperNode.h"
++ #include "Tracing.h"
++ 
++ extern mozilla::LazyLogModule gAutoplayPermissionLog;
++ 
++ #define AUTOPLAY_LOG(msg, ...) \
++   MOZ_LOG(gAutoplayPermissionLog, LogLevel::Debug, (msg, ##__VA_ARGS__))
++ 
++-using std::move;
++-
++ namespace mozilla::dom {
++ 
++ // 0 is a special value that MediaTracks use to denote they are not part of a
++ // AudioContext.
++ static dom::AudioContext::AudioContextId gAudioContextId = 1;
++ 
++ NS_IMPL_CYCLE_COLLECTION_CLASS(AudioContext)
++ 
++@@ -676,17 +674,17 @@ already_AddRefed<Promise> AudioContext::
++   }
++   if (aSuccessCallback.WasPassed()) {
++     successCallback = &aSuccessCallback.Value();
++   }
++   UniquePtr<WebAudioDecodeJob> job(
++       new WebAudioDecodeJob(this, promise, successCallback, failureCallback));
++   AsyncDecodeWebAudio(contentType.get(), data, length, *job);
++   // Transfer the ownership to mDecodeJobs
++-  mDecodeJobs.AppendElement(move(job));
+++  mDecodeJobs.AppendElement(std::move(job));
++ 
++   return promise.forget();
++ }
++ 
++ void AudioContext::RemoveFromDecodeQueue(WebAudioDecodeJob* aDecodeJob) {
++   // Since UniquePtr doesn't provide an operator== which allows you to compare
++   // against raw pointers, we need to iterate manually.
++   for (uint32_t i = 0; i < mDecodeJobs.Length(); ++i) {
++@@ -847,17 +845,17 @@ class OnStateChangeTask final : public R
++ 
++ void AudioContext::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable) {
++   MOZ_ASSERT(NS_IsMainThread());
++   nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject());
++   // It can happen that this runnable took a long time to reach the main thread,
++   // and the global is not valid anymore.
++   if (parentObject) {
++     parentObject->AbstractMainThreadFor(TaskCategory::Other)
++-        ->Dispatch(move(aRunnable));
+++        ->Dispatch(std::move(aRunnable));
++   } else {
++     RefPtr<nsIRunnable> runnable(aRunnable);
++     runnable = nullptr;
++   }
++ }
++ 
++ void AudioContext::OnStateChanged(void* aPromise, AudioContextState aNewState) {
++   MOZ_ASSERT(NS_IsMainThread());
++@@ -1020,17 +1018,17 @@ void AudioContext::SuspendInternal(void*
++   // If mSuspendCalled is true then we already suspended all our tracks,
++   // so don't suspend them again (since suspend(); suspend(); resume(); should
++   // cancel both suspends). But we still need to do ApplyAudioContextOperation
++   // to ensure our new promise is resolved.
++   if (!mSuspendCalled) {
++     tracks = GetAllTracks();
++   }
++   auto promise = Graph()->ApplyAudioContextOperation(
++-      DestinationTrack(), move(tracks), AudioContextOperation::Suspend);
+++      DestinationTrack(), std::move(tracks), AudioContextOperation::Suspend);
++   if ((aFlags & AudioContextOperationFlags::SendStateChange)) {
++     promise->Then(
++         GetMainThread(), "AudioContext::OnStateChanged",
++         [self = RefPtr<AudioContext>(this),
++          aPromise](AudioContextState aNewState) {
++           self->OnStateChanged(aPromise, aNewState);
++         },
++         [] { MOZ_CRASH("Unexpected rejection"); });
++@@ -1095,17 +1093,17 @@ void AudioContext::ResumeInternal(AudioC
++   // If mSuspendCalled is false then we already resumed all our tracks,
++   // so don't resume them again (since suspend(); resume(); resume(); should
++   // be OK). But we still need to do ApplyAudioContextOperation
++   // to ensure our new promise is resolved.
++   if (mSuspendCalled) {
++     tracks = GetAllTracks();
++   }
++   auto promise = Graph()->ApplyAudioContextOperation(
++-      DestinationTrack(), move(tracks), AudioContextOperation::Resume);
+++      DestinationTrack(), std::move(tracks), AudioContextOperation::Resume);
++   if (aFlags & AudioContextOperationFlags::SendStateChange) {
++     promise->Then(
++         GetMainThread(), "AudioContext::OnStateChanged",
++         [self = RefPtr<AudioContext>(this)](AudioContextState aNewState) {
++           self->OnStateChanged(nullptr, aNewState);
++         },
++         [] {});  // Promise may be rejected after graph shutdown.
++   }
++@@ -1227,17 +1225,17 @@ void AudioContext::CloseInternal(void* a
++     nsTArray<RefPtr<mozilla::MediaTrack>> tracks;
++     // If mSuspendCalled or mCloseCalled are true then we already suspended
++     // all our tracks, so don't suspend them again. But we still need to do
++     // ApplyAudioContextOperation to ensure our new promise is resolved.
++     if (!mSuspendCalled && !mCloseCalled) {
++       tracks = GetAllTracks();
++     }
++     auto promise = Graph()->ApplyAudioContextOperation(
++-        ds, move(tracks), AudioContextOperation::Close);
+++        ds, std::move(tracks), AudioContextOperation::Close);
++     if ((aFlags & AudioContextOperationFlags::SendStateChange)) {
++       promise->Then(
++           GetMainThread(), "AudioContext::OnStateChanged",
++           [self = RefPtr<AudioContext>(this),
++            aPromise](AudioContextState aNewState) {
++             self->OnStateChanged(aPromise, aNewState);
++           },
++           [] {});  // Promise may be rejected after graph shutdown.
++@@ -1296,18 +1294,18 @@ void AudioContext::Unmute() const {
++   if (mDestination) {
++     mDestination->Unmute();
++   }
++ }
++ 
++ void AudioContext::SetParamMapForWorkletName(
++     const nsAString& aName, AudioParamDescriptorMap* aParamMap) {
++   MOZ_ASSERT(!mWorkletParamDescriptors.Contains(aName));
++-  Unused << mWorkletParamDescriptors.InsertOrUpdate(aName, move(*aParamMap),
++-                                                    fallible);
+++  Unused << mWorkletParamDescriptors.InsertOrUpdate(
+++      aName, std::move(*aParamMap), fallible);
++ }
++ 
++ size_t AudioContext::SizeOfIncludingThis(
++     mozilla::MallocSizeOf aMallocSizeOf) const {
++   // AudioNodes are tracked separately because we do not want the AudioContext
++   // to track all of the AudioNodes it creates, so we wouldn't be able to
++   // traverse them from here.
++ 
+diff --git a/media/gmp-clearkey/0.1/ClearKeyPersistence.cpp b/media/gmp-clearkey/0.1/ClearKeyPersistence.cpp
+--- a/media/gmp-clearkey/0.1/ClearKeyPersistence.cpp
++++ b/media/gmp-clearkey/0.1/ClearKeyPersistence.cpp
+@@ -59,17 +59,17 @@ ClearKeyPersistence::ReadAllRecordsFromI
+     [self, aOnComplete] ()
+   {
+     CK_LOGD("ClearKeyPersistence: Failed to load index file (it might not exist");
+     self->mPersistentKeyState = PersistentKeyState::LOADED;
+     aOnComplete();
+   };
+ 
+   string filename = "index";
+-  ReadData(mHost, filename, move(onIndexSuccess), move(onIndexFailed));
++  ReadData(mHost, filename, std::move(onIndexSuccess), std::move(onIndexFailed));
+ }
+ 
+ void
+ ClearKeyPersistence::WriteIndex() {
+   function <void()> onIndexSuccess =
+     [] ()
+   {
+     CK_LOGD("ClearKeyPersistence: Wrote index file");
+@@ -91,34 +91,34 @@ ClearKeyPersistence::WriteIndex() {
+   string dataString = ss.str();
+   uint8_t* dataArray = (uint8_t*)dataString.data();
+   vector<uint8_t> data(dataArray, dataArray + dataString.size());
+ 
+   string filename = "index";
+   WriteData(mHost,
+             filename,
+             data,
+-            move(onIndexSuccess),
+-            move(onIndexFail));
++            std::move(onIndexSuccess),
++            std::move(onIndexFail));
+ }
+ 
+ 
+ ClearKeyPersistence::ClearKeyPersistence(Host_9* aHost)
+ {
+   this->mHost = aHost;
+ }
+ 
+ void
+ ClearKeyPersistence::EnsureInitialized(bool aPersistentStateAllowed,
+                                        function<void()>&& aOnInitialized)
+ {
+   if (aPersistentStateAllowed &&
+       mPersistentKeyState == PersistentKeyState::UNINITIALIZED) {
+     mPersistentKeyState = LOADING;
+-    ReadAllRecordsFromIndex(move(aOnInitialized));
++    ReadAllRecordsFromIndex(std::move(aOnInitialized));
+   } else {
+     mPersistentKeyState = PersistentKeyState::LOADED;
+     aOnInitialized();
+   }
+ }
+ 
+ bool ClearKeyPersistence::IsLoaded() const
+ {
+diff --git a/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp b/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp
+--- a/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp
++++ b/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp
+@@ -62,17 +62,17 @@ ClearKeySessionManager::Init(bool aDisti
+       function<void()> func = self->mDeferredInitialize.front();
+       self->mDeferredInitialize.pop();
+ 
+       func();
+     }
+   };
+ 
+   mPersistence->EnsureInitialized(aPersistentStateAllowed,
+-                                  move(onPersistentStateLoaded));
++                                  std::move(onPersistentStateLoaded));
+ }
+ 
+ void
+ ClearKeySessionManager::CreateSession(uint32_t aPromiseId,
+                                       InitDataType aInitDataType,
+                                       const uint8_t* aInitData,
+                                       uint32_t aInitDataSize,
+                                       SessionType aSessionType)
+@@ -89,17 +89,17 @@ ClearKeySessionManager::CreateSession(ui
+     self->CreateSession(aPromiseId,
+                         aInitDataType,
+                         initData.data(),
+                         initData.size(),
+                         aSessionType);
+   };
+ 
+   // If we haven't loaded, don't do this yet
+-  if (MaybeDeferTillInitialized(move(deferrer))) {
++  if (MaybeDeferTillInitialized(std::move(deferrer))) {
+     CK_LOGD("Deferring CreateSession");
+     return;
+   }
+ 
+   CK_LOGARRAY("ClearKeySessionManager::CreateSession initdata: ",
+               aInitData,
+               aInitDataSize);
+ 
+@@ -195,17 +195,17 @@ ClearKeySessionManager::LoadSession(uint
+   // we try to use it.
+   RefPtr<ClearKeySessionManager> self(this);
+   function<void()> deferrer =
+     [self, aPromiseId, sessionId] ()
+   {
+     self->LoadSession(aPromiseId, sessionId.data(), sessionId.size());
+   };
+ 
+-  if (MaybeDeferTillInitialized(move(deferrer))) {
++  if (MaybeDeferTillInitialized(std::move(deferrer))) {
+     CK_LOGD("Deferring LoadSession");
+     return;
+   }
+ 
+   // If the SessionManager has been shutdown mHost will be null and we won't
+   // be able to resolve the promise.
+   if (!mHost) {
+     return;
+@@ -233,17 +233,17 @@ ClearKeySessionManager::LoadSession(uint
+   function<void()> failure = [self, aPromiseId] {
+     if (!self->mHost) {
+       return;
+     }
+     // As per the API described in ContentDecryptionModule_8
+     self->mHost->OnResolveNewSessionPromise(aPromiseId, nullptr, 0);
+   };
+ 
+-  ReadData(mHost, sessionId, move(success), move(failure));
++  ReadData(mHost, sessionId, std::move(success), std::move(failure));
+ }
+ 
+ void
+ ClearKeySessionManager::PersistentSessionDataLoaded(uint32_t aPromiseId,
+                                                     const string& aSessionId,
+                                                     const uint8_t* aKeyData,
+                                                     uint32_t aKeyDataSize)
+ {
+@@ -331,17 +331,17 @@ ClearKeySessionManager::UpdateSession(ui
+     self->UpdateSession(aPromiseId,
+                         sessionId.data(),
+                         sessionId.size(),
+                         response.data(),
+                         response.size());
+   };
+ 
+   // If we haven't fully loaded, defer calling this method
+-  if (MaybeDeferTillInitialized(move(deferrer))) {
++  if (MaybeDeferTillInitialized(std::move(deferrer))) {
+     CK_LOGD("Deferring LoadSession");
+     return;
+   }
+ 
+   // Make sure the SessionManager has not been shutdown before we try and
+   // resolve any promises.
+   if (!mHost) {
+     return;
+@@ -441,17 +441,17 @@ ClearKeySessionManager::UpdateSession(ui
+     static const char* message = "Couldn't store cenc key init data";
+     self->mHost->OnRejectPromise(aPromiseId,
+                                  Exception::kExceptionInvalidStateError,
+                                  0,
+                                  message,
+                                  strlen(message));
+   };
+ 
+-  WriteData(mHost, sessionId, keydata, move(resolve), move(reject));
++  WriteData(mHost, sessionId, keydata, std::move(resolve), std::move(reject));
+ }
+ 
+ void
+ ClearKeySessionManager::Serialize(const ClearKeySession* aSession,
+                                   std::vector<uint8_t>& aOutKeyData)
+ {
+   const std::vector<KeyId>& keyIds = aSession->GetKeyIds();
+   for (size_t i = 0; i < keyIds.size(); i++) {
+@@ -481,17 +481,17 @@ ClearKeySessionManager::CloseSession(uin
+   RefPtr<ClearKeySessionManager> self(this);
+   function<void()> deferrer =
+     [self, aPromiseId, sessionId] ()
+   {
+     self->CloseSession(aPromiseId, sessionId.data(), sessionId.size());
+   };
+ 
+   // If we haven't loaded, call this method later.
+-  if (MaybeDeferTillInitialized(move(deferrer))) {
++  if (MaybeDeferTillInitialized(std::move(deferrer))) {
+     CK_LOGD("Deferring CloseSession");
+     return;
+   }
+ 
+   // If DecryptingComplete has been called mHost will be null and we won't
+   // be able to resolve our promise.
+   if (!mHost) {
+     return;
+@@ -540,17 +540,17 @@ ClearKeySessionManager::RemoveSession(ui
+   RefPtr<ClearKeySessionManager> self(this);
+   function<void()> deferrer =
+     [self, aPromiseId, sessionId] ()
+   {
+     self->RemoveSession(aPromiseId, sessionId.data(), sessionId.size());
+   };
+ 
+   // If we haven't fully loaded, defer calling this method.
+-  if (MaybeDeferTillInitialized(move(deferrer))) {
++  if (MaybeDeferTillInitialized(std::move(deferrer))) {
+     CK_LOGD("Deferring RemoveSession");
+     return;
+   }
+ 
+   // Check that the SessionManager has not been shutdown before we try and
+   // resolve any promises.
+   if (!mHost) {
+     return;
+@@ -600,17 +600,17 @@ ClearKeySessionManager::RemoveSession(ui
+     static const char* message = "Could not remove session";
+     self->mHost->OnRejectPromise(aPromiseId,
+                                  Exception::kExceptionTypeError,
+                                  0,
+                                  message,
+                                  strlen(message));
+   };
+ 
+-  WriteData(mHost, sessionId, emptyKeydata, move(resolve), move(reject));
++  WriteData(mHost, sessionId, emptyKeydata, std::move(resolve), std::move(reject));
+ }
+ 
+ void
+ ClearKeySessionManager::SetServerCertificate(uint32_t aPromiseId,
+                                              const uint8_t* aServerCert,
+                                              uint32_t aServerCertSize)
+ {
+   // ClearKey CDM doesn't support this method by spec.
+@@ -669,11 +669,11 @@ ClearKeySessionManager::DecryptingComple
+ }
+ 
+ bool ClearKeySessionManager::MaybeDeferTillInitialized(function<void()>&& aMaybeDefer)
+ {
+   if (mPersistence->IsLoaded()) {
+     return false;
+   }
+ 
+-  mDeferredInitialize.emplace(move(aMaybeDefer));
++  mDeferredInitialize.emplace(std::move(aMaybeDefer));
+   return true;
+ }
+diff --git a/media/gmp-clearkey/0.1/ClearKeyStorage.cpp b/media/gmp-clearkey/0.1/ClearKeyStorage.cpp
+--- a/media/gmp-clearkey/0.1/ClearKeyStorage.cpp
++++ b/media/gmp-clearkey/0.1/ClearKeyStorage.cpp
+@@ -39,18 +39,18 @@ public:
+    */
+   static void Write(Host_9* aHost,
+                     string& aRecordName,
+                     const vector<uint8_t>& aData,
+                     function<void()>&& aOnSuccess,
+                     function<void()>&& aOnFailure)
+ {
+     WriteRecordClient* client = new WriteRecordClient(aData,
+-                                                      move(aOnSuccess),
+-                                                      move(aOnFailure));
++                                                      std::move(aOnSuccess),
++                                                      std::move(aOnFailure));
+     client->Do(aRecordName, aHost);
+   }
+ 
+   void OnOpenComplete(Status aStatus) override
+   {
+     // If we hit an error, fail.
+     if (aStatus != Status::kSuccess) {
+       Done(aStatus);
+@@ -73,18 +73,18 @@ public:
+     Done(aStatus);
+   }
+ 
+ private:
+   explicit WriteRecordClient(const vector<uint8_t>& aData,
+                              function<void()>&& aOnSuccess,
+                              function<void()>&& aOnFailure)
+     : mFileIO(nullptr)
+-    , mOnSuccess(move(aOnSuccess))
+-    , mOnFailure(move(aOnFailure))
++    , mOnSuccess(std::move(aOnSuccess))
++    , mOnFailure(std::move(aOnFailure))
+     , mData(aData) {}
+ 
+   void Do(const string& aName, Host_9* aHost)
+   {
+     // Initialize the FileIO.
+     mFileIO = aHost->CreateFileIO(this);
+     mFileIO->Open(aName.c_str(), aName.size());
+   }
+@@ -122,34 +122,34 @@ WriteData(Host_9* aHost,
+           string& aRecordName,
+           const vector<uint8_t>& aData,
+           function<void()>&& aOnSuccess,
+           function<void()>&& aOnFailure)
+ {
+   WriteRecordClient::Write(aHost,
+                            aRecordName,
+                            aData,
+-                           move(aOnSuccess),
+-                           move(aOnFailure));
++                           std::move(aOnSuccess),
++                           std::move(aOnFailure));
+ }
+ 
+ class ReadRecordClient : public FileIOClient
+ {
+ public:
+   /*
+    * This function will take the memory ownership of the parameters and
+    * delete them when done.
+    */
+   static void Read(Host_9* aHost,
+                    string& aRecordName,
+                    function<void(const uint8_t*, uint32_t)>&& aOnSuccess,
+                    function<void()>&& aOnFailure)
+   {
+ 
+-    (new ReadRecordClient(move(aOnSuccess), move(aOnFailure)))->
++    (new ReadRecordClient(std::move(aOnSuccess), std::move(aOnFailure)))->
+       Do(aRecordName, aHost);
+   }
+ 
+   void OnOpenComplete(Status aStatus) override
+   {
+     auto err = aStatus;
+     if (aStatus != Status::kSuccess) {
+       Done(err, nullptr, 0);
+@@ -170,18 +170,18 @@ public:
+     // We should never reach here, this client only ever reads data.
+     assert(false);
+   }
+ 
+ private:
+   explicit ReadRecordClient(function<void(const uint8_t*, uint32_t)>&& aOnSuccess,
+                             function<void()>&& aOnFailure)
+     : mFileIO(nullptr)
+-    , mOnSuccess(move(aOnSuccess))
+-    , mOnFailure(move(aOnFailure))
++    , mOnSuccess(std::move(aOnSuccess))
++    , mOnFailure(std::move(aOnFailure))
+   {}
+ 
+   void Do(const string& aName, Host_9* aHost)
+   {
+     mFileIO = aHost->CreateFileIO(this);
+     mFileIO->Open(aName.c_str(), aName.size());
+   }
+ 
+@@ -216,11 +216,11 @@ private:
+ void
+ ReadData(Host_9* mHost,
+          string& aRecordName,
+          function<void(const uint8_t*, uint32_t)>&& aOnSuccess,
+          function<void()>&& aOnFailure)
+ {
+   ReadRecordClient::Read(mHost,
+                          aRecordName,
+-                         move(aOnSuccess),
+-                         move(aOnFailure));
++                         std::move(aOnSuccess),
++                         std::move(aOnFailure));
+ }
+diff --git a/xpcom/tests/gtest/TestThrottledEventQueue.cpp.1757122.later b/xpcom/tests/gtest/TestThrottledEventQueue.cpp.1757122.later
+new file mode 100644
+--- /dev/null
++++ b/xpcom/tests/gtest/TestThrottledEventQueue.cpp.1757122.later
+@@ -0,0 +1,60 @@
++--- TestThrottledEventQueue.cpp
+++++ TestThrottledEventQueue.cpp
++@@ -25,17 +25,16 @@
++ #include "prinrval.h"
++ 
++ using mozilla::CondVar;
++ using mozilla::MakeRefPtr;
++ using mozilla::Mutex;
++ using mozilla::MutexAutoLock;
++ using mozilla::ThrottledEventQueue;
++ using std::function;
++-using std::move;
++ using std::string;
++ 
++ namespace TestThrottledEventQueue {
++ 
++ // A simple queue of runnables, to serve as the base target of
++ // ThrottledEventQueues in tests.
++ //
++ // This is much simpler than mozilla::TaskQueue, and so better for unit tests.
++@@ -44,17 +43,17 @@ namespace TestThrottledEventQueue {
++ struct RunnableQueue : nsISerialEventTarget {
++   std::queue<nsCOMPtr<nsIRunnable>> runnables;
++ 
++   bool IsEmpty() { return runnables.empty(); }
++   size_t Length() { return runnables.size(); }
++ 
++   [[nodiscard]] nsresult Run() {
++     while (!runnables.empty()) {
++-      auto runnable = move(runnables.front());
+++      auto runnable = std::move(runnables.front());
++       runnables.pop();
++       nsresult rv = runnable->Run();
++       if (NS_FAILED(rv)) return rv;
++     }
++ 
++     return NS_OK;
++   }
++ 
++@@ -92,18 +91,18 @@ struct RunnableQueue : nsISerialEventTar
++ 
++  private:
++   virtual ~RunnableQueue() = default;
++ };
++ 
++ NS_IMPL_ISUPPORTS(RunnableQueue, nsIEventTarget, nsISerialEventTarget)
++ 
++ static void Enqueue(nsIEventTarget* target, function<void()>&& aCallable) {
++-  nsresult rv =
++-      target->Dispatch(NS_NewRunnableFunction("TEQ GTest", move(aCallable)));
+++  nsresult rv = target->Dispatch(
+++      NS_NewRunnableFunction("TEQ GTest", std::move(aCallable)));
++   MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
++ }
++ 
++ }  // namespace TestThrottledEventQueue
++ 
++ using namespace TestThrottledEventQueue;
++ 
++ TEST(ThrottledEventQueue, RunnableQueue)

+ 31 - 0
mozilla-release/patches/1768999-102a1.patch

@@ -0,0 +1,31 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1652402724 0
+# Node ID bbb75aa6c4f2525fcf4e5d26218e9dc413ec12c1
+# Parent  399017403f1ab1231b86605557977d1cb9f2c1f5
+Bug 1768999 - Replace unqualified use of std::move in ChromiumCDMAdapter.cpp. r=media-playback-reviewers,padenot
+
+Differential Revision: https://phabricator.services.mozilla.com/D146153
+
+diff --git a/dom/media/gmp/ChromiumCDMAdapter.cpp b/dom/media/gmp/ChromiumCDMAdapter.cpp
+--- a/dom/media/gmp/ChromiumCDMAdapter.cpp
++++ b/dom/media/gmp/ChromiumCDMAdapter.cpp
+@@ -241,17 +241,17 @@ GetDosDeviceNames()
+   size_t l;
+   while (p < end && (l = wcsnlen_s(p, end - p)) > 0) {
+     // The string is of the form "C:\". We need to strip off the trailing
+     // backslash.
+     std::wstring drive = std::wstring(p, p + l);
+     if (drive.back() == '\\') {
+       drive.erase(drive.end() - 1);
+     }
+-    v.push_back(move(drive));
++    v.push_back(std::move(drive));
+     p += l + 1;
+   }
+   return v;
+ }
+ 
+ static std::wstring
+ GetDeviceMapping(const std::wstring& aDosDeviceName)
+ {

+ 100 - 0
mozilla-release/patches/870698-02-FIX-58a1.patch

@@ -0,0 +1,100 @@
+# HG changeset patch
+# User Chris Peterson <cpeterson@mozilla.com>
+# Date 1504502051 25200
+# Node ID c81b52d58ea4df9c46c0bf46a89e9f1dbb532fe5
+# Parent  fed5d9b7e12b3406d89f18a64b0878916fbe6f5e
+Bug 870698 - Part 2: Replace Append("") with AppendLiteral(""). r=erahm
+
+MozReview-Commit-ID: CrkIP4iHP1U
+
+diff --git a/dom/workers/test/gtest/TestReadWrite.cpp b/dom/workers/test/gtest/TestReadWrite.cpp
+--- a/dom/workers/test/gtest/TestReadWrite.cpp
++++ b/dom/workers/test/gtest/TestReadWrite.cpp
+@@ -647,44 +647,44 @@ TEST(ServiceWorkerRegistrar, TestVersion
+   ASSERT_EQ((int64_t)0, data[1].currentWorkerActivatedTime());
+   ASSERT_EQ((int64_t)0, data[1].lastUpdateTime());
+ }
+ 
+ TEST(ServiceWorkerRegistrar, TestVersion7Migration)
+ {
+   nsAutoCString buffer("7" "\n");
+ 
+-  buffer.Append("^appId=123&inBrowser=1\n");
++  buffer.AppendLiteral("^appId=123&inBrowser=1\n");
+   buffer.AppendLiteral("https://scope_0.org\ncurrentWorkerURL 0\n");
+-  buffer.Append(SERVICEWORKERREGISTRAR_TRUE "\n");
+-  buffer.Append("cacheName 0\n");
++  buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TRUE "\n");
++  buffer.AppendLiteral("cacheName 0\n");
+   buffer.AppendInt(nsIRequest::LOAD_NORMAL, 16);
+-  buffer.Append("\n");
++  buffer.AppendLiteral("\n");
+   buffer.AppendInt(0);
+-  buffer.Append("\n");
++  buffer.AppendLiteral("\n");
+   buffer.AppendInt(0);
+-  buffer.Append("\n");
++  buffer.AppendLiteral("\n");
+   buffer.AppendInt(0);
+-  buffer.Append("\n");
+-  buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
++  buffer.AppendLiteral("\n");
++  buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
+ 
+-  buffer.Append("\n");
++  buffer.AppendLiteral("\n");
+   buffer.AppendLiteral("https://scope_1.org\ncurrentWorkerURL 1\n");
+-  buffer.Append(SERVICEWORKERREGISTRAR_FALSE "\n");
+-  buffer.Append("cacheName 1\n");
++  buffer.AppendLiteral(SERVICEWORKERREGISTRAR_FALSE "\n");
++  buffer.AppendLiteral("cacheName 1\n");
+   buffer.AppendInt(nsIRequest::VALIDATE_ALWAYS, 16);
+-  buffer.Append("\n");
++  buffer.AppendLiteral("\n");
+   PRTime ts = PR_Now();
+   buffer.AppendInt(ts);
+-  buffer.Append("\n");
++  buffer.AppendLiteral("\n");
+   buffer.AppendInt(ts);
+-  buffer.Append("\n");
++  buffer.AppendLiteral("\n");
+   buffer.AppendInt(ts);
+-  buffer.Append("\n");
+-  buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
++  buffer.AppendLiteral("\n");
++  buffer.AppendLiteral(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
+ 
+   ASSERT_TRUE(CreateFile(buffer)) << "CreateFile should not fail";
+ 
+   RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest;
+ 
+   nsresult rv = swr->TestReadData();
+   ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail";
+ 
+diff --git a/netwerk/cookie/CookieServiceChild.cpp b/netwerk/cookie/CookieServiceChild.cpp
+--- a/netwerk/cookie/CookieServiceChild.cpp
++++ b/netwerk/cookie/CookieServiceChild.cpp
+@@ -311,21 +311,21 @@ CookieServiceChild::GetCookieStringFromC
+ 
+     // check if the cookie has expired
+     if (cookie->Expiry() <= currentTime) {
+       continue;
+     }
+ 
+     if (!cookie->Name().IsEmpty() || !cookie->Value().IsEmpty()) {
+       if (!aCookieString.IsEmpty()) {
+-        aCookieString.Append("; ");
++        aCookieString.AppendLiteral("; ");
+       }
+       if (!cookie->Name().IsEmpty()) {
+         aCookieString.Append(cookie->Name().get());
+-        aCookieString.Append("=");
++        aCookieString.AppendLiteral("=");
+         aCookieString.Append(cookie->Value().get());
+       } else {
+         aCookieString.Append(cookie->Value().get());
+       }
+     }
+   }
+ }
+ 

+ 26 - 0
mozilla-release/patches/series

@@ -92,6 +92,7 @@ NOBUG-20170803-promisehelper-57a1.patch
 1403084-58a1.patch
 1250832-58a1.patch
 1394559-58a1.patch
+870698-02-FIX-58a1.patch
 1304328-58a1.patch
 1403175-1-58a1.patch
 1403175-2-58a1.patch
@@ -710,6 +711,7 @@ NOBUG-20170803-promisehelper-57a1.patch
 1415472-59a1.patch
 1425704-59a1.patch
 1424336-59a1.patch
+1422316-59a1.patch
 1260598-59a1.patch
 1425318-1-59a1.patch
 1425318-2-59a1.patch
@@ -748,6 +750,7 @@ NOBUG-20170803-promisehelper-57a1.patch
 1426018-59a1.patch
 1419366-59a1.patch
 1421992-4c-59a1.patch
+1401359-59a1.patch
 1426108-59a1.patch
 1420289-0-59a1.patch
 1420289-1-59a1.patch
@@ -1383,6 +1386,9 @@ servo-19877-60a1.patch
 1430139-2-60a1.patch
 1430139-3-60a1.patch
 1430139-4-60a1.patch
+1431184-60a1.patch
+1433276-1-60a1.patch
+1433276-2-60a1.patch
 1395973-60a1.patch
 1433576-60a1.patch
 1412066-60a1.patch
@@ -1445,6 +1451,7 @@ servo-19881-60a1.patch
 1433837-4-60a1.patch
 1433597-60a1.patch
 1433568-60a1.patch
+1433914-60a1.patch
 1433497-60a1.patch
 1430817-1-60a1.patch
 1430817-2-60a1.patch
@@ -1607,6 +1614,19 @@ servo-19902-60a1.patch
 1432963-15-60a1.patch
 1432963-16-60a1.patch
 1432963-17-60a1.patch
+1433505-1-60a1.patch
+1433505-2-60a1.patch
+1433505-3-60a1.patch
+1433545-1-60a1.patch
+1433545-2-60a1.patch
+1434342-1-60a1.patch
+1434342-2-60a1.patch
+1434342-3-60a1.patch
+1434342-4-60a1.patch
+1434342-5-60a1.patch
+1434342-6-60a1.patch
+1434342-7-60a1.patch
+1434342-8-60a1.patch
 1434628-60a1.patch
 1433579-60a1.patch
 servo-19465-60a1.patch
@@ -1716,6 +1736,7 @@ servo-19529-60a1.patch
 1434686-4-60a1.patch
 1417380-1-60a1.patch
 1417380-2-60a1.patch
+1434934-60a1.patch
 1339461-1a-60a1.patch
 servo-19927-60a1.patch
 1434429-1-60a1.patch
@@ -1813,6 +1834,7 @@ NOBUG-20180206-jsgdb-60a1.patch
 1435293-60a1.patch
 1422036-60a1.patch
 1435174-60a1.patch
+1434599-60a1.patch
 1435673-1-60a1.patch
 1435673-2-60a1.patch
 1435673-3-60a1.patch
@@ -5094,6 +5116,7 @@ NOBUG-20180824-buildsetting-63a1.patch
 1497669-65a1.patch
 1506798-65a1.patch
 1502457-4-65a1.patch
+1204606-PARTIAL-fake-cdm-65a1.patch
 1468542-65a1.patch
 1501507-65a1.patch
 1408675-1-65a1.patch
@@ -5767,6 +5790,7 @@ NOBUG-removenonascii67a1-25314.patch
 1559975-16-69a1.patch
 1559975-17-69a1.patch
 1559975-18-69a1.patch
+1577934-70a1.patch
 1558372-70a1.patch
 1563085-70a1.patch
 1559975-19-70a1.patch
@@ -7147,6 +7171,7 @@ NOBUG-20210216-9b29bb9d-87a1.patch
 1753050-webp-98a1.patch
 1745860-98a1.patch
 1741873-99a1.patch
+1757122-99a1.patch
 1754724-1-99a1.patch
 1754724-2-99a1.patch
 1754724-3-99a1.patch
@@ -7205,6 +7230,7 @@ NOBUG-cleanbootstrap-25313.patch
 1772804-1-version-prebeta-mr-25314.patch
 1761764-102a1.patch
 1766848-102a1.patch
+1768999-102a1.patch
 1142667-102a1.patch
 1768568-102a1.patch
 1766085-102a1.patch