Bug 1508310 - Implement Report-to header support - part 4 - IPC to get endpoint from content process, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Sat, 01 Dec 2018 21:26:09 +0100
changeset 505578 ad2c155ce3518b4304161897a850620aa8912291
parent 505577 bbcbf470d213b8556c770f85a5cf3ffe216b2c13
child 505579 a00225dfc4146cbe04d03c28de49d4fed41cf04c
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1508310
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1508310 - Implement Report-to header support - part 4 - IPC to get endpoint from content process, r=smaug
dom/bindings/BindingUtils.cpp
dom/reporting/EndpointForReportChild.cpp
dom/reporting/EndpointForReportChild.h
dom/reporting/EndpointForReportParent.cpp
dom/reporting/EndpointForReportParent.h
dom/reporting/PEndpointForReport.ipdl
dom/reporting/ReportDeliver.cpp
dom/reporting/ReportDeliver.h
dom/reporting/ReportingHeader.cpp
dom/reporting/ReportingHeader.h
dom/reporting/ReportingUtils.cpp
dom/reporting/ReportingUtils.h
dom/reporting/moz.build
dom/security/featurepolicy/FeaturePolicyUtils.cpp
ipc/glue/BackgroundChildImpl.cpp
ipc/glue/BackgroundChildImpl.h
ipc/glue/BackgroundParentImpl.cpp
ipc/glue/BackgroundParentImpl.h
ipc/glue/PBackground.ipdl
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -3803,16 +3803,17 @@ void ReportDeprecation(nsPIDOMWindowInne
     return;
   }
 
   RefPtr<DeprecationReportBody> body =
       new DeprecationReportBody(aWindow, type, Nullable<Date>(), msg, aFileName,
                                 aLineNumber, aColumnNumber);
 
   ReportingUtils::Report(aWindow, nsGkAtoms::deprecation,
+                         NS_LITERAL_STRING("default"),
                          NS_ConvertUTF8toUTF16(spec), body);
 }
 
 void MaybeReportDeprecation(nsPIDOMWindowInner* aWindow,
                             nsIDocument::DeprecatedOperations aOperation,
                             const nsAString& aFileName,
                             const Nullable<uint32_t>& aLineNumber,
                             const Nullable<uint32_t>& aColumnNumber) {
new file mode 100644
--- /dev/null
+++ b/dom/reporting/EndpointForReportChild.cpp
@@ -0,0 +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
+ * 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/EndpointForReportChild.h"
+
+namespace mozilla {
+namespace dom {
+
+EndpointForReportChild::EndpointForReportChild() = default;
+
+EndpointForReportChild::~EndpointForReportChild() = default;
+
+void EndpointForReportChild::Initialize(
+    const ReportDeliver::ReportData& aData) {
+  mReportData = aData;
+}
+
+mozilla::ipc::IPCResult EndpointForReportChild::Recv__delete__(
+    const nsCString& aEndpointURL) {
+  if (!aEndpointURL.IsEmpty()) {
+    mReportData.mEndpointURL = aEndpointURL;
+    ReportDeliver::Fetch(mReportData);
+  }
+
+  return IPC_OK();
+}
+
+}  // namespace dom
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/reporting/EndpointForReportChild.h
@@ -0,0 +1,35 @@
+/* -*- 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_EndpointForReportChild_h
+#define mozilla_dom_EndpointForReportChild_h
+
+#include "mozilla/dom/ReportDeliver.h"
+#include "mozilla/dom/PEndpointForReportChild.h"
+
+namespace mozilla {
+namespace dom {
+
+class EndpointForReport;
+
+class EndpointForReportChild final : public PEndpointForReportChild {
+ public:
+  EndpointForReportChild();
+  ~EndpointForReportChild();
+
+  void Initialize(const ReportDeliver::ReportData& aReportData);
+
+  mozilla::ipc::IPCResult Recv__delete__(
+      const nsCString& aEndpointURL) override;
+
+ private:
+  ReportDeliver::ReportData mReportData;
+};
+
+}  // namespace dom
+}  // namespace mozilla
+
+#endif  // mozilla_dom_EndpointForReportChild_h
new file mode 100644
--- /dev/null
+++ b/dom/reporting/EndpointForReportParent.cpp
@@ -0,0 +1,44 @@
+/* -*- 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/EndpointForReportParent.h"
+#include "mozilla/dom/ReportingHeader.h"
+#include "mozilla/ipc/PBackgroundSharedTypes.h"
+#include "mozilla/Unused.h"
+#include "nsThreadUtils.h"
+
+namespace mozilla {
+namespace dom {
+
+EndpointForReportParent::EndpointForReportParent()
+    : mPBackgroundThread(NS_GetCurrentThread()), mActive(true) {}
+
+EndpointForReportParent::~EndpointForReportParent() = default;
+
+void EndpointForReportParent::ActorDestroy(ActorDestroyReason aWhy) {
+  mActive = false;
+}
+
+void EndpointForReportParent::Run(
+    const nsString& aGroupName,
+    const mozilla::ipc::PrincipalInfo& aPrincipalInfo) {
+  RefPtr<EndpointForReportParent> self = this;
+
+  NS_DispatchToMainThread(NS_NewRunnableFunction(
+      "EndpointForReportParent::Run", [self, aGroupName, aPrincipalInfo]() {
+        nsAutoCString uri;
+        ReportingHeader::GetEndpointForReport(aGroupName, aPrincipalInfo, uri);
+        self->mPBackgroundThread->Dispatch(NS_NewRunnableFunction(
+            "EndpointForReportParent::Answer", [self, uri]() {
+              if (self->mActive) {
+                Unused << self->Send__delete__(self, uri);
+              }
+            }));
+      }));
+}
+
+}  // namespace dom
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/reporting/EndpointForReportParent.h
@@ -0,0 +1,38 @@
+/* -*- 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_EndpointForReportParent_h
+#define mozilla_dom_EndpointForReportParent_h
+
+#include "mozilla/dom/PEndpointForReportParent.h"
+
+namespace mozilla {
+namespace dom {
+
+class EndpointForReport;
+
+class EndpointForReportParent final : public PEndpointForReportParent {
+ public:
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(EndpointForReportParent)
+
+  EndpointForReportParent();
+
+  void Run(const nsString& aGroupName,
+           const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
+
+ private:
+  ~EndpointForReportParent();
+
+  void ActorDestroy(ActorDestroyReason aWhy) override;
+
+  nsCOMPtr<nsIThread> mPBackgroundThread;
+  bool mActive;
+};
+
+}  // namespace dom
+}  // namespace mozilla
+
+#endif  // mozilla_dom_EndpointForReportParent_h
new file mode 100644
--- /dev/null
+++ b/dom/reporting/PEndpointForReport.ipdl
@@ -0,0 +1,19 @@
+/* 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 protocol PBackground;
+
+namespace mozilla {
+namespace dom {
+
+protocol PEndpointForReport
+{
+  manager PBackground;
+
+child:
+  async __delete__(nsCString endpointURL);
+};
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/reporting/ReportDeliver.cpp
@@ -0,0 +1,66 @@
+/* -*- 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/EndpointForReportChild.h"
+#include "mozilla/dom/ReportDeliver.h"
+#include "mozilla/ipc/BackgroundChild.h"
+#include "mozilla/ipc/PBackgroundChild.h"
+#include "mozilla/ipc/PBackgroundSharedTypes.h"
+#include "nsGlobalWindowInner.h"
+
+namespace mozilla {
+namespace dom {
+
+/* static */ void ReportDeliver::Record(nsPIDOMWindowInner* aWindow,
+                                        const nsAString& aType,
+                                        const nsAString& aGroupName,
+                                        const nsAString& aURL,
+                                        ReportBody* aBody) {
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aWindow);
+  MOZ_ASSERT(aBody);
+
+  nsAutoString reportBodyJSON;
+  aBody->ToJSON(reportBodyJSON);
+
+  nsCOMPtr<nsIPrincipal> principal =
+      nsGlobalWindowInner::Cast(aWindow)->GetPrincipal();
+  if (NS_WARN_IF(!principal)) {
+    return;
+  }
+
+  mozilla::ipc::PrincipalInfo principalInfo;
+  nsresult rv = PrincipalToPrincipalInfo(principal, &principalInfo);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return;
+  }
+
+  mozilla::ipc::PBackgroundChild* actorChild =
+      mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
+
+  PEndpointForReportChild* actor =
+      actorChild->SendPEndpointForReportConstructor(nsString(aGroupName),
+                                                    principalInfo);
+  if (NS_WARN_IF(!actor)) {
+    return;
+  }
+
+  ReportData data;
+  data.mType = aType;
+  data.mURL = aURL;
+  data.mReportBodyJSON = reportBodyJSON;
+  data.mPrincipal = principal;
+  data.mFailures = 0;
+
+  static_cast<EndpointForReportChild*>(actor)->Initialize(data);
+}
+
+/* static */ void ReportDeliver::Fetch(const ReportData& aReportData) {
+  // TODO
+}
+
+}  // namespace dom
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/reporting/ReportDeliver.h
@@ -0,0 +1,37 @@
+/* -*- 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_ReportDeliver_h
+#define mozilla_dom_ReportDeliver_h
+
+class nsIPrincipal;
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+namespace dom {
+
+class ReportDeliver final {
+ public:
+  struct ReportData {
+    nsString mType;
+    nsString mURL;
+    nsCString mEndpointURL;
+    nsString mReportBodyJSON;
+    nsCOMPtr<nsIPrincipal> mPrincipal;
+    uint32_t mFailures;
+  };
+
+  static void Record(nsPIDOMWindowInner* aWindow, const nsAString& aType,
+                     const nsAString& aGroupName, const nsAString& aURL,
+                     ReportBody* aBody);
+
+  static void Fetch(const ReportData& aReportData);
+};
+
+}  // namespace dom
+}  // namespace mozilla
+
+#endif  // mozilla_dom_ReportDeliver_h
--- a/dom/reporting/ReportingHeader.cpp
+++ b/dom/reporting/ReportingHeader.cpp
@@ -14,16 +14,17 @@
 #include "mozilla/Services.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/StaticPtr.h"
 #include "nsContentUtils.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpProtocolHandler.h"
 #include "nsIObserverService.h"
 #include "nsIPrincipal.h"
+#include "nsIRandomGenerator.h"
 #include "nsIScriptError.h"
 #include "nsNetUtil.h"
 #include "nsXULAppAPI.h"
 
 namespace mozilla {
 namespace dom {
 
 namespace {
@@ -406,16 +407,102 @@ bool ReportingHeader::IsSecureURI(nsIURI
   }
 
   rv = nsContentUtils::ReportToConsoleByWindowID(
       localizedMsg, nsIScriptError::infoFlag, NS_LITERAL_CSTRING("Reporting"),
       windowID, aURI);
   Unused << NS_WARN_IF(NS_FAILED(rv));
 }
 
+/* static */ void ReportingHeader::GetEndpointForReport(
+    const nsAString& aGroupName,
+    const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
+    nsACString& aEndpointURI) {
+  MOZ_ASSERT(aEndpointURI.IsEmpty());
+
+  if (!gReporting) {
+    return;
+  }
+
+  nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(aPrincipalInfo);
+  if (NS_WARN_IF(!principal)) {
+    return;
+  }
+
+  nsAutoCString origin;
+  nsresult rv = principal->GetOrigin(origin);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return;
+  }
+
+  Client* client = gReporting->mOrigins.Get(origin);
+  if (!client) {
+    return;
+  }
+
+  for (const Group& group : client->mGroups) {
+    if (group.mName == aGroupName) {
+      GetEndpointForReportInternal(group, aEndpointURI);
+      break;
+    }
+  }
+}
+
+/* static */ void ReportingHeader::GetEndpointForReportInternal(
+    const ReportingHeader::Group& aGroup, nsACString& aEndpointURI) {
+  TimeDuration diff = TimeStamp::Now() - aGroup.mCreationTime;
+  if (diff.ToSeconds() > aGroup.mTTL) {
+    // Expired.
+    return;
+  }
+
+  if (aGroup.mEndpoints.IsEmpty()) {
+    return;
+  }
+
+  int64_t minPriority = -1;
+  uint32_t totalWeight = 0;
+
+  for (const Endpoint& endpoint : aGroup.mEndpoints) {
+    if (minPriority == -1 || minPriority > endpoint.mPriority) {
+      minPriority = endpoint.mPriority;
+      totalWeight = endpoint.mWeight;
+    } else if (minPriority == endpoint.mPriority) {
+      totalWeight += endpoint.mWeight;
+    }
+  }
+
+  nsCOMPtr<nsIRandomGenerator> randomGenerator =
+      do_GetService("@mozilla.org/security/random-generator;1");
+  if (NS_WARN_IF(!randomGenerator)) {
+    return;
+  }
+
+  uint32_t randomNumber = 0;
+
+  uint8_t* buffer;
+  nsresult rv =
+      randomGenerator->GenerateRandomBytes(sizeof(randomNumber), &buffer);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return;
+  }
+
+  memcpy(&randomNumber, buffer, sizeof(randomNumber));
+  free(buffer);
+
+  totalWeight = randomNumber % totalWeight;
+
+  for (const Endpoint& endpoint : aGroup.mEndpoints) {
+    if (minPriority == endpoint.mPriority && totalWeight < endpoint.mWeight) {
+      Unused << NS_WARN_IF(NS_FAILED(endpoint.mUrl->GetSpec(aEndpointURI)));
+      break;
+    }
+  }
+}
+
 NS_INTERFACE_MAP_BEGIN(ReportingHeader)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(ReportingHeader)
 NS_IMPL_RELEASE(ReportingHeader)
 
--- a/dom/reporting/ReportingHeader.h
+++ b/dom/reporting/ReportingHeader.h
@@ -12,16 +12,21 @@
 #include "nsIObserver.h"
 #include "nsTArray.h"
 
 class nsIHttpChannel;
 class nsIPrincipal;
 class nsIURI;
 
 namespace mozilla {
+
+namespace ipc {
+class PrincipalInfo;
+}
+
 namespace dom {
 
 class ReportingHeader final : public nsIObserver {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   static void Initialize();
@@ -44,16 +49,21 @@ class ReportingHeader final : public nsI
 
   struct Client {
     nsTArray<Group> mGroups;
   };
 
   static UniquePtr<Client> ParseHeader(nsIHttpChannel* aChannel, nsIURI* aURI,
                                        const nsACString& aHeaderValue);
 
+  static void GetEndpointForReport(
+      const nsAString& aGroupName,
+      const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
+      nsACString& aEndpointURI);
+
  private:
   ReportingHeader();
   ~ReportingHeader();
 
   static void Shutdown();
 
   // Checks if a channel contains a Report-To header and parses its value.
   void ReportingFromChannel(nsIHttpChannel* aChannel);
@@ -81,15 +91,18 @@ class ReportingHeader final : public nsI
                                              nsIURI* aURI,
                                              const nsAString& aName,
                                              const nsAString& aURL);
 
   static void LogToConsoleInternal(nsIHttpChannel* aChannel, nsIURI* aURI,
                                    const char* aMsg,
                                    const nsTArray<nsString>& aParams);
 
+  static void GetEndpointForReportInternal(const ReportingHeader::Group& aGrup,
+                                           nsACString& aEndpointURI);
+
   nsClassHashtable<nsCStringHashKey, Client> mOrigins;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_ReportingHeader_h
--- a/dom/reporting/ReportingUtils.cpp
+++ b/dom/reporting/ReportingUtils.cpp
@@ -1,29 +1,40 @@
 /* -*- 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/ReportingUtils.h"
 #include "mozilla/dom/ReportBody.h"
+#include "mozilla/dom/ReportDeliver.h"
 #include "mozilla/dom/Report.h"
+#include "mozilla/ipc/BackgroundChild.h"
+#include "mozilla/ipc/BackgroundUtils.h"
+#include "mozilla/ipc/PBackgroundChild.h"
 #include "nsAtom.h"
 #include "nsPIDOMWindow.h"
 
 namespace mozilla {
 namespace dom {
 
 /* static */ void ReportingUtils::Report(nsPIDOMWindowInner* aWindow,
-                                         nsAtom* aType, const nsAString& aURL,
+                                         nsAtom* aType,
+                                         const nsAString& aGroupName,
+                                         const nsAString& aURL,
                                          ReportBody* aBody) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aWindow);
   MOZ_ASSERT(aBody);
 
-  RefPtr<mozilla::dom::Report> report = new mozilla::dom::Report(
-      aWindow, nsDependentAtomString(aType), aURL, aBody);
+  nsDependentAtomString type(aType);
+
+  RefPtr<mozilla::dom::Report> report =
+      new mozilla::dom::Report(aWindow, type, aURL, aBody);
   aWindow->BroadcastReport(report);
+
+  // Send the report to the server.
+  ReportDeliver::Record(aWindow, type, aGroupName, aURL, aBody);
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/reporting/ReportingUtils.h
+++ b/dom/reporting/ReportingUtils.h
@@ -14,15 +14,16 @@ class nsIPDOMWindowInner;
 namespace mozilla {
 namespace dom {
 
 class ReportBody;
 
 class ReportingUtils final {
  public:
   static void Report(nsPIDOMWindowInner* aWindow, nsAtom* aType,
-                     const nsAString& aURL, ReportBody* aBody);
+                     const nsAString& aGroupName, const nsAString& aURL,
+                     ReportBody* aBody);
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_ReportingUtils_h
--- a/dom/reporting/moz.build
+++ b/dom/reporting/moz.build
@@ -1,36 +1,46 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 EXPORTS.mozilla.dom = [
     'DeprecationReportBody.h',
+    'EndpointForReportChild.h',
+    'EndpointForReportParent.h',
     'FeaturePolicyViolationReportBody.h',
     'Report.h',
     'ReportBody.h',
+    'ReportDeliver.h',
     'ReportingHeader.h',
     'ReportingObserver.h',
     'ReportingUtils.h',
     'TestingDeprecatedInterface.h',
 ]
 
 UNIFIED_SOURCES += [
     'DeprecationReportBody.cpp',
+    'EndpointForReportChild.cpp',
+    'EndpointForReportParent.cpp',
     'FeaturePolicyViolationReportBody.cpp',
     'Report.cpp',
     'ReportBody.cpp',
+    'ReportDeliver.cpp',
     'ReportingHeader.cpp',
     'ReportingObserver.cpp',
     'ReportingUtils.cpp',
     'TestingDeprecatedInterface.cpp',
 ]
 
+IPDL_SOURCES += [
+    'PEndpointForReport.ipdl',
+]
+
 include('/ipc/chromium/chromium-config.mozbuild')
 
 with Files('**'):
     BUG_COMPONENT = ('DOM', 'Security')
 
 FINAL_LIBRARY = 'xul'
 
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
--- a/dom/security/featurepolicy/FeaturePolicyUtils.cpp
+++ b/dom/security/featurepolicy/FeaturePolicyUtils.cpp
@@ -144,13 +144,14 @@ FeaturePolicyUtils::DefaultAllowListFeat
   }
 
   RefPtr<FeaturePolicyViolationReportBody> body =
       new FeaturePolicyViolationReportBody(
           window, aFeatureName, NS_ConvertUTF8toUTF16(fileName), lineNumber,
           columnNumber, NS_LITERAL_STRING("enforce"));
 
   ReportingUtils::Report(window, nsGkAtoms::featurePolicyViolation,
+                         NS_LITERAL_STRING("default"),
                          NS_ConvertUTF8toUTF16(spec), body);
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/ipc/glue/BackgroundChildImpl.cpp
+++ b/ipc/glue/BackgroundChildImpl.cpp
@@ -17,16 +17,17 @@
 #include "mozilla/SchedulerGroup.h"
 #include "mozilla/dom/ClientManagerActors.h"
 #include "mozilla/dom/PBackgroundLSDatabaseChild.h"
 #include "mozilla/dom/PBackgroundLSObserverChild.h"
 #include "mozilla/dom/PBackgroundLSRequestChild.h"
 #include "mozilla/dom/PBackgroundLSSimpleRequestChild.h"
 #include "mozilla/dom/PBackgroundSDBConnectionChild.h"
 #include "mozilla/dom/PFileSystemRequestChild.h"
+#include "mozilla/dom/EndpointForReportChild.h"
 #include "mozilla/dom/FileSystemTaskBase.h"
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
 #include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
 #include "mozilla/dom/ipc/IPCBlobInputStreamChild.h"
 #include "mozilla/dom/ipc/PendingIPCBlobChild.h"
 #include "mozilla/dom/ipc/TemporaryIPCBlobChild.h"
@@ -767,16 +768,28 @@ bool BackgroundChildImpl::GetMessageSche
       }
     }
     return true;
   }
 
   return false;
 }
 
+dom::PEndpointForReportChild* BackgroundChildImpl::AllocPEndpointForReportChild(
+    const nsString& aGroupName, const PrincipalInfo& aPrincipalInfo) {
+  return new dom::EndpointForReportChild();
+}
+
+bool BackgroundChildImpl::DeallocPEndpointForReportChild(
+    PEndpointForReportChild* aActor) {
+  MOZ_ASSERT(aActor);
+  delete static_cast<dom::EndpointForReportChild*>(aActor);
+  return true;
+}
+
 }  // namespace ipc
 }  // namespace mozilla
 
 mozilla::ipc::IPCResult TestChild::Recv__delete__(const nsCString& aTestArg) {
   MOZ_RELEASE_ASSERT(aTestArg == mTestArg,
                      "BackgroundTest message was corrupted!");
 
   return IPC_OK();
--- a/ipc/glue/BackgroundChildImpl.h
+++ b/ipc/glue/BackgroundChildImpl.h
@@ -282,16 +282,22 @@ class BackgroundChildImpl : public PBack
   virtual bool DeallocPServiceWorkerContainerChild(
       PServiceWorkerContainerChild*) override;
 
   virtual PServiceWorkerRegistrationChild* AllocPServiceWorkerRegistrationChild(
       const IPCServiceWorkerRegistrationDescriptor&) override;
 
   virtual bool DeallocPServiceWorkerRegistrationChild(
       PServiceWorkerRegistrationChild*) override;
+
+  virtual PEndpointForReportChild* AllocPEndpointForReportChild(
+      const nsString& aGroupName, const PrincipalInfo& aPrincipalInfo) override;
+
+  virtual bool DeallocPEndpointForReportChild(
+      PEndpointForReportChild* aActor) override;
 };
 
 class BackgroundChildImpl::ThreadLocal final {
   friend class nsAutoPtr<ThreadLocal>;
 
  public:
   nsAutoPtr<mozilla::dom::indexedDB::ThreadLocal> mIndexedDBThreadLocal;
   mozilla::dom::IDBFileHandle* mCurrentFileHandle;
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -11,16 +11,17 @@
 #ifdef MOZ_WEBRTC
 #include "CamerasParent.h"
 #endif
 #include "mozilla/media/MediaParent.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/dom/ClientManagerActors.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/DOMTypes.h"
+#include "mozilla/dom/EndpointForReportParent.h"
 #include "mozilla/dom/FileSystemBase.h"
 #include "mozilla/dom/FileSystemRequestParent.h"
 #include "mozilla/dom/GamepadEventChannelParent.h"
 #include "mozilla/dom/GamepadTestChannelParent.h"
 #include "mozilla/dom/PGamepadEventChannelParent.h"
 #include "mozilla/dom/PGamepadTestChannelParent.h"
 #include "mozilla/dom/MessagePortParent.h"
 #include "mozilla/dom/ServiceWorkerActors.h"
@@ -1198,15 +1199,38 @@ bool BackgroundParentImpl::DeallocPServi
 mozilla::ipc::IPCResult
 BackgroundParentImpl::RecvPServiceWorkerRegistrationConstructor(
     PServiceWorkerRegistrationParent* aActor,
     const IPCServiceWorkerRegistrationDescriptor& aDescriptor) {
   dom::InitServiceWorkerRegistrationParent(aActor, aDescriptor);
   return IPC_OK();
 }
 
+dom::PEndpointForReportParent*
+BackgroundParentImpl::AllocPEndpointForReportParent(
+    const nsString& aGroupName, const PrincipalInfo& aPrincipalInfo) {
+  RefPtr<dom::EndpointForReportParent> actor =
+      new dom::EndpointForReportParent();
+  return actor.forget().take();
+}
+
+mozilla::ipc::IPCResult BackgroundParentImpl::RecvPEndpointForReportConstructor(
+    PEndpointForReportParent* aActor, const nsString& aGroupName,
+    const PrincipalInfo& aPrincipalInfo) {
+  static_cast<dom::EndpointForReportParent*>(aActor)->Run(aGroupName,
+                                                          aPrincipalInfo);
+  return IPC_OK();
+}
+
+bool BackgroundParentImpl::DeallocPEndpointForReportParent(
+    PEndpointForReportParent* aActor) {
+  RefPtr<dom::EndpointForReportParent> actor =
+      dont_AddRef(static_cast<dom::EndpointForReportParent*>(aActor));
+  return true;
+}
+
 }  // namespace ipc
 }  // namespace mozilla
 
 void TestParent::ActorDestroy(ActorDestroyReason aWhy) {
   mozilla::ipc::AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
 }
--- a/ipc/glue/BackgroundParentImpl.h
+++ b/ipc/glue/BackgroundParentImpl.h
@@ -352,14 +352,24 @@ class BackgroundParentImpl : public PBac
       const IPCServiceWorkerRegistrationDescriptor&) override;
 
   virtual bool DeallocPServiceWorkerRegistrationParent(
       PServiceWorkerRegistrationParent*) override;
 
   virtual mozilla::ipc::IPCResult RecvPServiceWorkerRegistrationConstructor(
       PServiceWorkerRegistrationParent* aActor,
       const IPCServiceWorkerRegistrationDescriptor& aDescriptor) override;
+
+  virtual PEndpointForReportParent* AllocPEndpointForReportParent(
+      const nsString& aGroupName, const PrincipalInfo& aPrincipalInfo) override;
+
+  virtual mozilla::ipc::IPCResult RecvPEndpointForReportConstructor(
+      PEndpointForReportParent* actor, const nsString& aGroupName,
+      const PrincipalInfo& aPrincipalInfo) override;
+
+  virtual bool DeallocPEndpointForReportParent(
+      PEndpointForReportParent* aActor) override;
 };
 
 }  // namespace ipc
 }  // namespace mozilla
 
 #endif  // mozilla_ipc_backgroundparentimpl_h__
--- a/ipc/glue/PBackground.ipdl
+++ b/ipc/glue/PBackground.ipdl
@@ -13,16 +13,17 @@ include protocol PBackgroundLSSimpleRequ
 include protocol PBackgroundLocalStorageCache;
 include protocol PBackgroundStorage;
 include protocol PBackgroundTest;
 include protocol PBroadcastChannel;
 include protocol PCache;
 include protocol PCacheStorage;
 include protocol PCacheStreamControl;
 include protocol PClientManager;
+include protocol PEndpointForReport;
 include protocol PFileDescriptorSet;
 include protocol PFileSystemRequest;
 include protocol PGamepadEventChannel;
 include protocol PGamepadTestChannel;
 include protocol PHttpBackgroundChannel;
 include protocol PIPCBlobInputStream;
 include protocol PPendingIPCBlob;
 include protocol PRemoteWorker;
@@ -84,16 +85,17 @@ sync protocol PBackground
   manages PBackgroundLocalStorageCache;
   manages PBackgroundStorage;
   manages PBackgroundTest;
   manages PBroadcastChannel;
   manages PCache;
   manages PCacheStorage;
   manages PCacheStreamControl;
   manages PClientManager;
+  manages PEndpointForReport;
   manages PFileDescriptorSet;
   manages PFileSystemRequest;
   manages PGamepadEventChannel;
   manages PGamepadTestChannel;
   manages PHttpBackgroundChannel;
   manages PIPCBlobInputStream;
   manages PPendingIPCBlob;
   manages PRemoteWorker;
@@ -208,16 +210,18 @@ parent:
   async PServiceWorker(IPCServiceWorkerDescriptor aDescriptor);
 
   async PRemoteWorkerService();
 
   async PServiceWorkerContainer();
 
   async PServiceWorkerRegistration(IPCServiceWorkerRegistrationDescriptor aDescriptor);
 
+  async PEndpointForReport(nsString aGroupName, PrincipalInfo aPrincipalInfo);
+
 child:
   async PCache();
   async PCacheStreamControl();
 
   async PParentToChildStream();
 
   async PPendingIPCBlob(IPCBlob blob);