Bug 1046166 - Send userContent.css URL to content processes. r?dbaron draft
authorWei-Cheng Pan <wpan@mozilla.com>
Thu, 21 Jul 2016 18:57:35 +0800
changeset 440335 c31568af155e6dd050010bf909ba913b2b7f82dc
parent 440163 c27117f67fa3ff30bbd34bcd6c7536c0d10bd4ad
child 440336 862bacd2ad489da5d702f440446e52808719c87e
push id36205
push userbmo:wpan@mozilla.com
push dateThu, 17 Nov 2016 10:38:13 +0000
reviewersdbaron
bugs1046166
milestone53.0a1
Bug 1046166 - Send userContent.css URL to content processes. r?dbaron MozReview-Commit-ID: 4NTxwYeFGSU
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
layout/style/nsLayoutStylesheetCache.cpp
layout/style/nsLayoutStylesheetCache.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -909,22 +909,23 @@ ContentChild::InitXPCOM()
   if (NS_FAILED(svc->RegisterListener(mConsoleListener)))
     NS_WARNING("Couldn't register console listener for child process");
 
   bool isOffline, isLangRTL, haveBidiKeyboards;
   bool isConnected;
   ClipboardCapabilities clipboardCaps;
   DomainPolicyClone domainPolicy;
   StructuredCloneData initialData;
+  OptionalURIParams userContentSheetURL;
 
   SendGetXPCOMProcessAttributes(&isOffline, &isConnected,
                                 &isLangRTL, &haveBidiKeyboards,
                                 &mAvailableDictionaries,
                                 &clipboardCaps, &domainPolicy, &initialData,
-                                &mFontFamilies);
+                                &mFontFamilies, &userContentSheetURL);
   RecvSetOffline(isOffline);
   RecvSetConnectivity(isConnected);
   RecvBidiKeyboardNotify(isLangRTL, haveBidiKeyboards);
 
   // Create the CPOW manager as soon as possible.
   SendPJavaScriptConstructor();
 
   if (domainPolicy.active()) {
@@ -952,16 +953,20 @@ ContentChild::InitXPCOM()
     initialData.Read(jsapi.cx(), &data, rv);
     if (NS_WARN_IF(rv.Failed())) {
       MOZ_CRASH();
     }
     ProcessGlobal* global = ProcessGlobal::Get();
     global->SetInitialProcessData(data);
   }
 
+  // The stylesheet cache is not ready yet. Store this URL for future use.
+  nsCOMPtr<nsIURI> ucsURL = DeserializeURI(userContentSheetURL);
+  nsLayoutStylesheetCache::SetUserContentCSSURL(ucsURL);
+
   // This will register cross-process observer.
   mozilla::dom::time::InitializeDateCacheCleaner();
 }
 
 PMemoryReportRequestChild*
 ContentChild::AllocPMemoryReportRequestChild(const uint32_t& aGeneration,
                                              const bool &aAnonymize,
                                              const bool &aMinimizeMemoryUsage,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -177,16 +177,18 @@
 #include "nsPluginTags.h"
 #include "nsIBlocklistService.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "nsHostObjectProtocolHandler.h"
 
 #include "nsIBidiKeyboard.h"
 
+#include "nsLayoutStylesheetCache.h"
+
 #ifdef MOZ_WEBRTC
 #include "signaling/src/peerconnection/WebrtcGlobalParent.h"
 #endif
 
 #if defined(ANDROID) || defined(LINUX)
 #include "nsSystemInfo.h"
 #endif
 
@@ -2536,17 +2538,18 @@ mozilla::ipc::IPCResult
 ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline,
                                              bool* aIsConnected,
                                              bool* aIsLangRTL,
                                              bool* aHaveBidiKeyboards,
                                              InfallibleTArray<nsString>* dictionaries,
                                              ClipboardCapabilities* clipboardCaps,
                                              DomainPolicyClone* domainPolicy,
                                              StructuredCloneData* aInitialData,
-                                             InfallibleTArray<FontFamilyListEntry>* fontFamilies)
+                                             InfallibleTArray<FontFamilyListEntry>* fontFamilies,
+                                             OptionalURIParams* aUserContentCSSURL)
 {
   nsCOMPtr<nsIIOService> io(do_GetIOService());
   MOZ_ASSERT(io, "No IO service?");
   DebugOnly<nsresult> rv = io->GetOffline(aIsOffline);
   MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting offline?");
 
   rv = io->GetConnectivity(aIsConnected);
   MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting connectivity?");
@@ -2596,16 +2599,25 @@ ContentParent::RecvGetXPCOMProcessAttrib
       rv.SuppressException();
       return IPC_FAIL_NO_REASON(this);
     }
   }
 
   // This is only implemented (returns a non-empty list) by MacOSX at present.
   gfxPlatform::GetPlatform()->GetSystemFontFamilyList(fontFamilies);
 
+  // Content processes have no permission to access profile directory, so we
+  // send the file URL instead.
+  StyleSheet* ucs = nsLayoutStylesheetCache::For(StyleBackendType::Gecko)->UserContentSheet();
+  if (ucs) {
+    SerializeURI(ucs->GetSheetURI(), *aUserContentCSSURL);
+  } else {
+    SerializeURI(nullptr, *aUserContentCSSURL);
+  }
+
   return IPC_OK();
 }
 
 mozilla::jsipc::PJavaScriptParent *
 ContentParent::AllocPJavaScriptParent()
 {
   MOZ_ASSERT(ManagedPJavaScriptParent().IsEmpty());
   return nsIContentParent::AllocPJavaScriptParent();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -658,18 +658,18 @@ private:
   RecvGetXPCOMProcessAttributes(bool* aIsOffline,
                                 bool* aIsConnected,
                                 bool* aIsLangRTL,
                                 bool* aHaveBidiKeyboards,
                                 InfallibleTArray<nsString>* dictionaries,
                                 ClipboardCapabilities* clipboardCaps,
                                 DomainPolicyClone* domainPolicy,
                                 StructuredCloneData* initialData,
-                                InfallibleTArray<FontFamilyListEntry>* fontFamilies)
-                                override;
+                                InfallibleTArray<FontFamilyListEntry>* fontFamilies,
+                                OptionalURIParams* aUserContentSheetURL) override;
 
   virtual bool
   DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*) override;
 
   virtual bool
   DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent*) override;
 
   virtual PBrowserParent* AllocPBrowserParent(const TabId& aTabId,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -689,17 +689,18 @@ parent:
     sync GetProcessAttributes()
         returns (ContentParentId cpId, bool isForBrowser);
     sync GetXPCOMProcessAttributes()
         returns (bool isOffline, bool isConnected, bool isLangRTL,
                  bool haveBidiKeyboards, nsString[] dictionaries,
                  ClipboardCapabilities clipboardCaps,
                  DomainPolicyClone domainPolicy,
                  StructuredCloneData initialData,
-                 FontFamilyListEntry[] fontFamilies /* used on MacOSX only */);
+                 FontFamilyListEntry[] fontFamilies /* used on MacOSX only */,
+                 OptionalURIParams userContentSheetURL);
 
     sync CreateChildProcess(IPCTabContext context,
                             ProcessPriority priority,
                             TabId openerTabId)
         returns (ContentParentId cpId, bool isForBrowser, TabId tabId);
     sync BridgeToChildProcess(ContentParentId cpId);
 
     async CreateGMPService();
--- a/layout/style/nsLayoutStylesheetCache.cpp
+++ b/layout/style/nsLayoutStylesheetCache.cpp
@@ -15,16 +15,17 @@
 #include "mozilla/css/Loader.h"
 #include "mozilla/dom/SRIMetadata.h"
 #include "nsIFile.h"
 #include "nsNetUtil.h"
 #include "nsIObserverService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIXULRuntime.h"
 #include "nsPrintfCString.h"
+#include "nsXULAppAPI.h"
 
 // Includes for the crash report annotation in ErrorLoadingBuiltinSheet.
 #ifdef MOZ_CRASHREPORTER
 #include "mozilla/Omnijar.h"
 #include "nsDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsExceptionHandler.h"
 #include "nsIChromeRegistry.h"
@@ -248,16 +249,24 @@ nsLayoutStylesheetCache::DesignModeSheet
 
 void
 nsLayoutStylesheetCache::Shutdown()
 {
   gCSSLoader_Gecko = nullptr;
   gCSSLoader_Servo = nullptr;
   gStyleCache_Gecko = nullptr;
   gStyleCache_Servo = nullptr;
+  MOZ_ASSERT(!gUserContentSheetURL, "Got the URL but never used?");
+}
+
+void
+nsLayoutStylesheetCache::SetUserContentCSSURL(nsIURI* aURI)
+{
+  MOZ_ASSERT(XRE_IsContentProcess(), "Only used in content processes.");
+  gUserContentSheetURL = aURI;
 }
 
 MOZ_DEFINE_MALLOC_SIZE_OF(LayoutStylesheetCacheMallocSizeOf)
 
 NS_IMETHODIMP
 nsLayoutStylesheetCache::CollectReports(nsIHandleReportCallback* aHandleReport,
                                         nsISupports* aData, bool aAnonymize)
 {
@@ -329,16 +338,22 @@ nsLayoutStylesheetCache::nsLayoutStylesh
                &mMinimalXULSheet, eAgentSheetFeatures);
   LoadSheetURL("resource://gre-resources/quirk.css",
                &mQuirkSheet, eAgentSheetFeatures);
   LoadSheetURL("resource://gre/res/svg.css",
                &mSVGSheet, eAgentSheetFeatures);
   LoadSheetURL("chrome://global/content/xul.css",
                &mXULSheet, eAgentSheetFeatures);
 
+  if (gUserContentSheetURL) {
+    MOZ_ASSERT(XRE_IsContentProcess(), "Only used in content processes.");
+    LoadSheet(gUserContentSheetURL, &mUserContentSheet, eUserSheetFeatures);
+    gUserContentSheetURL = nullptr;
+  }
+
   // The remaining sheets are created on-demand do to their use being rarer
   // (which helps save memory for Firefox OS apps) or because they need to
   // be re-loadable in DependentPrefChanged.
 }
 
 nsLayoutStylesheetCache::~nsLayoutStylesheetCache()
 {
   mozilla::UnregisterWeakMemoryReporter(this);
@@ -962,8 +977,11 @@ nsLayoutStylesheetCache::gStyleCache_Gec
 mozilla::StaticRefPtr<nsLayoutStylesheetCache>
 nsLayoutStylesheetCache::gStyleCache_Servo;
 
 mozilla::StaticRefPtr<mozilla::css::Loader>
 nsLayoutStylesheetCache::gCSSLoader_Gecko;
 
 mozilla::StaticRefPtr<mozilla::css::Loader>
 nsLayoutStylesheetCache::gCSSLoader_Servo;
+
+mozilla::StaticRefPtr<nsIURI>
+nsLayoutStylesheetCache::gUserContentSheetURL;
--- a/layout/style/nsLayoutStylesheetCache.h
+++ b/layout/style/nsLayoutStylesheetCache.h
@@ -61,16 +61,18 @@ class nsLayoutStylesheetCache final
   mozilla::StyleSheet* ContentPreferenceSheet(nsPresContext* aPresContext);
   mozilla::StyleSheet* ContentEditableSheet();
   mozilla::StyleSheet* DesignModeSheet();
 
   static void InvalidatePreferenceSheets();
 
   static void Shutdown();
 
+  static void SetUserContentCSSURL(nsIURI* aURI);
+
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
 private:
   explicit nsLayoutStylesheetCache(mozilla::StyleBackendType aImpl);
   ~nsLayoutStylesheetCache();
 
   void InitFromProfile();
   void InitMemoryReporter();
@@ -87,16 +89,17 @@ private:
   static void DependentPrefChanged(const char* aPref, void* aData);
   void BuildPreferenceSheet(RefPtr<mozilla::StyleSheet>* aSheet,
                             nsPresContext* aPresContext);
 
   static mozilla::StaticRefPtr<nsLayoutStylesheetCache> gStyleCache_Gecko;
   static mozilla::StaticRefPtr<nsLayoutStylesheetCache> gStyleCache_Servo;
   static mozilla::StaticRefPtr<mozilla::css::Loader> gCSSLoader_Gecko;
   static mozilla::StaticRefPtr<mozilla::css::Loader> gCSSLoader_Servo;
+  static mozilla::StaticRefPtr<nsIURI> gUserContentSheetURL;
   mozilla::StyleBackendType mBackendType;
   RefPtr<mozilla::StyleSheet> mChromePreferenceSheet;
   RefPtr<mozilla::StyleSheet> mContentEditableSheet;
   RefPtr<mozilla::StyleSheet> mContentPreferenceSheet;
   RefPtr<mozilla::StyleSheet> mCounterStylesSheet;
   RefPtr<mozilla::StyleSheet> mDesignModeSheet;
   RefPtr<mozilla::StyleSheet> mFormsSheet;
   RefPtr<mozilla::StyleSheet> mHTMLSheet;