Bug 1430317: Add memory reporter to show basic information about active WebExtensions. r?erahm draft
authorKris Maglione <maglione.k@gmail.com>
Fri, 12 Jan 2018 16:01:18 -0800
changeset 719980 0bd92d75475690ddd702bc5e6b270a08dddbd3ef
parent 719979 8357c080dccbe4c6aaba3d9e012b3262f45ff7f6
child 745944 de21c9808e947e0db7fb55f9adf59c8dbf56c57e
push id95413
push usermaglione.k@gmail.com
push dateSat, 13 Jan 2018 00:03:57 +0000
reviewerserahm
bugs1430317
milestone59.0a1
Bug 1430317: Add memory reporter to show basic information about active WebExtensions. r?erahm MozReview-Commit-ID: FR8F30bhhA4
toolkit/components/extensions/ExtensionPolicyService.cpp
toolkit/components/extensions/ExtensionPolicyService.h
--- a/toolkit/components/extensions/ExtensionPolicyService.cpp
+++ b/toolkit/components/extensions/ExtensionPolicyService.cpp
@@ -4,16 +4,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ExtensionPolicyService.h"
 #include "mozilla/extensions/WebExtensionContentScript.h"
 #include "mozilla/extensions/WebExtensionPolicy.h"
 
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/ResultExtensions.h"
 #include "mozilla/Services.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozIExtensionProcessScript.h"
 #include "nsEscape.h"
 #include "nsGkAtoms.h"
 #include "nsIChannel.h"
 #include "nsIContentPolicy.h"
@@ -62,31 +63,37 @@ ProcessScript()
 
 /* static */ ExtensionPolicyService&
 ExtensionPolicyService::GetSingleton()
 {
   static RefPtr<ExtensionPolicyService> sExtensionPolicyService;
 
   if (MOZ_UNLIKELY(!sExtensionPolicyService)) {
     sExtensionPolicyService = new ExtensionPolicyService();
+    RegisterWeakMemoryReporter(sExtensionPolicyService);
     ClearOnShutdown(&sExtensionPolicyService);
   }
   return *sExtensionPolicyService.get();
 }
 
 ExtensionPolicyService::ExtensionPolicyService()
 {
   mObs = services::GetObserverService();
   MOZ_RELEASE_ASSERT(mObs);
 
   Preferences::AddBoolVarCache(&sRemoteExtensions, "extensions.webextensions.remote", false);
 
   RegisterObservers();
 }
 
+ExtensionPolicyService::~ExtensionPolicyService()
+{
+  UnregisterWeakMemoryReporter(this);
+}
+
 bool
 ExtensionPolicyService::UseRemoteExtensions() const
 {
   return sRemoteExtensions && BrowserTabsRemoteAutostart();
 }
 
 bool
 ExtensionPolicyService::IsExtensionProcess() const
@@ -170,16 +177,55 @@ ExtensionPolicyService::DefaultCSP(nsASt
   rv = Preferences::GetString("extensions.webextensions.default-content-security-policy", aDefaultCSP);
   if (NS_FAILED(rv)) {
     aDefaultCSP.AssignLiteral(DEFAULT_DEFAULT_CSP);
   }
 }
 
 
 /*****************************************************************************
+ * nsIMemoryReporter
+ *****************************************************************************/
+
+NS_IMETHODIMP
+ExtensionPolicyService::CollectReports(nsIHandleReportCallback* aHandleReport,
+                                       nsISupports* aData, bool aAnonymize)
+{
+  for (auto iter = mExtensions.Iter(); !iter.Done(); iter.Next()) {
+    auto& ext = iter.Data();
+
+    nsAtomCString id(ext->Id());
+
+    NS_ConvertUTF16toUTF8 name(ext->Name());
+    name.ReplaceSubstring("\"", "");
+    name.ReplaceSubstring("\\", "");
+
+    nsString url;
+    MOZ_TRY_VAR(url, ext->GetURL(NS_LITERAL_STRING("")));
+
+    nsPrintfCString desc("Extension(id=%s, name=\"%s\", baseURL=%s)",
+                         id.get(), name.get(),
+                         NS_ConvertUTF16toUTF8(url).get());
+    desc.ReplaceChar('/', '\\');
+
+    nsCString path("extensions/");
+    path.Append(desc);
+
+    aHandleReport->Callback(
+      EmptyCString(), path,
+      KIND_NONHEAP, UNITS_COUNT, 1,
+      NS_LITERAL_CSTRING("WebExtensions that are active in this session"),
+      aData);
+  }
+
+  return NS_OK;
+}
+
+
+/*****************************************************************************
  * Content script management
  *****************************************************************************/
 
 void
 ExtensionPolicyService::RegisterObservers()
 {
   mObs->AddObserver(this, "content-document-global-created", false);
   mObs->AddObserver(this, "document-element-inserted", false);
--- a/toolkit/components/extensions/ExtensionPolicyService.h
+++ b/toolkit/components/extensions/ExtensionPolicyService.h
@@ -1,22 +1,24 @@
 /* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ExtensionPolicyService_h
 #define mozilla_ExtensionPolicyService_h
 
+#include "mozilla/MemoryReporting.h"
 #include "mozilla/extensions/WebExtensionPolicy.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsHashKeys.h"
 #include "nsIAddonPolicyService.h"
 #include "nsAtom.h"
+#include "nsIMemoryReporter.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsISupports.h"
 #include "nsPointerHashKeys.h"
 #include "nsRefPtrHashtable.h"
 
 class nsIChannel;
 class nsIObserverService;
@@ -28,23 +30,25 @@ namespace extensions {
   class DocInfo;
 }
 
 using extensions::DocInfo;
 using extensions::WebExtensionPolicy;
 
 class ExtensionPolicyService final : public nsIAddonPolicyService
                                    , public nsIObserver
+                                   , public nsIMemoryReporter
 {
 public:
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ExtensionPolicyService,
                                            nsIAddonPolicyService)
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIADDONPOLICYSERVICE
   NS_DECL_NSIOBSERVER
+  NS_DECL_NSIMEMORYREPORTER
 
   static ExtensionPolicyService& GetSingleton();
 
   static already_AddRefed<ExtensionPolicyService> GetInstance()
   {
     return do_AddRef(&GetSingleton());
   }
 
@@ -74,17 +78,17 @@ public:
 
   void BaseCSP(nsAString& aDefaultCSP) const;
   void DefaultCSP(nsAString& aDefaultCSP) const;
 
   bool UseRemoteExtensions() const;
   bool IsExtensionProcess() const;
 
 protected:
-  virtual ~ExtensionPolicyService() = default;
+  virtual ~ExtensionPolicyService();
 
 private:
   ExtensionPolicyService();
 
   void RegisterObservers();
   void UnregisterObservers();
 
   void CheckRequest(nsIChannel* aChannel);