author | Brad Lassey <blassey@mozilla.com> |
Sun, 05 Feb 2017 00:52:38 -0500 | |
changeset 387742 | 5a43dbcb95cab9ff9728383f05780faa72e1ad5e |
parent 387741 | c5d678ebcbcd24dce64426492e3f20ca5a1bd261 |
child 387743 | 4dc3eb7f7b1284459eafc16d1fa0aecc9b2ff385 |
push id | 7198 |
push user | jlorenzo@mozilla.com |
push date | Tue, 18 Apr 2017 12:07:49 +0000 |
treeherder | mozilla-beta@d57aa49c3948 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | billm |
bugs | 1303096 |
milestone | 54.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
|
--- a/caps/DomainPolicy.cpp +++ b/caps/DomainPolicy.cpp @@ -134,17 +134,17 @@ CopyURIs(const InfallibleTArray<URIParam { for (uint32_t i = 0; i < aDomains.Length(); i++) { nsCOMPtr<nsIURI> uri = DeserializeURI(aDomains[i]); aSet->Add(uri); } } void -DomainPolicy::ApplyClone(DomainPolicyClone* aClone) +DomainPolicy::ApplyClone(const DomainPolicyClone* aClone) { CopyURIs(aClone->blacklist(), mBlacklist); CopyURIs(aClone->whitelist(), mWhitelist); CopyURIs(aClone->superBlacklist(), mSuperBlacklist); CopyURIs(aClone->superWhitelist(), mSuperWhitelist); } static already_AddRefed<nsIURI>
--- a/caps/nsIDomainPolicy.idl +++ b/caps/nsIDomainPolicy.idl @@ -12,16 +12,17 @@ interface nsIDomainSet; namespace mozilla { namespace dom { class DomainPolicyClone; } } %} [ptr] native DomainPolicyClonePtr(mozilla::dom::DomainPolicyClone); +[ptr] native DomainPolicyCloneConstPtr(const mozilla::dom::DomainPolicyClone); /* * When a domain policy is instantiated by invoking activateDomainPolicy() on * nsIScriptSecurityManager, these domain sets are consulted when each new * global is created (they have no effect on already-created globals). * If javascript is globally enabled with |javascript.enabled|, the blacklists * are consulted. If globally disabled, the whitelists are consulted. Lookups * on blacklist and whitelist happen with contains(), and lookups on @@ -36,17 +37,17 @@ interface nsIDomainPolicy : nsISupports readonly attribute nsIDomainSet blacklist; readonly attribute nsIDomainSet superBlacklist; readonly attribute nsIDomainSet whitelist; readonly attribute nsIDomainSet superWhitelist; void deactivate(); [noscript, notxpcom] void cloneDomainPolicy(in DomainPolicyClonePtr aClone); - [noscript, notxpcom] void applyClone(in DomainPolicyClonePtr aClone); + [noscript, notxpcom] void applyClone(in DomainPolicyCloneConstPtr aClone); }; [scriptable, builtinclass, uuid(665c981b-0a0f-4229-ac06-a826e02d4f69)] interface nsIDomainSet : nsISupports { /* * The type of the set. See: DomainSetType */
--- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -497,20 +497,34 @@ ContentChild::~ContentChild() #endif NS_INTERFACE_MAP_BEGIN(ContentChild) NS_INTERFACE_MAP_ENTRY(nsIContentChild) NS_INTERFACE_MAP_ENTRY(nsIWindowProvider) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentChild) NS_INTERFACE_MAP_END + +mozilla::ipc::IPCResult +ContentChild::RecvSetXPCOMProcessAttributes(const XPCOMInitData& aXPCOMInit, + const StructuredCloneData& aInitialData, + nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) +{ + mLookAndFeelCache = aLookAndFeelIntCache; + InitXPCOM(aXPCOMInit, aInitialData); + InitGraphicsDeviceData(); + return IPC_OK(); +} + bool ContentChild::Init(MessageLoop* aIOLoop, base::ProcessId aParentPid, - IPC::Channel* aChannel) + IPC::Channel* aChannel, + uint64_t aChildID, + bool aIsForBrowser) { #ifdef MOZ_WIDGET_GTK // We need to pass a display down to gtk_init because it's not going to // use the one from the environment on its own when deciding which backend // to use, and when starting under XWayland, it may choose to start with // the wayland backend instead of the x11 backend. // The DISPLAY environment variable is normally set by the parent process. char* display_name = PR_GetEnv("DISPLAY"); @@ -566,17 +580,18 @@ ContentChild::Init(MessageLoop* aIOLoop, SendBackUpXResources(FileDescriptor(xSocketFd)); #endif #ifdef MOZ_CRASHREPORTER SendPCrashReporterConstructor(CrashReporter::CurrentThreadId(), XRE_GetProcessType()); #endif - SendGetProcessAttributes(&mID, &mIsForBrowser); + mID = aChildID; + mIsForBrowser = aIsForBrowser; #ifdef NS_PRINTING // Force the creation of the nsPrintingProxy so that it's IPC counterpart, // PrintingParent, is always available for printing initiated from the parent. RefPtr<nsPrintingProxy> printingProxy = nsPrintingProxy::GetInstance(); #endif SetProcessName(NS_LITERAL_STRING("Web Content"), true); @@ -928,18 +943,24 @@ void ContentChild::InitGraphicsDeviceData() { // Initialize the graphics platform. This may contact the parent process // to read device preferences. gfxPlatform::GetPlatform(); } void -ContentChild::InitXPCOM() +ContentChild::InitXPCOM(const XPCOMInitData& aXPCOMInit, + const mozilla::dom::ipc::StructuredCloneData& aInitialData) { + SET_PREF_PHASE(pref_initPhase::BEGIN_ALL_PREFS); + for (unsigned int i = 0; i < aXPCOMInit.prefs().Length(); i++) { + Preferences::SetPreference(aXPCOMInit.prefs().ElementAt(i)); + } + SET_PREF_PHASE(pref_initPhase::END_ALL_PREFS); // Do this as early as possible to get the parent process to initialize the // background thread since we'll likely need database information very soon. BackgroundChild::Startup(); nsCOMPtr<nsIIPCBackgroundChildCreateCallback> callback = new BackgroundChildPrimer(); if (!BackgroundChild::GetOrCreateForCurrentThread(callback)) { MOZ_CRASH("Failed to create PBackgroundChild!"); @@ -952,71 +973,60 @@ ContentChild::InitXPCOM() NS_WARNING("Couldn't acquire console service"); return; } mConsoleListener = new ConsoleListener(this); if (NS_FAILED(svc->RegisterListener(mConsoleListener))) NS_WARNING("Couldn't register console listener for child process"); - bool isOffline, isLangRTL, haveBidiKeyboards; - bool isConnected; - int32_t captivePortalState; - ClipboardCapabilities clipboardCaps; - DomainPolicyClone domainPolicy; - StructuredCloneData initialData; - OptionalURIParams userContentSheetURL; - - SendGetXPCOMProcessAttributes(&isOffline, &isConnected, &captivePortalState, - &isLangRTL, &haveBidiKeyboards, - &mAvailableDictionaries, - &clipboardCaps, &domainPolicy, &initialData, - &mFontFamilies, &userContentSheetURL, - &mLookAndFeelCache); - - RecvSetOffline(isOffline); - RecvSetConnectivity(isConnected); - RecvSetCaptivePortalState(captivePortalState); - RecvBidiKeyboardNotify(isLangRTL, haveBidiKeyboards); + mAvailableDictionaries = aXPCOMInit.dictionaries(); + + RecvSetOffline(aXPCOMInit.isOffline()); + RecvSetConnectivity(aXPCOMInit.isConnected()); + RecvSetCaptivePortalState(aXPCOMInit.captivePortalState()); + RecvBidiKeyboardNotify(aXPCOMInit.isLangRTL(), aXPCOMInit.haveBidiKeyboards()); // Create the CPOW manager as soon as possible. SendPJavaScriptConstructor(); - if (domainPolicy.active()) { + if (aXPCOMInit.domainPolicy().active()) { nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); MOZ_ASSERT(ssm); ssm->ActivateDomainPolicyInternal(getter_AddRefs(mPolicy)); if (!mPolicy) { MOZ_CRASH("Failed to activate domain policy."); } - mPolicy->ApplyClone(&domainPolicy); + mPolicy->ApplyClone(&aXPCOMInit.domainPolicy()); } nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1")); if (nsCOMPtr<nsIClipboardProxy> clipboardProxy = do_QueryInterface(clipboard)) { - clipboardProxy->SetCapabilities(clipboardCaps); + clipboardProxy->SetCapabilities(aXPCOMInit.clipboardCaps()); } { AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) { MOZ_CRASH(); } ErrorResult rv; JS::RootedValue data(jsapi.cx()); - initialData.Read(jsapi.cx(), &data, rv); + mozilla::dom::ipc::StructuredCloneData id; + id.Copy(aInitialData); + id.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); + nsCOMPtr<nsIURI> ucsURL = DeserializeURI(aXPCOMInit.userContentSheetURL()); nsLayoutStylesheetCache::SetUserContentCSSURL(ucsURL); // This will register cross-process observer. mozilla::dom::time::InitializeDateCacheCleaner(); } mozilla::ipc::IPCResult ContentChild::RecvRequestMemoryReport(const uint32_t& aGeneration,
--- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -91,19 +91,22 @@ public: const nsAString& aName, const nsACString& aFeatures, bool aForceNoOpener, bool* aWindowIsNew, mozIDOMWindowProxy** aReturn); bool Init(MessageLoop* aIOLoop, base::ProcessId aParentPid, - IPC::Channel* aChannel); + IPC::Channel* aChannel, + uint64_t aChildID, + bool aIsForBrowser); - void InitXPCOM(); + void InitXPCOM(const XPCOMInitData& aXPCOMInit, + const mozilla::dom::ipc::StructuredCloneData& aInitialData); void InitGraphicsDeviceData(); static ContentChild* GetSingleton() { return sSingleton; } @@ -568,16 +571,21 @@ public: mozilla::ipc::IPCResult RecvRequestMemoryReport( const uint32_t& generation, const bool& anonymize, const bool& minimizeMemoryUsage, const MaybeFileDesc& DMDFile) override; + virtual mozilla::ipc::IPCResult + RecvSetXPCOMProcessAttributes(const XPCOMInitData& aXPCOMInit, + const StructuredCloneData& aInitialData, + nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override; + #if defined(XP_WIN) && defined(ACCESSIBILITY) bool SendGetA11yContentId(); #endif // defined(XP_WIN) && defined(ACCESSIBILITY) // Get a reference to the font family list passed from the chrome process, // for use during gfx initialization. InfallibleTArray<mozilla::dom::FontFamilyListEntry>&
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -181,16 +181,18 @@ #include "mozilla/StyleSheetInlines.h" #include "nsHostObjectProtocolHandler.h" #include "nsICaptivePortalService.h" #include "nsIBidiKeyboard.h" #include "nsLayoutStylesheetCache.h" +#include "ContentPrefs.h" + #ifdef MOZ_WEBRTC #include "signaling/src/peerconnection/WebrtcGlobalParent.h" #endif #if defined(ANDROID) || defined(LINUX) #include "nsSystemInfo.h" #endif @@ -1819,16 +1821,58 @@ ContentParent::InitializeMembers() } bool ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */) { PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER); std::vector<std::string> extraArgs; + extraArgs.push_back("-childID"); + char idStr[21]; + SprintfLiteral(idStr, "%" PRId64, static_cast<uint64_t>(mChildID)); + extraArgs.push_back(idStr); + extraArgs.push_back(IsForBrowser() ? "-isForBrowser" : "-notForBrowser"); + + std::stringstream boolPrefs; + std::stringstream intPrefs; + std::stringstream stringPrefs; + + size_t prefsLen; + ContentPrefs::GetContentPrefs(&prefsLen); + + for (unsigned int i = 0; i < prefsLen; i++) { + MOZ_ASSERT(i == 0 || strcmp(ContentPrefs::GetContentPref(i), ContentPrefs::GetContentPref(i - 1)) > 0); + switch (Preferences::GetType(ContentPrefs::GetContentPref(i))) { + case nsIPrefBranch::PREF_INT: + intPrefs << i << ':' << Preferences::GetInt(ContentPrefs::GetContentPref(i)) << '|'; + break; + case nsIPrefBranch::PREF_BOOL: + boolPrefs << i << ':' << Preferences::GetBool(ContentPrefs::GetContentPref(i)) << '|'; + break; + case nsIPrefBranch::PREF_STRING: { + std::string value(Preferences::GetCString(ContentPrefs::GetContentPref(i)).get()); + stringPrefs << i << ':' << value.length() << ':' << value << '|'; + } + break; + case nsIPrefBranch::PREF_INVALID: + break; + default: + printf("preference type: %x\n", Preferences::GetType(ContentPrefs::GetContentPref(i))); + MOZ_CRASH(); + } + } + + extraArgs.push_back("-intPrefs"); + extraArgs.push_back(intPrefs.str()); + extraArgs.push_back("-boolPrefs"); + extraArgs.push_back(boolPrefs.str()); + extraArgs.push_back("-stringPrefs"); + extraArgs.push_back(stringPrefs.str()); + if (!mSubprocess->LaunchAndWaitForProcessHandle(extraArgs)) { MarkAsDead(); return false; } Open(mSubprocess->GetChannel(), base::GetProcId(mSubprocess->GetChildProcessHandle())); @@ -1838,16 +1882,27 @@ ContentParent::LaunchSubprocess(ProcessP ContentProcessManager::GetSingleton()->AddContentProcess(this); mHangMonitorActor = ProcessHangMonitor::AddProcess(this); // Set a reply timeout for CPOWs. SetReplyTimeoutMs(Preferences::GetInt("dom.ipc.cpow.timeout", 0)); + Telemetry::Accumulate(Telemetry::CONTENT_PROCESS_LAUNCH_TIME_MS, + static_cast<uint32_t>((TimeStamp::Now() - mLaunchTS) + .ToMilliseconds())); + + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + if (obs) { + nsAutoString cpId; + cpId.AppendInt(static_cast<uint64_t>(this->ChildID())); + obs->NotifyObservers(static_cast<nsIObserver*>(this), "ipc:content-initializing", cpId.get()); + } + return true; } ContentParent::ContentParent(ContentParent* aOpener, const nsAString& aRemoteType) : nsIContentParent() , mLaunchTS(TimeStamp::Now()) , mOpener(aOpener) @@ -1895,16 +1950,100 @@ ContentParent::~ContentParent() !sBrowserContentParents->Get(mRemoteType)->Contains(this)); } void ContentParent::InitInternal(ProcessPriority aInitialPriority, bool aSetupOffMainThreadCompositing, bool aSendRegisteredChrome) { + Telemetry::Accumulate(Telemetry::CONTENT_PROCESS_LAUNCH_TIME_MS, + static_cast<uint32_t>((TimeStamp::Now() - mLaunchTS) + .ToMilliseconds())); + + XPCOMInitData xpcomInit; + + Preferences::GetPreferences(&xpcomInit.prefs()); + nsCOMPtr<nsIIOService> io(do_GetIOService()); + MOZ_ASSERT(io, "No IO service?"); + DebugOnly<nsresult> rv = io->GetOffline(&xpcomInit.isOffline()); + MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting offline?"); + + rv = io->GetConnectivity(&xpcomInit.isConnected()); + MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting connectivity?"); + + xpcomInit.captivePortalState() = nsICaptivePortalService::UNKNOWN; + nsCOMPtr<nsICaptivePortalService> cps = do_GetService(NS_CAPTIVEPORTAL_CONTRACTID); + if (cps) { + cps->GetState(&xpcomInit.captivePortalState()); + } + + nsIBidiKeyboard* bidi = nsContentUtils::GetBidiKeyboard(); + + xpcomInit.isLangRTL() = false; + xpcomInit.haveBidiKeyboards() = false; + if (bidi) { + bidi->IsLangRTL(&xpcomInit.isLangRTL()); + bidi->GetHaveBidiKeyboards(&xpcomInit.haveBidiKeyboards()); + } + + nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID)); + MOZ_ASSERT(spellChecker, "No spell checker?"); + + spellChecker->GetDictionaryList(&xpcomInit.dictionaries()); + + nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1")); + MOZ_ASSERT(clipboard, "No clipboard?"); + + rv = clipboard->SupportsSelectionClipboard(&xpcomInit.clipboardCaps().supportsSelectionClipboard()); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + + rv = clipboard->SupportsFindClipboard(&xpcomInit.clipboardCaps().supportsFindClipboard()); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + + // Let's copy the domain policy from the parent to the child (if it's active). + StructuredCloneData initialData; + nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); + if (ssm) { + ssm->CloneDomainPolicy(&xpcomInit.domainPolicy()); + + if (nsFrameMessageManager* mm = nsFrameMessageManager::sParentProcessManager) { + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) { + MOZ_CRASH(); + } + JS::RootedValue init(jsapi.cx()); + nsresult result = mm->GetInitialProcessData(jsapi.cx(), &init); + if (NS_FAILED(result)) { + MOZ_CRASH(); + } + + ErrorResult rv; + initialData.Write(jsapi.cx(), init, rv); + if (NS_WARN_IF(rv.Failed())) { + rv.SuppressException(); + MOZ_CRASH(); + } + } + } + // This is only implemented (returns a non-empty list) by MacOSX at present. + gfxPlatform::GetPlatform()->GetSystemFontFamilyList(&xpcomInit.fontFamilies()); + nsTArray<LookAndFeelInt> lnfCache = LookAndFeel::GetIntCache(); + + // 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(), xpcomInit.userContentSheetURL()); + } else { + SerializeURI(nullptr, xpcomInit.userContentSheetURL()); + } + + Unused << SendSetXPCOMProcessAttributes(xpcomInit, initialData, lnfCache); + if (aSendRegisteredChrome) { nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService(); nsChromeRegistryChrome* chromeRegistry = static_cast<nsChromeRegistryChrome*>(registrySvc.get()); chromeRegistry->SendRegisteredChrome(this); } if (gAppData) { @@ -2067,23 +2206,16 @@ ContentParent::Pid() const { if (!mSubprocess || !mSubprocess->GetChildProcessHandle()) { return -1; } return base::GetProcId(mSubprocess->GetChildProcessHandle()); } mozilla::ipc::IPCResult -ContentParent::RecvReadPrefsArray(InfallibleTArray<PrefSetting>* aPrefs) -{ - Preferences::GetPreferences(aPrefs); - return IPC_OK(); -} - -mozilla::ipc::IPCResult ContentParent::RecvGetGfxVars(InfallibleTArray<GfxVarUpdate>* aVars) { // Ensure gfxVars is initialized (for xpcshell tests). gfxVars::Initialize(); *aVars = gfxVars::FetchNonDefaultVars(); // Now that content has initialized gfxVars, we can start listening for @@ -2543,128 +2675,16 @@ ContentParent::RecvInitBackground(Endpoi { if (!BackgroundParent::Alloc(this, Move(aEndpoint))) { return IPC_FAIL(this, "BackgroundParent::Alloc failed"); } return IPC_OK(); } -mozilla::ipc::IPCResult -ContentParent::RecvGetProcessAttributes(ContentParentId* aCpId, - bool* aIsForBrowser) -{ - *aCpId = mChildID; - *aIsForBrowser = mIsForBrowser; - - return IPC_OK(); -} - -mozilla::ipc::IPCResult -ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline, - bool* aIsConnected, - int32_t* aCaptivePortalState, - bool* aIsLangRTL, - bool* aHaveBidiKeyboards, - InfallibleTArray<nsString>* dictionaries, - ClipboardCapabilities* clipboardCaps, - DomainPolicyClone* domainPolicy, - StructuredCloneData* aInitialData, - InfallibleTArray<FontFamilyListEntry>* fontFamilies, - OptionalURIParams* aUserContentCSSURL, - nsTArray<LookAndFeelInt>* aLookAndFeelIntCache) -{ - Telemetry::Accumulate(Telemetry::CONTENT_PROCESS_LAUNCH_TIME_MS, - static_cast<uint32_t>((TimeStamp::Now() - mLaunchTS) - .ToMilliseconds())); - - 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?"); - - *aCaptivePortalState = nsICaptivePortalService::UNKNOWN; - nsCOMPtr<nsICaptivePortalService> cps = do_GetService(NS_CAPTIVEPORTAL_CONTRACTID); - if (cps) { - cps->GetState(aCaptivePortalState); - } - - nsIBidiKeyboard* bidi = nsContentUtils::GetBidiKeyboard(); - - *aIsLangRTL = false; - *aHaveBidiKeyboards = false; - if (bidi) { - bidi->IsLangRTL(aIsLangRTL); - bidi->GetHaveBidiKeyboards(aHaveBidiKeyboards); - } - - nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID)); - MOZ_ASSERT(spellChecker, "No spell checker?"); - - spellChecker->GetDictionaryList(dictionaries); - - nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1")); - MOZ_ASSERT(clipboard, "No clipboard?"); - - rv = clipboard->SupportsSelectionClipboard(&clipboardCaps->supportsSelectionClipboard()); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - - rv = clipboard->SupportsFindClipboard(&clipboardCaps->supportsFindClipboard()); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - - // Let's copy the domain policy from the parent to the child (if it's active). - nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); - NS_ENSURE_TRUE(ssm, IPC_OK()); - ssm->CloneDomainPolicy(domainPolicy); - - if (nsFrameMessageManager* mm = nsFrameMessageManager::sParentProcessManager) { - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) { - return IPC_FAIL_NO_REASON(this); - } - JS::RootedValue init(jsapi.cx()); - nsresult result = mm->GetInitialProcessData(jsapi.cx(), &init); - if (NS_FAILED(result)) { - return IPC_FAIL_NO_REASON(this); - } - - ErrorResult rv; - aInitialData->Write(jsapi.cx(), init, rv); - if (NS_WARN_IF(rv.Failed())) { - 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); - *aLookAndFeelIntCache = LookAndFeel::GetIntCache(); - - // 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); - } - - nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); - if (obs) { - nsAutoString cpId; - cpId.AppendInt(static_cast<uint64_t>(this->ChildID())); - obs->NotifyObservers(static_cast<nsIObserver*>(this), "ipc:content-initializing", cpId.get()); - } - - return IPC_OK(); -} - mozilla::jsipc::PJavaScriptParent * ContentParent::AllocPJavaScriptParent() { MOZ_ASSERT(ManagedPJavaScriptParent().IsEmpty()); return nsIContentParent::AllocPJavaScriptParent(); } bool
--- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -741,34 +741,16 @@ private: /** * Get or create the corresponding content parent array to |aContentProcessType|. */ static nsTArray<ContentParent*>& GetOrCreatePool(const nsAString& aContentProcessType); virtual mozilla::ipc::IPCResult RecvInitBackground(Endpoint<mozilla::ipc::PBackgroundParent>&& aEndpoint) override; - virtual mozilla::ipc::IPCResult RecvGetProcessAttributes(ContentParentId* aCpId, - bool* aIsForBrowser) override; - - virtual mozilla::ipc::IPCResult - RecvGetXPCOMProcessAttributes(bool* aIsOffline, - bool* aIsConnected, - int32_t* aCaptivePortalState, - bool* aIsLangRTL, - bool* aHaveBidiKeyboards, - InfallibleTArray<nsString>* dictionaries, - ClipboardCapabilities* clipboardCaps, - DomainPolicyClone* domainPolicy, - StructuredCloneData* initialData, - InfallibleTArray<FontFamilyListEntry>* fontFamilies, - OptionalURIParams* aUserContentSheetURL, - nsTArray<LookAndFeelInt>* aLookAndFeelIntCache) override; - - mozilla::ipc::IPCResult RecvAddMemoryReport(const MemoryReport& aReport) override; mozilla::ipc::IPCResult RecvFinishMemoryReport(const uint32_t& aGeneration) override; virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*) override; virtual bool DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent*) override; @@ -893,17 +875,16 @@ private: virtual PWebBrowserPersistDocumentParent* AllocPWebBrowserPersistDocumentParent(PBrowserParent* aBrowser, const uint64_t& aOuterWindowID) override; virtual bool DeallocPWebBrowserPersistDocumentParent(PWebBrowserPersistDocumentParent* aActor) override; - virtual mozilla::ipc::IPCResult RecvReadPrefsArray(InfallibleTArray<PrefSetting>* aPrefs) override; virtual mozilla::ipc::IPCResult RecvGetGfxVars(InfallibleTArray<GfxVarUpdate>* aVars) override; virtual mozilla::ipc::IPCResult RecvReadFontList(InfallibleTArray<FontListEntry>* retValue) override; virtual mozilla::ipc::IPCResult RecvReadDataStorageArray(const nsString& aFilename, InfallibleTArray<DataStorageItem>* aValues) override; virtual mozilla::ipc::IPCResult RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions) override;
new file mode 100644 --- /dev/null +++ b/dom/ipc/ContentPrefs.cpp @@ -0,0 +1,276 @@ +/* -*- 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 "ContentPrefs.h" + +const char* mozilla::dom::ContentPrefs::gInitPrefs[] = { + "accessibility.monoaudio.enable", + "accessibility.mouse_focuses_formcontrol", + "accessibility.tabfocus_applies_to_xul", + "app.update.channel", + "browser.dom.window.dump.enabled", + "browser.sessionhistory.max_entries", + "browser.sessionhistory.max_total_viewers", + "content.cors.disable", + "content.cors.no_private_data", + "content.notify.backoffcount", + "content.notify.interval", + "content.notify.ontimer", + "content.sink.enable_perf_mode", + "content.sink.event_probe_rate", + "content.sink.initial_perf_time", + "content.sink.interactive_deflect_count", + "content.sink.interactive_parse_time", + "content.sink.interactive_time", + "content.sink.pending_event_mode", + "content.sink.perf_deflect_count", + "content.sink.perf_parse_time", + "device.storage.prompt.testing", + "device.storage.writable.name", + "dom.allow_XUL_XBL_for_file", + "dom.allow_cut_copy", + "dom.enable_frame_timing", + "dom.enable_performance", + "dom.enable_resource_timing", + "dom.event.handling-user-input-time-limit", + "dom.event.touch.coalescing.enabled", + "dom.forms.autocomplete.experimental", + "dom.ipc.processPriorityManager.backgroundGracePeriodMS", + "dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS", + "dom.max_chrome_script_run_time", + "dom.max_script_run_time", + "dom.performance.enable_notify_performance_timing", + "dom.performance.enable_user_timing_logging", + "dom.storage.testing", + "dom.url.encode_decode_hash", + "dom.url.getters_decode_hash", + "dom.use_watchdog", + "dom.vibrator.enabled", + "dom.vibrator.max_vibrate_list_len", + "dom.vibrator.max_vibrate_ms", + "focusmanager.testmode", + "font.size.inflation.disabledInMasterProcess", + "font.size.inflation.emPerLine", + "font.size.inflation.forceEnabled", + "font.size.inflation.lineThreshold", + "font.size.inflation.mappingIntercept", + "font.size.inflation.maxRatio", + "font.size.inflation.minTwips", + "full-screen-api.allow-trusted-requests-only", + "full-screen-api.enabled", + "full-screen-api.unprefix.enabled", + "gfx.font_rendering.opentype_svg.enabled", + "hangmonitor.timeout", + "html5.flushtimer.initialdelay", + "html5.flushtimer.subsequentdelay", + "html5.offmainthread", + "intl.charset.fallback.tld", + "intl.ime.hack.on_ime_unaware_apps.fire_key_events_for_composition", + "javascript.enabled", + "javascript.options.asmjs", + "javascript.options.asyncstack", + "javascript.options.baselinejit", + "javascript.options.baselinejit.threshold", + "javascript.options.baselinejit.unsafe_eager_compilation", + "javascript.options.discardSystemSource", + "javascript.options.dump_stack_on_debuggee_would_run", + "javascript.options.gczeal", + "javascript.options.gczeal.frequency", + "javascript.options.ion", + "javascript.options.ion.offthread_compilation", + "javascript.options.ion.threshold", + "javascript.options.ion.unsafe_eager_compilation", + "javascript.options.jit.full_debug_checks", + "javascript.options.native_regexp", + "javascript.options.parallel_parsing", + "javascript.options.shared_memory", + "javascript.options.strict", + "javascript.options.strict.debug", + "javascript.options.throw_on_asmjs_validation_failure", + "javascript.options.throw_on_debuggee_would_run", + "javascript.options.wasm", + "javascript.options.wasm_baselinejit", + "javascript.options.werror", + "javascript.use_us_english_locale", + "jsloader.reuseGlobal", + "layout.css.all-shorthand.enabled", + "layout.css.background-blend-mode.enabled", + "layout.css.background-clip-text.enabled", + "layout.css.box-decoration-break.enabled", + "layout.css.color-adjust.enabled", + "layout.css.contain.enabled", + "layout.css.control-characters.visible", + "layout.css.display-flow-root.enabled", + "layout.css.expensive-style-struct-assertions.enabled", + "layout.css.float-logical-values.enabled", + "layout.css.font-variations.enabled", + "layout.css.grid.enabled", + "layout.css.image-orientation.enabled", + "layout.css.initial-letter.enabled", + "layout.css.isolation.enabled", + "layout.css.mix-blend-mode.enabled", + "layout.css.object-fit-and-position.enabled", + "layout.css.osx-font-smoothing.enabled", + "layout.css.overflow-clip-box.enabled", + "layout.css.prefixes.animations", + "layout.css.prefixes.border-image", + "layout.css.prefixes.box-sizing", + "layout.css.prefixes.device-pixel-ratio-webkit", + "layout.css.prefixes.font-features", + "layout.css.prefixes.gradients", + "layout.css.prefixes.transforms", + "layout.css.prefixes.transitions", + "layout.css.prefixes.webkit", + "layout.css.scope-pseudo.enabled", + "layout.css.scroll-behavior.property-enabled", + "layout.css.scroll-snap.enabled", + "layout.css.shape-outside.enabled", + "layout.css.text-align-unsafe-value.enabled", + "layout.css.text-combine-upright-digits.enabled", + "layout.css.text-combine-upright.enabled", + "layout.css.touch_action.enabled", + "layout.css.unprefixing-service.enabled", + "layout.css.unprefixing-service.globally-whitelisted", + "layout.css.unprefixing-service.include-test-domains", + "layout.css.variables.enabled", + "layout.css.visited_links_enabled", + "layout.idle_period.required_quiescent_frames", + "layout.idle_period.time_limit", + "layout.interruptible-reflow.enabled", + "mathml.disabled", + "media.apple.forcevda", + "media.clearkey.persistent-license.enabled", + "media.cubeb_latency_msg_frames", + "media.cubeb_latency_playback_ms", + "media.decoder-doctor.wmf-disabled-is-failure", + "media.decoder.fuzzing.dont-delay-inputexhausted", + "media.decoder.fuzzing.enabled", + "media.decoder.fuzzing.video-output-minimum-interval-ms", + "media.decoder.limit", + "media.decoder.recycle.enabled", + "media.dormant-on-pause-timeout-ms", + "media.eme.audio.blank", + "media.eme.enabled", + "media.eme.video.blank", + "media.ffmpeg.enabled", + "media.ffvpx.enabled", + "media.flac.enabled", + "media.forcestereo.enabled", + "media.gmp.async-shutdown-timeout", + "media.gmp.decoder.aac", + "media.gmp.decoder.enabled", + "media.gmp.decoder.h264", + "media.gmp.insecure.allow", + "media.gpu-process-decoder", + "media.libavcodec.allow-obsolete", + "media.num-decode-threads", + "media.ogg.enabled", + "media.ogg.flac.enabled", + "media.resampling.enabled", + "media.resampling.rate", + "media.ruin-av-sync.enabled", + "media.rust.test_mode", + "media.suspend-bkgnd-video.delay-ms", + "media.suspend-bkgnd-video.enabled", + "media.use-blank-decoder", + "media.video_stats.enabled", + "media.volume_scale", + "media.webspeech.recognition.enable", + "media.webspeech.recognition.force_enable", + "media.webspeech.synth.force_global_queue", + "media.webspeech.test.enable", + "media.webspeech.test.fake_fsm_events", + "media.webspeech.test.fake_recognition_service", + "media.wmf.allow-unsupported-resolutions", + "media.wmf.decoder.thread-count", + "media.wmf.enabled", + "media.wmf.skip-blacklist", + "media.wmf.vp9.enabled", + "memory.free_dirty_pages", + "memory.low_commit_space_threshold_mb", + "memory.low_memory_notification_interval_ms", + "memory.low_physical_memory_threshold_mb", + "memory.low_virtual_mem_threshold_mb", + "network.IDN.blacklist_chars", + "network.IDN.restriction_profile", + "network.IDN.use_whitelist", + "network.IDN_show_punycode", + "network.buffer.cache.count", + "network.buffer.cache.size", + "network.captive-portal-service.enabled", + "network.cookie.cookieBehavior", + "network.cookie.lifetimePolicy", + "network.dns.disablePrefetch", + "network.dns.disablePrefetchFromHTTPS", + "network.jar.block-remote-files", + "network.loadinfo.skip_type_assertion", + "network.notify.changed", + "network.offline-mirrors-connectivity", + "network.protocol-handler.external.jar", + "network.proxy.type", + "network.security.ports.banned", + "network.security.ports.banned.override", + "network.standard-url.enable-rust", + "network.standard-url.max-length", + "network.sts.max_time_for_events_between_two_polls", + "network.sts.max_time_for_pr_close_during_shutdown", + "network.tcp.keepalive.enabled", + "network.tcp.keepalive.idle_time", + "network.tcp.keepalive.probe_count", + "network.tcp.keepalive.retry_interval", + "network.tcp.sendbuffer", + "nglayout.debug.invalidation", + "privacy.donottrackheader.enabled", + "privacy.firstparty.isolate", + "privacy.firstparty.isolate.restrict_opener_access", + "privacy.resistFingerprinting", + "security.data_uri.inherit_security_context", + "security.fileuri.strict_origin_policy", + "security.sandbox.content.level", + "security.sandbox.content.tempDirSuffix", + "security.sandbox.logging.enabled", + "security.sandbox.mac.track.violations", + "security.sandbox.windows.log", + "security.sandbox.windows.log.stackTraceDepth", + "shutdown.watchdog.timeoutSecs", + "signed.applets.codebase_principal_support", + "svg.disabled", + "svg.display-lists.hit-testing.enabled", + "svg.display-lists.painting.enabled", + "svg.new-getBBox.enabled", + "svg.paint-order.enabled", + "svg.path-caching.enabled", + "svg.transform-box.enabled", + "toolkit.asyncshutdown.crash_timeout", + "toolkit.asyncshutdown.log", + "toolkit.osfile.log", + "toolkit.osfile.log.redirect", + "toolkit.telemetry.enabled", + "toolkit.telemetry.idleTimeout", + "toolkit.telemetry.initDelay", + "toolkit.telemetry.log.dump", + "toolkit.telemetry.log.level", + "toolkit.telemetry.minSubsessionLength", + "toolkit.telemetry.scheduler.idleTickInterval", + "toolkit.telemetry.scheduler.tickInterval", + "toolkit.telemetry.unified", + "ui.key.menuAccessKeyFocuses", + "ui.popup.disable_autohide", + "ui.use_activity_cursor", + "view_source.editor.external"}; + +const char** mozilla::dom::ContentPrefs::GetContentPrefs(size_t* aCount) +{ + *aCount = ArrayLength(ContentPrefs::gInitPrefs); + return gInitPrefs; +} + +const char* mozilla::dom::ContentPrefs::GetContentPref(size_t aIndex) +{ + MOZ_ASSERT(aIndex < ArrayLength(ContentPrefs::gInitPrefs)); + return gInitPrefs[aIndex]; +} +
new file mode 100644 --- /dev/null +++ b/dom/ipc/ContentPrefs.h @@ -0,0 +1,25 @@ +/* -*- 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_ContentPrefs_h +#define mozilla_dom_ContentPrefs_h + +namespace mozilla { +namespace dom { + +class ContentPrefs { +public: + static const char** GetContentPrefs(size_t* aCount); + static const char* GetContentPref(size_t aIndex); + +private: + static const char* gInitPrefs[]; +}; + +} +} + +#endif
--- a/dom/ipc/ContentProcess.cpp +++ b/dom/ipc/ContentProcess.cpp @@ -2,16 +2,17 @@ /* 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/ipc/IOThreadChild.h" #include "ContentProcess.h" +#include "ContentPrefs.h" #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) #include <stdlib.h> #endif #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX) #include "mozilla/Preferences.h" #include "nsAppDirectoryServiceDefs.h" @@ -98,60 +99,157 @@ SetUpSandboxEnvironment() if (NS_WARN_IF(NS_FAILED(rv))) { return; } SetTmpEnvironmentVariable(sandboxedContentTemp); } #endif -void -ContentProcess::SetAppDir(const nsACString& aPath) +bool +ContentProcess::Init(int aArgc, char* aArgv[]) { - mXREEmbed.SetAppDir(aPath); -} + // If passed in grab the application path for xpcom init + bool foundAppdir = false; + bool foundChildID = false; + bool foundIsForBrowser = false; + bool foundIntPrefs = false; + bool foundBoolPrefs = false; + bool foundStringPrefs = false; + + uint64_t childID; + bool isForBrowser; #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) -void -ContentProcess::SetProfile(const nsACString& aProfile) -{ - bool flag; - nsresult rv = - XRE_GetFileFromPath(aProfile.BeginReading(), getter_AddRefs(mProfileDir)); - if (NS_FAILED(rv) || - NS_FAILED(mProfileDir->Exists(&flag)) || !flag) { - NS_WARNING("Invalid profile directory passed to content process."); - mProfileDir = nullptr; - } -} + // If passed in grab the profile path for sandboxing + bool foundProfile = false; + nsCOMPtr<nsIFile> profileDir; #endif -bool -ContentProcess::Init() -{ - mContent.Init(IOThreadChild::message_loop(), - ParentPid(), - IOThreadChild::channel()); - mXREEmbed.Start(); - mContent.InitXPCOM(); - mContent.InitGraphicsDeviceData(); + InfallibleTArray<PrefSetting> prefsArray; + for (int idx = aArgc; idx > 0; idx--) { + if (!aArgv[idx]) { + continue; + } + if (!strcmp(aArgv[idx], "-appdir")) { + MOZ_ASSERT(!foundAppdir); + if (foundAppdir) { + continue; + } + nsCString appDir; + appDir.Assign(nsDependentCString(aArgv[idx+1])); + mXREEmbed.SetAppDir(appDir); + foundAppdir = true; + } else if (!strcmp(aArgv[idx], "-childID")) { + MOZ_ASSERT(!foundChildID); + if (foundChildID) { + continue; + } + if (idx + 1 < aArgc) { + childID = strtoull(aArgv[idx + 1], nullptr, 10); + foundChildID = true; + } + } else if (!strcmp(aArgv[idx], "-isForBrowser") || !strcmp(aArgv[idx], "-notForBrowser")) { + MOZ_ASSERT(!foundIsForBrowser); + if (foundIsForBrowser) { + continue; + } + isForBrowser = strcmp(aArgv[idx], "-notForBrowser"); + foundIsForBrowser = true; + } else if (!strcmp(aArgv[idx], "-intPrefs")) { + SET_PREF_PHASE(BEGIN_INIT_PREFS); + char* str = aArgv[idx + 1]; + while (*str) { + int32_t index = strtol(str, &str, 10); + str++; + MaybePrefValue value(PrefValue(static_cast<int32_t>(strtol(str, &str, 10)))); + str++; + PrefSetting pref(nsCString(ContentPrefs::GetContentPref(index)), value, MaybePrefValue()); + prefsArray.AppendElement(pref); + } + SET_PREF_PHASE(END_INIT_PREFS); + foundIntPrefs = true; + } else if (!strcmp(aArgv[idx], "-boolPrefs")) { + SET_PREF_PHASE(BEGIN_INIT_PREFS); + char* str = aArgv[idx + 1]; + while (*str) { + int32_t index = strtol(str, &str, 10); + str++; + MaybePrefValue value(PrefValue(!!strtol(str, &str, 10))); + str++; + PrefSetting pref(nsCString(ContentPrefs::GetContentPref(index)), value, MaybePrefValue()); + prefsArray.AppendElement(pref); + } + SET_PREF_PHASE(END_INIT_PREFS); + foundBoolPrefs = true; + } else if (!strcmp(aArgv[idx], "-stringPrefs")) { + SET_PREF_PHASE(BEGIN_INIT_PREFS); + char* str = aArgv[idx + 1]; + while (*str) { + int32_t index = strtol(str, &str, 10); + str++; + int32_t length = strtol(str, &str, 10); + str++; + MaybePrefValue value(PrefValue(nsCString(str, length))); + PrefSetting pref(nsCString(ContentPrefs::GetContentPref(index)), value, MaybePrefValue()); + prefsArray.AppendElement(pref); + str += length + 1; + } + SET_PREF_PHASE(END_INIT_PREFS); + foundStringPrefs = true; + } + +#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) + else if (!strcmp(aArgv[idx], "-profile")) { + MOZ_ASSERT(!foundProfile); + if (foundProfile) { + continue; + } + bool flag; + nsresult rv = XRE_GetFileFromPath(aArgv[idx+1], getter_AddRefs(profileDir)); + if (NS_FAILED(rv) || + NS_FAILED(profileDir->Exists(&flag)) || !flag) { + NS_WARNING("Invalid profile directory passed to content process."); + profileDir = nullptr; + } + foundProfile = true; + } +#endif /* XP_MACOSX && MOZ_CONTENT_SANDBOX */ + + bool allFound = foundAppdir && foundChildID && foundIsForBrowser && foundIntPrefs && foundBoolPrefs && foundStringPrefs; + +#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) + allFound &= foundProfile; +#endif + + if (allFound) { + break; + } + } + Preferences::SetInitPreferences(&prefsArray); + mContent.Init(IOThreadChild::message_loop(), + ParentPid(), + IOThreadChild::channel(), + childID, + isForBrowser); + mXREEmbed.Start(); #if (defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX) - mContent.SetProfileDir(mProfileDir); + mContent.SetProfileDir(profileDir); #endif #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX) - SetUpSandboxEnvironment(); + SetUpSandboxEnvironment(); #endif - return true; + return true; } // Note: CleanUp() never gets called in non-debug builds because we exit early // in ContentChild::ActorDestroy(). void ContentProcess::CleanUp() { - mXREEmbed.Stop(); + mXREEmbed.Stop(); } } // namespace dom } // namespace mozilla
--- a/dom/ipc/ContentProcess.h +++ b/dom/ipc/ContentProcess.h @@ -29,33 +29,23 @@ class ContentProcess : public mozilla::i public: explicit ContentProcess(ProcessId aParentPid) : ProcessChild(aParentPid) { } ~ContentProcess() { } - virtual bool Init() override; + virtual bool Init(int aArgc, char* aArgv[]) override; virtual void CleanUp() override; - void SetAppDir(const nsACString& aPath); - -#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) - void SetProfile(const nsACString& aProfile); -#endif - private: ContentChild mContent; mozilla::ipc::ScopedXREEmbed mXREEmbed; -#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) - nsCOMPtr<nsIFile> mProfileDir; -#endif - #if defined(XP_WIN) // This object initializes and configures COM. mozilla::mscom::MainThreadRuntime mCOMRuntime; #endif DISALLOW_EVIL_CONSTRUCTORS(ContentProcess); };
--- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -329,16 +329,32 @@ struct GMPAPITags struct GMPCapabilityData { nsCString name; nsCString version; GMPAPITags[] capabilities; }; +struct XPCOMInitData +{ + bool isOffline; + bool isConnected; + int32_t captivePortalState; + bool isLangRTL; + bool haveBidiKeyboards; + nsString[] dictionaries; + ClipboardCapabilities clipboardCaps; + DomainPolicyClone domainPolicy; + /* used on MacOSX only */ + FontFamilyListEntry[] fontFamilies; + OptionalURIParams userContentSheetURL; + PrefSetting[] prefs; +}; + struct GfxInfoFeatureStatus { int32_t feature; int32_t status; nsCString failureId; }; /** @@ -522,16 +538,18 @@ child: */ async InitServiceWorkers(ServiceWorkerConfiguration aConfig); /** * Send BlobURLRegistrationData to child process. */ async InitBlobURLs(BlobURLRegistrationData[] registrations); + async SetXPCOMProcessAttributes(XPCOMInitData xpcomInit, StructuredCloneData initialData, LookAndFeelInt[] lookAndFeelIntCache); + // Notify child that last-pb-context-exited notification was observed async LastPrivateDocShellDestroyed(); async FilePathUpdate(nsString storageType, nsString storageName, nsString filepath, nsCString reasons); async NotifyProcessPriorityChanged(ProcessPriority priority); async MinimizeMemoryUsage(); @@ -645,40 +663,16 @@ child: async BlobURLUnregistration(nsCString aURI); async GMPsChanged(GMPCapabilityData[] capabilities); parent: async InitBackground(Endpoint<PBackgroundParent> aEndpoint); - /** - * Tell the content process some attributes of itself. This is - * among the first information queried by content processes after - * startup. (The message is sync to allow the content process to - * control when it receives the information.) - * - * |id| is a unique ID among all subprocesses. When - * |isForBrowser|, we're loading <browser> or <xul:browser remote>. - * - * Keep the return values in sync with PBrowser()! - */ - sync GetProcessAttributes() - returns (ContentParentId cpId, bool isForBrowser); - sync GetXPCOMProcessAttributes() - returns (bool isOffline, bool isConnected, int32_t captivePortalState, - bool isLangRTL, - bool haveBidiKeyboards, nsString[] dictionaries, - ClipboardCapabilities clipboardCaps, - DomainPolicyClone domainPolicy, - StructuredCloneData initialData, - FontFamilyListEntry[] fontFamilies /* used on MacOSX only */, - OptionalURIParams userContentSheetURL, - LookAndFeelInt[] lookAndFeelIntCache); - sync CreateChildProcess(IPCTabContext context, ProcessPriority priority, TabId openerTabId) returns (ContentParentId cpId, bool isForBrowser, TabId tabId); sync BridgeToChildProcess(ContentParentId cpId) returns (Endpoint<PContentBridgeParent> endpoint); async CreateGMPService(); @@ -812,17 +806,16 @@ parent: async StartVisitedQuery(URIParams uri); async VisitURI(URIParams uri, OptionalURIParams referrer, uint32_t flags); async SetURITitle(URIParams uri, nsString title); async LoadURIExternal(URIParams uri, PBrowser windowContext); async ExtProtocolChannelConnectParent(uint32_t registrarId); // PrefService message - sync ReadPrefsArray() returns (PrefSetting[] prefs) verify; sync GetGfxVars() returns (GfxVarUpdate[] vars); sync ReadFontList() returns (FontListEntry[] retValue); sync ReadDataStorageArray(nsString aFilename) returns (DataStorageItem[] retValue); sync SyncMessage(nsString aMessage, ClonedMessageData aData,
--- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -114,16 +114,18 @@ #include "FrameLayerBuilder.h" #include "VRManagerChild.h" #include "nsICommandParams.h" #include "nsISHistory.h" #include "nsQueryObject.h" #include "GroupedSHistory.h" #include "nsIHttpChannel.h" #include "mozilla/dom/DocGroup.h" +#include "nsISupportsPrimitives.h" +#include "mozilla/Telemetry.h" #ifdef NS_PRINTING #include "nsIPrintSession.h" #include "nsIPrintSettings.h" #include "nsIPrintSettingsService.h" #include "nsIWebBrowserPrint.h" #endif
--- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -15,16 +15,17 @@ EXPORTS.mozilla.dom.ipc += [ 'StructuredCloneData.h', ] EXPORTS.mozilla.dom += [ 'ContentBridgeChild.h', 'ContentBridgeParent.h', 'ContentChild.h', 'ContentParent.h', + 'ContentPrefs.h', 'ContentProcess.h', 'ContentProcessManager.h', 'CPOWManagerGetter.h', 'CrashReporterChild.h', 'CrashReporterParent.h', 'FilePickerParent.h', 'MemoryReportRequest.h', 'nsIContentChild.h', @@ -45,16 +46,17 @@ EXPORTS.mozilla += [ 'ProcessPriorityManager.h', ] UNIFIED_SOURCES += [ 'ColorPickerParent.cpp', 'ContentBridgeChild.cpp', 'ContentBridgeParent.cpp', 'ContentParent.cpp', + 'ContentPrefs.cpp', 'ContentProcess.cpp', 'ContentProcessManager.cpp', 'CrashReporterParent.cpp', 'DatePickerParent.cpp', 'FilePickerParent.cpp', 'MemoryReportRequest.cpp', 'nsIContentChild.cpp', 'nsIContentParent.cpp',
--- a/dom/media/gmp/GMPProcessChild.cpp +++ b/dom/media/gmp/GMPProcessChild.cpp @@ -20,17 +20,17 @@ GMPProcessChild::GMPProcessChild(Process { } GMPProcessChild::~GMPProcessChild() { } bool -GMPProcessChild::Init() +GMPProcessChild::Init(int aArgc, char* aArgv[]) { nsAutoString pluginFilename; #if defined(OS_POSIX) // NB: need to be very careful in ensuring that the first arg // (after the binary name) here is indeed the plugin module path. // Keep in sync with dom/plugins/PluginModuleParent. std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
--- a/dom/media/gmp/GMPProcessChild.h +++ b/dom/media/gmp/GMPProcessChild.h @@ -17,17 +17,17 @@ class GMPLoader; class GMPProcessChild final : public mozilla::ipc::ProcessChild { protected: typedef mozilla::ipc::ProcessChild ProcessChild; public: explicit GMPProcessChild(ProcessId aParentPid); ~GMPProcessChild(); - bool Init() override; + bool Init(int aArgc, char* aArgv[]) override; void CleanUp() override; private: GMPChild mPlugin; DISALLOW_COPY_AND_ASSIGN(GMPProcessChild); }; } // namespace gmp
--- a/dom/plugins/ipc/PluginProcessChild.cpp +++ b/dom/plugins/ipc/PluginProcessChild.cpp @@ -35,17 +35,17 @@ using mozilla::ipc::IOThreadChild; #include <algorithm> #endif namespace mozilla { namespace plugins { bool -PluginProcessChild::Init() +PluginProcessChild::Init(int aArgc, char* aArgv[]) { nsDebugImpl::SetMultiprocessMode("NPAPI"); #if defined(XP_MACOSX) // Remove the trigger for "dyld interposing" that we added in // GeckoChildProcessHost::PerformAsyncLaunchInternal(), in the host // process just before we were launched. Dyld interposing will still // happen in our process (the plugin child process). But we don't want
--- a/dom/plugins/ipc/PluginProcessChild.h +++ b/dom/plugins/ipc/PluginProcessChild.h @@ -25,17 +25,17 @@ protected: public: explicit PluginProcessChild(ProcessId aParentPid) : ProcessChild(aParentPid), mPlugin(true) { } virtual ~PluginProcessChild() { } - virtual bool Init() override; + virtual bool Init(int aArgc, char* aArgv[]) override; virtual void CleanUp() override; protected: static PluginProcessChild* current() { return static_cast<PluginProcessChild*>(ProcessChild::current()); } private:
--- a/gfx/ipc/GPUProcessImpl.cpp +++ b/gfx/ipc/GPUProcessImpl.cpp @@ -17,17 +17,17 @@ GPUProcessImpl::GPUProcessImpl(ProcessId { } GPUProcessImpl::~GPUProcessImpl() { } bool -GPUProcessImpl::Init() +GPUProcessImpl::Init(int aArgc, char* aArgv[]) { return mGPU.Init(ParentPid(), IOThreadChild::message_loop(), IOThreadChild::channel()); } void GPUProcessImpl::CleanUp()
--- a/gfx/ipc/GPUProcessImpl.h +++ b/gfx/ipc/GPUProcessImpl.h @@ -19,17 +19,17 @@ namespace gfx { // This class owns the subprocess instance of a PGPU - which in this case, // is a GPUParent. It is instantiated as a singleton in XRE_InitChildProcess. class GPUProcessImpl final : public ipc::ProcessChild { public: explicit GPUProcessImpl(ProcessId aParentPid); ~GPUProcessImpl(); - bool Init() override; + bool Init(int aArgc, char* aArgv[]) override; void CleanUp() override; private: DISALLOW_COPY_AND_ASSIGN(GPUProcessImpl); GPUParent mGPU; #if defined(XP_WIN)
--- a/ipc/glue/ProcessChild.h +++ b/ipc/glue/ProcessChild.h @@ -22,17 +22,17 @@ namespace ipc { class ProcessChild : public ChildProcess { protected: typedef base::ProcessId ProcessId; public: explicit ProcessChild(ProcessId aParentPid); virtual ~ProcessChild(); - virtual bool Init() = 0; + virtual bool Init(int aArgc, char* aArgv[]) = 0; virtual void CleanUp() { } static MessageLoop* message_loop() { return gProcessChild->mUILoop; } /**
--- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -1,16 +1,16 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/MemoryReporting.h" -#include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/PContent.h" #include "mozilla/ArrayUtils.h" #include "mozilla/Attributes.h" #include "mozilla/HashFunctions.h" #include "mozilla/UniquePtrExtensions.h" #include "nsXULAppAPI.h" @@ -541,36 +541,42 @@ NS_INTERFACE_MAP_BEGIN(Preferences) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_END /* * nsIPrefService Implementation */ +InfallibleTArray<Preferences::PrefSetting>* gInitPrefs; + +/*static*/ +void +Preferences::SetInitPreferences(nsTArray<PrefSetting>* aPrefs) { + gInitPrefs = new InfallibleTArray<PrefSetting>(mozilla::Move(*aPrefs)); +} + nsresult Preferences::Init() { nsresult rv; PREF_SetDirtyCallback(&DirtyCallback); PREF_Init(); rv = pref_InitInitialObjects(); NS_ENSURE_SUCCESS(rv, rv); - using mozilla::dom::ContentChild; if (XRE_IsContentProcess()) { - InfallibleTArray<PrefSetting> prefs; - ContentChild::GetSingleton()->SendReadPrefsArray(&prefs); - - // Store the array - for (uint32_t i = 0; i < prefs.Length(); ++i) { - pref_SetPref(prefs[i]); + MOZ_ASSERT(gInitPrefs); + for (unsigned int i = 0; i < gInitPrefs->Length(); i++) { + Preferences::SetPreference(gInitPrefs->ElementAt(i)); } + delete gInitPrefs; + gInitPrefs = nullptr; return NS_OK; } nsXPIDLCString lockFileName; /* * The following is a small hack which will allow us to only load the library * which supports the netscape.cfg file if the preference is defined. We * test for the existence of the pref, set in the all.js (mozilla) or @@ -775,16 +781,24 @@ Preferences::GetPreferences(InfallibleTA continue; } dom::PrefSetting *pref = aPrefs->AppendElement(); pref_GetPrefFromEntry(entry, pref); } } +#ifdef DEBUG +void +Preferences::SetInitPhase(pref_initPhase phase) +{ + pref_SetInitPhase(phase); +} +#endif + NS_IMETHODIMP Preferences::GetBranch(const char *aPrefRoot, nsIPrefBranch **_retval) { nsresult rv; if ((nullptr != aPrefRoot) && (*aPrefRoot != '\0')) { // TODO: - cache this stuff and allow consumers to share branches (hold weak references I think) RefPtr<nsPrefBranch> prefBranch = new nsPrefBranch(aPrefRoot, false);
--- a/modules/libpref/Preferences.h +++ b/modules/libpref/Preferences.h @@ -23,16 +23,30 @@ class nsIFile; class nsAdoptingString; class nsAdoptingCString; #ifndef have_PrefChangedFunc_typedef typedef void (*PrefChangedFunc)(const char *, void *); #define have_PrefChangedFunc_typedef #endif +#ifdef DEBUG +enum pref_initPhase { + START, + BEGIN_INIT_PREFS, + END_INIT_PREFS, + BEGIN_ALL_PREFS, + END_ALL_PREFS +}; + +#define SET_PREF_PHASE(p) Preferences::SetInitPhase(p) +#else +#define SET_PREF_PHASE(p) do { } while (0) +#endif + namespace mozilla { namespace dom { class PrefSetting; } // namespace dom class Preferences final : public nsIPrefService, public nsIObserver, @@ -361,16 +375,22 @@ public: */ static int32_t GetDefaultType(const char* aPref); // Used to synchronise preferences between chrome and content processes. static void GetPreferences(InfallibleTArray<PrefSetting>* aPrefs); static void GetPreference(PrefSetting* aPref); static void SetPreference(const PrefSetting& aPref); + static void SetInitPreferences(nsTArray<PrefSetting>* aPrefs); + +#ifdef DEBUG + static void SetInitPhase(pref_initPhase phase); +#endif + static int64_t SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeOf); static void DirtyCallback(); protected: virtual ~Preferences(); nsresult NotifyServiceObservers(const char *aSubject);
--- a/modules/libpref/prefapi.cpp +++ b/modules/libpref/prefapi.cpp @@ -24,16 +24,17 @@ #include "plstr.h" #include "PLDHashTable.h" #include "plbase64.h" #include "mozilla/Logging.h" #include "prprf.h" #include "mozilla/MemoryReporting.h" #include "mozilla/dom/PContent.h" +#include "mozilla/dom/ContentPrefs.h" #include "nsQuickSort.h" #include "nsString.h" #include "nsPrintfCString.h" #include "prlink.h" using namespace mozilla; static void @@ -731,23 +732,58 @@ static PrefTypeFlags pref_SetValue(PrefV MOZ_ASSERT(newValue.stringVal); existingValue->stringVal = newValue.stringVal ? PL_strdup(newValue.stringVal) : nullptr; } else { *existingValue = newValue; } return flags; } +#ifdef DEBUG +static pref_initPhase gPhase = START; + +void +pref_SetInitPhase(pref_initPhase phase) +{ + gPhase = phase; +} + +struct StringComparator +{ + const char* mKey; + explicit StringComparator(const char* aKey) : mKey(aKey) {} + int operator()(const char* string) const { + return strcmp(mKey, string); + } +}; + +bool +inInitArray(const char* key) +{ + size_t prefsLen; + size_t found; + const char** list = mozilla::dom::ContentPrefs::GetContentPrefs(&prefsLen); + return BinarySearchIf(list, 0, prefsLen, + StringComparator(key), &found); +} +#endif PrefHashEntry* pref_HashTableLookup(const char *key) { #ifndef MOZ_B2G MOZ_ASSERT(NS_IsMainThread()); #endif - + MOZ_ASSERT((!XRE_IsContentProcess() || gPhase != START), + "pref access before commandline prefs set"); + /* If you're hitting this assertion, you've added a pref access to start up. + * Consider moving it later or add it to the whitelist in ContentPrefs.cpp + * and get review from a DOM peer + */ + MOZ_ASSERT((!XRE_IsContentProcess() || gPhase > END_INIT_PREFS || inInitArray(key)), + "accessing non-init pref before the rest of the prefs are sent"); return static_cast<PrefHashEntry*>(gHashTable->Search(key)); } nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, uint32_t flags) { #ifndef MOZ_B2G MOZ_ASSERT(NS_IsMainThread()); #endif
--- a/modules/libpref/prefapi_private_data.h +++ b/modules/libpref/prefapi_private_data.h @@ -5,31 +5,37 @@ /* Data shared between prefapi.c and nsPref.cpp */ #ifndef prefapi_private_data_h #define prefapi_private_data_h #include "mozilla/MemoryReporting.h" #include "mozilla/UniquePtr.h" +#include "Preferences.h" extern PLDHashTable* gHashTable; namespace mozilla { namespace dom { class PrefSetting; } // namespace dom } // namespace mozilla mozilla::UniquePtr<char*[]> pref_savePrefs(PLDHashTable* aTable, uint32_t* aPrefCount); nsresult pref_SetPref(const mozilla::dom::PrefSetting& aPref); +#ifdef DEBUG +void +pref_SetInitPhase(pref_initPhase phase); +#endif + int pref_CompareStrings(const void *v1, const void *v2, void* unused); PrefHashEntry* pref_HashTableLookup(const char *key); bool pref_EntryHasAdvisablySizedValues(PrefHashEntry* aHashEntry); void pref_GetPrefFromEntry(PrefHashEntry *aHashEntry, mozilla::dom::PrefSetting* aPref);
--- a/toolkit/xre/nsEmbedFunctions.cpp +++ b/toolkit/xre/nsEmbedFunctions.cpp @@ -620,59 +620,18 @@ XRE_InitChildProcess(int aArgc, case GeckoProcessType_Default: MOZ_CRASH("This makes no sense"); break; case GeckoProcessType_Plugin: process = new PluginProcessChild(parentPID); break; - case GeckoProcessType_Content: { - process = new ContentProcess(parentPID); - // If passed in grab the application path for xpcom init - bool foundAppdir = false; - -#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) - // If passed in grab the profile path for sandboxing - bool foundProfile = false; -#endif - - for (int idx = aArgc; idx > 0; idx--) { - if (aArgv[idx] && !strcmp(aArgv[idx], "-appdir")) { - MOZ_ASSERT(!foundAppdir); - if (foundAppdir) { - continue; - } - nsCString appDir; - appDir.Assign(nsDependentCString(aArgv[idx+1])); - static_cast<ContentProcess*>(process.get())->SetAppDir(appDir); - foundAppdir = true; - } - -#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) - if (aArgv[idx] && !strcmp(aArgv[idx], "-profile")) { - MOZ_ASSERT(!foundProfile); - if (foundProfile) { - continue; - } - nsCString profile; - profile.Assign(nsDependentCString(aArgv[idx+1])); - static_cast<ContentProcess*>(process.get())->SetProfile(profile); - foundProfile = true; - } - if (foundProfile && foundAppdir) { - break; - } -#else - if (foundAppdir) { - break; - } -#endif /* XP_MACOSX && MOZ_CONTENT_SANDBOX */ - } - } + case GeckoProcessType_Content: + process = new ContentProcess(parentPID); break; case GeckoProcessType_IPDLUnitTest: #ifdef MOZ_IPDL_TESTS process = new IPDLUnitTestProcessChild(parentPID); #else MOZ_CRASH("rebuild with --enable-ipdl-tests"); #endif @@ -685,17 +644,17 @@ XRE_InitChildProcess(int aArgc, case GeckoProcessType_GPU: process = new gfx::GPUProcessImpl(parentPID); break; default: MOZ_CRASH("Unknown main thread class"); } - if (!process->Init()) { + if (!process->Init(aArgc, aArgv)) { return NS_ERROR_FAILURE; } #ifdef MOZ_CRASHREPORTER #if defined(XP_WIN) || defined(XP_MACOSX) CrashReporter::InitChildProcessTmpDir(); #endif #endif