Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifdef MOZ_WIDGET_GTK
8 : #include <gtk/gtk.h>
9 : #endif
10 :
11 : #include "ContentChild.h"
12 :
13 : #include "GeckoProfiler.h"
14 : #include "TabChild.h"
15 : #include "HandlerServiceChild.h"
16 :
17 : #include "mozilla/Attributes.h"
18 : #include "mozilla/LookAndFeel.h"
19 : #include "mozilla/Preferences.h"
20 : #include "mozilla/ProcessHangMonitorIPC.h"
21 : #include "mozilla/Unused.h"
22 : #include "mozilla/devtools/HeapSnapshotTempFileHelperChild.h"
23 : #include "mozilla/docshell/OfflineCacheUpdateChild.h"
24 : #include "mozilla/dom/ContentBridgeChild.h"
25 : #include "mozilla/dom/ContentBridgeParent.h"
26 : #include "mozilla/dom/VideoDecoderManagerChild.h"
27 : #include "mozilla/dom/ContentParent.h"
28 : #include "mozilla/dom/DataTransfer.h"
29 : #include "mozilla/dom/DocGroup.h"
30 : #include "mozilla/dom/ExternalHelperAppChild.h"
31 : #include "mozilla/dom/FileCreatorHelper.h"
32 : #include "mozilla/dom/FlyWebPublishedServerIPC.h"
33 : #include "mozilla/dom/GetFilesHelper.h"
34 : #include "mozilla/dom/IPCBlobUtils.h"
35 : #include "mozilla/dom/MemoryReportRequest.h"
36 : #include "mozilla/dom/ProcessGlobal.h"
37 : #include "mozilla/dom/PushNotifier.h"
38 : #include "mozilla/dom/LocalStorage.h"
39 : #include "mozilla/dom/StorageIPC.h"
40 : #include "mozilla/dom/TabGroup.h"
41 : #include "mozilla/dom/workers/ServiceWorkerManager.h"
42 : #include "mozilla/dom/nsIContentChild.h"
43 : #include "mozilla/dom/URLClassifierChild.h"
44 : #include "mozilla/gfx/gfxVars.h"
45 : #include "mozilla/psm/PSMContentListener.h"
46 : #include "mozilla/hal_sandbox/PHalChild.h"
47 : #include "mozilla/ipc/BackgroundChild.h"
48 : #include "mozilla/ipc/FileDescriptorSetChild.h"
49 : #include "mozilla/ipc/FileDescriptorUtils.h"
50 : #include "mozilla/ipc/GeckoChildProcessHost.h"
51 : #include "mozilla/ipc/ProcessChild.h"
52 : #include "mozilla/ipc/PChildToParentStreamChild.h"
53 : #include "mozilla/intl/LocaleService.h"
54 : #include "mozilla/ipc/TestShellChild.h"
55 : #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
56 : #include "mozilla/jsipc/PJavaScript.h"
57 : #include "mozilla/layers/APZChild.h"
58 : #include "mozilla/layers/CompositorManagerChild.h"
59 : #include "mozilla/layers/ContentProcessController.h"
60 : #include "mozilla/layers/ImageBridgeChild.h"
61 : #include "mozilla/layout/RenderFrameChild.h"
62 : #include "mozilla/loader/ScriptCacheActors.h"
63 : #include "mozilla/net/NeckoChild.h"
64 : #include "mozilla/net/CaptivePortalService.h"
65 : #include "mozilla/plugins/PluginInstanceParent.h"
66 : #include "mozilla/plugins/PluginModuleParent.h"
67 : #include "mozilla/widget/ScreenManager.h"
68 : #include "mozilla/widget/WidgetMessageUtils.h"
69 : #include "nsBaseDragService.h"
70 : #include "mozilla/media/MediaChild.h"
71 : #include "mozilla/BasePrincipal.h"
72 : #include "mozilla/WebBrowserPersistDocumentChild.h"
73 : #include "imgLoader.h"
74 : #include "GMPServiceChild.h"
75 : #include "NullPrincipal.h"
76 :
77 : #ifdef MOZ_GECKO_PROFILER
78 : #include "ChildProfilerController.h"
79 : #endif
80 :
81 : #if defined(MOZ_CONTENT_SANDBOX)
82 : #include "mozilla/SandboxSettings.h"
83 : #if defined(XP_WIN)
84 : #define TARGET_SANDBOX_EXPORTS
85 : #include "mozilla/sandboxTarget.h"
86 : #elif defined(XP_LINUX)
87 : #include "mozilla/Sandbox.h"
88 : #include "mozilla/SandboxInfo.h"
89 :
90 : // Remove this include with Bug 1104619
91 : #include "CubebUtils.h"
92 : #elif defined(XP_MACOSX)
93 : #include "mozilla/Sandbox.h"
94 : #endif
95 : #endif
96 :
97 : #include "mozilla/Unused.h"
98 :
99 : #include "mozInlineSpellChecker.h"
100 : #include "nsDocShell.h"
101 : #include "nsIConsoleListener.h"
102 : #include "nsIContentViewer.h"
103 : #include "nsICycleCollectorListener.h"
104 : #include "nsIIdlePeriod.h"
105 : #include "nsIDragService.h"
106 : #include "nsIIPCBackgroundChildCreateCallback.h"
107 : #include "nsIInterfaceRequestorUtils.h"
108 : #include "nsIMemoryReporter.h"
109 : #include "nsIMemoryInfoDumper.h"
110 : #include "nsIMutable.h"
111 : #include "nsIObserverService.h"
112 : #include "nsIScriptSecurityManager.h"
113 : #include "nsMemoryInfoDumper.h"
114 : #include "nsServiceManagerUtils.h"
115 : #include "nsStyleSheetService.h"
116 : #include "nsVariant.h"
117 : #include "nsXULAppAPI.h"
118 : #include "nsIScriptError.h"
119 : #include "nsIConsoleService.h"
120 : #include "nsJSEnvironment.h"
121 : #include "SandboxHal.h"
122 : #include "nsDebugImpl.h"
123 : #include "nsHashPropertyBag.h"
124 : #include "nsLayoutStylesheetCache.h"
125 : #include "nsThreadManager.h"
126 : #include "nsAnonymousTemporaryFile.h"
127 : #include "nsISpellChecker.h"
128 : #include "nsClipboardProxy.h"
129 : #include "nsDirectoryService.h"
130 : #include "nsDirectoryServiceUtils.h"
131 : #include "nsDirectoryServiceDefs.h"
132 : #include "nsContentPermissionHelper.h"
133 : #include "nsPluginHost.h"
134 : #ifdef NS_PRINTING
135 : #include "nsPrintingProxy.h"
136 : #endif
137 :
138 : #include "IHistory.h"
139 : #include "nsNetUtil.h"
140 :
141 : #include "base/message_loop.h"
142 : #include "base/process_util.h"
143 : #include "base/task.h"
144 :
145 : #include "nsChromeRegistryContent.h"
146 : #include "nsFrameMessageManager.h"
147 :
148 : #include "nsIGeolocationProvider.h"
149 : #include "mozilla/dom/PCycleCollectWithLogsChild.h"
150 :
151 : #include "nsIScriptSecurityManager.h"
152 : #include "nsHostObjectProtocolHandler.h"
153 :
154 : #ifdef MOZ_WEBRTC
155 : #include "signaling/src/peerconnection/WebrtcGlobalChild.h"
156 : #endif
157 :
158 : #ifdef MOZ_PERMISSIONS
159 : #include "nsPermission.h"
160 : #include "nsPermissionManager.h"
161 : #endif
162 :
163 : #include "PermissionMessageUtils.h"
164 :
165 : #if defined(MOZ_WIDGET_ANDROID)
166 : #include "APKOpen.h"
167 : #endif
168 :
169 : #if defined(MOZ_WIDGET_GONK)
170 : #include "nsVolume.h"
171 : #include "nsVolumeService.h"
172 : #endif
173 :
174 : #ifdef XP_WIN
175 : #include <process.h>
176 : #define getpid _getpid
177 : #include "mozilla/widget/AudioSession.h"
178 : #endif
179 :
180 : #ifdef MOZ_X11
181 : #include "mozilla/X11Util.h"
182 : #endif
183 :
184 : #ifdef ACCESSIBILITY
185 : #include "nsAccessibilityService.h"
186 : #ifdef XP_WIN
187 : #include "mozilla/a11y/AccessibleWrap.h"
188 : #endif
189 : #endif
190 :
191 : #include "mozilla/dom/File.h"
192 : #include "mozilla/dom/PPresentationChild.h"
193 : #include "mozilla/dom/PresentationIPCService.h"
194 : #include "mozilla/ipc/InputStreamUtils.h"
195 :
196 : #ifdef MOZ_WEBSPEECH
197 : #include "mozilla/dom/PSpeechSynthesisChild.h"
198 : #endif
199 :
200 : #include "ProcessUtils.h"
201 : #include "URIUtils.h"
202 : #include "nsContentUtils.h"
203 : #include "nsIPrincipal.h"
204 : #include "DomainPolicy.h"
205 : #include "mozilla/dom/ipc/StructuredCloneData.h"
206 : #include "mozilla/dom/time/DateCacheCleaner.h"
207 : #include "mozilla/net/NeckoMessageUtils.h"
208 : #include "mozilla/widget/PuppetBidiKeyboard.h"
209 : #include "mozilla/RemoteSpellCheckEngineChild.h"
210 : #include "GMPServiceChild.h"
211 : #include "GfxInfoBase.h"
212 : #include "gfxPlatform.h"
213 : #include "nscore.h" // for NS_FREE_PERMANENT_DATA
214 : #include "VRManagerChild.h"
215 : #include "private/pprio.h"
216 : #include "nsString.h"
217 :
218 : #ifdef MOZ_WIDGET_GTK
219 : #include "nsAppRunner.h"
220 : #endif
221 : #ifdef MOZ_CRASHREPORTER
222 : #include "mozilla/ipc/CrashReporterClient.h"
223 : #endif
224 :
225 : #ifdef MOZ_CODE_COVERAGE
226 : #include "mozilla/CodeCoverageHandler.h"
227 : #endif
228 :
229 : using namespace mozilla;
230 : using namespace mozilla::docshell;
231 : using namespace mozilla::dom::ipc;
232 : using namespace mozilla::dom::workers;
233 : using namespace mozilla::media;
234 : using namespace mozilla::embedding;
235 : using namespace mozilla::gmp;
236 : using namespace mozilla::hal_sandbox;
237 : using namespace mozilla::ipc;
238 : using namespace mozilla::intl;
239 : using namespace mozilla::layers;
240 : using namespace mozilla::layout;
241 : using namespace mozilla::net;
242 : using namespace mozilla::jsipc;
243 : using namespace mozilla::psm;
244 : using namespace mozilla::widget;
245 : #if defined(MOZ_WIDGET_GONK)
246 : using namespace mozilla::system;
247 : #endif
248 : using namespace mozilla::widget;
249 : using mozilla::loader::PScriptCacheChild;
250 :
251 : namespace mozilla {
252 :
253 : namespace dom {
254 :
255 : // IPC sender for remote GC/CC logging.
256 : class CycleCollectWithLogsChild final
257 : : public PCycleCollectWithLogsChild
258 : , public nsICycleCollectorLogSink
259 : {
260 : public:
261 : NS_DECL_ISUPPORTS
262 :
263 0 : CycleCollectWithLogsChild(const FileDescriptor& aGCLog,
264 : const FileDescriptor& aCCLog)
265 0 : {
266 0 : mGCLog = FileDescriptorToFILE(aGCLog, "w");
267 0 : mCCLog = FileDescriptorToFILE(aCCLog, "w");
268 0 : }
269 :
270 0 : NS_IMETHOD Open(FILE** aGCLog, FILE** aCCLog) override
271 : {
272 0 : if (NS_WARN_IF(!mGCLog) || NS_WARN_IF(!mCCLog)) {
273 0 : return NS_ERROR_FAILURE;
274 : }
275 0 : *aGCLog = mGCLog;
276 0 : *aCCLog = mCCLog;
277 0 : return NS_OK;
278 : }
279 :
280 0 : NS_IMETHOD CloseGCLog() override
281 : {
282 0 : MOZ_ASSERT(mGCLog);
283 0 : fclose(mGCLog);
284 0 : mGCLog = nullptr;
285 0 : SendCloseGCLog();
286 0 : return NS_OK;
287 : }
288 :
289 0 : NS_IMETHOD CloseCCLog() override
290 : {
291 0 : MOZ_ASSERT(mCCLog);
292 0 : fclose(mCCLog);
293 0 : mCCLog = nullptr;
294 0 : SendCloseCCLog();
295 0 : return NS_OK;
296 : }
297 :
298 0 : NS_IMETHOD GetFilenameIdentifier(nsAString& aIdentifier) override
299 : {
300 0 : return UnimplementedProperty();
301 : }
302 :
303 0 : NS_IMETHOD SetFilenameIdentifier(const nsAString& aIdentifier) override
304 : {
305 0 : return UnimplementedProperty();
306 : }
307 :
308 0 : NS_IMETHOD GetProcessIdentifier(int32_t *aIdentifier) override
309 : {
310 0 : return UnimplementedProperty();
311 : }
312 :
313 0 : NS_IMETHOD SetProcessIdentifier(int32_t aIdentifier) override
314 : {
315 0 : return UnimplementedProperty();
316 : }
317 :
318 0 : NS_IMETHOD GetGcLog(nsIFile** aPath) override
319 : {
320 0 : return UnimplementedProperty();
321 : }
322 :
323 0 : NS_IMETHOD GetCcLog(nsIFile** aPath) override
324 : {
325 0 : return UnimplementedProperty();
326 : }
327 :
328 : private:
329 0 : ~CycleCollectWithLogsChild() override
330 0 : {
331 0 : if (mGCLog) {
332 0 : fclose(mGCLog);
333 0 : mGCLog = nullptr;
334 : }
335 0 : if (mCCLog) {
336 0 : fclose(mCCLog);
337 0 : mCCLog = nullptr;
338 : }
339 : // The XPCOM refcount drives the IPC lifecycle; see also
340 : // DeallocPCycleCollectWithLogsChild.
341 0 : Unused << Send__delete__(this);
342 0 : }
343 :
344 0 : nsresult UnimplementedProperty()
345 : {
346 0 : MOZ_ASSERT(false, "This object is a remote GC/CC logger;"
347 : " this property isn't meaningful.");
348 : return NS_ERROR_UNEXPECTED;
349 : }
350 :
351 : FILE* mGCLog;
352 : FILE* mCCLog;
353 : };
354 :
355 0 : NS_IMPL_ISUPPORTS(CycleCollectWithLogsChild, nsICycleCollectorLogSink);
356 :
357 : class AlertObserver
358 : {
359 : public:
360 :
361 0 : AlertObserver(nsIObserver *aObserver, const nsString& aData)
362 0 : : mObserver(aObserver)
363 0 : , mData(aData)
364 : {
365 0 : }
366 :
367 0 : ~AlertObserver() = default;
368 :
369 : bool ShouldRemoveFrom(nsIObserver* aObserver,
370 : const nsString& aData) const
371 : {
372 : return (mObserver == aObserver && mData == aData);
373 : }
374 :
375 0 : bool Observes(const nsString& aData) const
376 : {
377 0 : return mData.Equals(aData);
378 : }
379 :
380 0 : bool Notify(const nsCString& aType) const
381 : {
382 0 : mObserver->Observe(nullptr, aType.get(), mData.get());
383 0 : return true;
384 : }
385 :
386 : private:
387 : nsCOMPtr<nsIObserver> mObserver;
388 : nsString mData;
389 : };
390 :
391 : class ConsoleListener final : public nsIConsoleListener
392 : {
393 : public:
394 2 : explicit ConsoleListener(ContentChild* aChild)
395 2 : : mChild(aChild) {}
396 :
397 : NS_DECL_ISUPPORTS
398 : NS_DECL_NSICONSOLELISTENER
399 :
400 : private:
401 : ~ConsoleListener() = default;
402 :
403 : ContentChild* mChild;
404 : friend class ContentChild;
405 : };
406 :
407 18 : NS_IMPL_ISUPPORTS(ConsoleListener, nsIConsoleListener)
408 :
409 : // Before we send the error to the parent process (which
410 : // involves copying the memory), truncate any long lines. CSS
411 : // errors in particular share the memory for long lines with
412 : // repeated errors, but the IPC communication we're about to do
413 : // will break that sharing, so we better truncate now.
414 : static void
415 0 : TruncateString(nsAString& aString)
416 : {
417 0 : if (aString.Length() > 1000) {
418 0 : aString.Truncate(1000);
419 : }
420 0 : }
421 :
422 : NS_IMETHODIMP
423 0 : ConsoleListener::Observe(nsIConsoleMessage* aMessage)
424 : {
425 0 : if (!mChild) {
426 0 : return NS_OK;
427 : }
428 :
429 0 : nsCOMPtr<nsIScriptError> scriptError = do_QueryInterface(aMessage);
430 0 : if (scriptError) {
431 0 : nsAutoString msg, sourceName, sourceLine;
432 0 : nsXPIDLCString category;
433 : uint32_t lineNum, colNum, flags;
434 :
435 0 : nsresult rv = scriptError->GetErrorMessage(msg);
436 0 : NS_ENSURE_SUCCESS(rv, rv);
437 0 : TruncateString(msg);
438 0 : rv = scriptError->GetSourceName(sourceName);
439 0 : NS_ENSURE_SUCCESS(rv, rv);
440 0 : TruncateString(sourceName);
441 0 : rv = scriptError->GetSourceLine(sourceLine);
442 0 : NS_ENSURE_SUCCESS(rv, rv);
443 0 : TruncateString(sourceLine);
444 :
445 0 : rv = scriptError->GetCategory(getter_Copies(category));
446 0 : NS_ENSURE_SUCCESS(rv, rv);
447 0 : rv = scriptError->GetLineNumber(&lineNum);
448 0 : NS_ENSURE_SUCCESS(rv, rv);
449 0 : rv = scriptError->GetColumnNumber(&colNum);
450 0 : NS_ENSURE_SUCCESS(rv, rv);
451 0 : rv = scriptError->GetFlags(&flags);
452 0 : NS_ENSURE_SUCCESS(rv, rv);
453 :
454 0 : mChild->SendScriptError(msg, sourceName, sourceLine,
455 0 : lineNum, colNum, flags, category);
456 0 : return NS_OK;
457 : }
458 :
459 0 : nsXPIDLString msg;
460 0 : nsresult rv = aMessage->GetMessageMoz(getter_Copies(msg));
461 0 : NS_ENSURE_SUCCESS(rv, rv);
462 0 : mChild->SendConsoleMessage(msg);
463 0 : return NS_OK;
464 : }
465 :
466 : class BackgroundChildPrimer final :
467 : public nsIIPCBackgroundChildCreateCallback
468 : {
469 : public:
470 2 : BackgroundChildPrimer()
471 2 : { }
472 :
473 : NS_DECL_ISUPPORTS
474 :
475 : private:
476 : ~BackgroundChildPrimer() = default;
477 :
478 : void
479 1 : ActorCreated(PBackgroundChild* aActor) override
480 : {
481 1 : MOZ_ASSERT(aActor, "Failed to create a PBackgroundChild actor!");
482 1 : }
483 :
484 : void
485 0 : ActorFailed() override
486 : {
487 0 : MOZ_CRASH("Failed to create a PBackgroundChild actor!");
488 : }
489 : };
490 :
491 23 : NS_IMPL_ISUPPORTS(BackgroundChildPrimer, nsIIPCBackgroundChildCreateCallback)
492 :
493 : ContentChild* ContentChild::sSingleton;
494 :
495 2 : ContentChild::ContentChild()
496 : : mID(uint64_t(-1))
497 : #if defined(XP_WIN) && defined(ACCESSIBILITY)
498 : , mMainChromeTid(0)
499 : , mMsaaID(0)
500 : #endif
501 : , mCanOverrideProcessName(true)
502 : , mIsAlive(true)
503 4 : , mShuttingDown(false)
504 : {
505 : // This process is a content process, so it's clearly running in
506 : // multiprocess mode!
507 2 : nsDebugImpl::SetMultiprocessMode("Child");
508 2 : }
509 :
510 : #ifdef _MSC_VER
511 : #pragma warning(push)
512 : #pragma warning(disable:4722) /* Silence "destructor never returns" warning */
513 : #endif
514 :
515 0 : ContentChild::~ContentChild()
516 : {
517 : #ifndef NS_FREE_PERMANENT_DATA
518 : MOZ_CRASH("Content Child shouldn't be destroyed.");
519 : #endif
520 0 : }
521 :
522 : #ifdef _MSC_VER
523 : #pragma warning(pop)
524 : #endif
525 :
526 0 : NS_INTERFACE_MAP_BEGIN(ContentChild)
527 0 : NS_INTERFACE_MAP_ENTRY(nsIContentChild)
528 0 : NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
529 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentChild)
530 0 : NS_INTERFACE_MAP_END
531 :
532 :
533 : mozilla::ipc::IPCResult
534 2 : ContentChild::RecvSetXPCOMProcessAttributes(const XPCOMInitData& aXPCOMInit,
535 : const StructuredCloneData& aInitialData,
536 : nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache)
537 : {
538 2 : mLookAndFeelCache = aLookAndFeelIntCache;
539 2 : gfx::gfxVars::SetValuesForInitialize(aXPCOMInit.gfxNonDefaultVarUpdates());
540 2 : InitXPCOM(aXPCOMInit, aInitialData);
541 2 : InitGraphicsDeviceData(aXPCOMInit.contentDeviceData());
542 :
543 : #ifdef NS_PRINTING
544 : // Force the creation of the nsPrintingProxy so that it's IPC counterpart,
545 : // PrintingParent, is always available for printing initiated from the parent.
546 : // Create nsPrintingProxy instance later than the SystemGroup initialization.
547 4 : RefPtr<nsPrintingProxy> printingProxy = nsPrintingProxy::GetInstance();
548 : #endif
549 :
550 4 : return IPC_OK();
551 : }
552 :
553 : bool
554 2 : ContentChild::Init(MessageLoop* aIOLoop,
555 : base::ProcessId aParentPid,
556 : IPC::Channel* aChannel,
557 : uint64_t aChildID,
558 : bool aIsForBrowser)
559 : {
560 : #ifdef MOZ_WIDGET_GTK
561 : // We need to pass a display down to gtk_init because it's not going to
562 : // use the one from the environment on its own when deciding which backend
563 : // to use, and when starting under XWayland, it may choose to start with
564 : // the wayland backend instead of the x11 backend.
565 : // The DISPLAY environment variable is normally set by the parent process.
566 2 : if (!gfxPlatform::IsHeadless()) {
567 2 : const char* display_name = DetectDisplay();
568 2 : if (display_name) {
569 2 : int argc = 3;
570 2 : char option_name[] = "--display";
571 : char* argv[] = {
572 : // argv0 is unused because g_set_prgname() was called in
573 : // XRE_InitChildProcess().
574 : nullptr,
575 : option_name,
576 : const_cast<char*>(display_name),
577 : nullptr
578 2 : };
579 2 : char** argvp = argv;
580 2 : gtk_init(&argc, &argvp);
581 : } else {
582 0 : gtk_init(nullptr, nullptr);
583 : }
584 : }
585 : #endif
586 :
587 : #ifdef MOZ_X11
588 2 : if (!gfxPlatform::IsHeadless()) {
589 : // Do this after initializing GDK, or GDK will install its own handler.
590 2 : XRE_InstallX11ErrorHandler();
591 : }
592 : #endif
593 :
594 2 : NS_ASSERTION(!sSingleton, "only one ContentChild per child");
595 :
596 : // Once we start sending IPC messages, we need the thread manager to be
597 : // initialized so we can deal with the responses. Do that here before we
598 : // try to construct the crash reporter.
599 2 : nsresult rv = nsThreadManager::get().Init();
600 2 : if (NS_WARN_IF(NS_FAILED(rv))) {
601 0 : return false;
602 : }
603 :
604 2 : if (!Open(aChannel, aParentPid, aIOLoop)) {
605 0 : return false;
606 : }
607 2 : sSingleton = this;
608 :
609 : // If communications with the parent have broken down, take the process
610 : // down so it's not hanging around.
611 2 : GetIPCChannel()->SetAbortOnError(true);
612 : #if defined(XP_WIN) && defined(ACCESSIBILITY)
613 : GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_A11Y_REENTRY);
614 : #endif
615 :
616 : // This must be sent before any IPDL message, which may hit sentinel
617 : // errors due to parent and content processes having different
618 : // versions.
619 2 : GetIPCChannel()->SendBuildID();
620 :
621 : #ifdef MOZ_X11
622 2 : if (!gfxPlatform::IsHeadless()) {
623 : // Send the parent our X socket to act as a proxy reference for our X
624 : // resources.
625 2 : int xSocketFd = ConnectionNumber(DefaultXDisplay());
626 2 : SendBackUpXResources(FileDescriptor(xSocketFd));
627 : }
628 : #endif
629 :
630 : #ifdef MOZ_CRASHREPORTER
631 2 : CrashReporterClient::InitSingleton(this);
632 : #endif
633 :
634 2 : mID = aChildID;
635 2 : mIsForBrowser = aIsForBrowser;
636 :
637 2 : SetProcessName(NS_LITERAL_STRING("Web Content"), true);
638 :
639 2 : return true;
640 : }
641 :
642 : void
643 2 : ContentChild::SetProcessName(const nsAString& aName, bool aDontOverride)
644 : {
645 2 : if (!mCanOverrideProcessName) {
646 0 : return;
647 : }
648 :
649 : char* name;
650 2 : if ((name = PR_GetEnv("MOZ_DEBUG_APP_PROCESS")) &&
651 0 : aName.EqualsASCII(name)) {
652 : #ifdef OS_POSIX
653 0 : printf_stderr("\n\nCHILDCHILDCHILDCHILD\n [%s] debug me @%d\n\n", name,
654 0 : getpid());
655 0 : sleep(30);
656 : #elif defined(OS_WIN)
657 : // Windows has a decent JIT debugging story, so NS_DebugBreak does the
658 : // right thing.
659 : NS_DebugBreak(NS_DEBUG_BREAK,
660 : "Invoking NS_DebugBreak() to debug child process",
661 : nullptr, __FILE__, __LINE__);
662 : #endif
663 : }
664 :
665 2 : mProcessName = aName;
666 2 : mozilla::ipc::SetThisProcessName(NS_LossyConvertUTF16toASCII(aName).get());
667 :
668 2 : if (aDontOverride) {
669 2 : mCanOverrideProcessName = false;
670 : }
671 : }
672 :
673 : NS_IMETHODIMP
674 0 : ContentChild::ProvideWindow(mozIDOMWindowProxy* aParent,
675 : uint32_t aChromeFlags,
676 : bool aCalledFromJS,
677 : bool aPositionSpecified,
678 : bool aSizeSpecified,
679 : nsIURI* aURI,
680 : const nsAString& aName,
681 : const nsACString& aFeatures,
682 : bool aForceNoOpener,
683 : bool* aWindowIsNew,
684 : mozIDOMWindowProxy** aReturn)
685 : {
686 0 : return ProvideWindowCommon(nullptr, aParent, false, aChromeFlags,
687 : aCalledFromJS, aPositionSpecified,
688 : aSizeSpecified, aURI, aName, aFeatures,
689 0 : aForceNoOpener, aWindowIsNew, aReturn);
690 : }
691 :
692 : static nsresult
693 0 : GetWindowParamsFromParent(mozIDOMWindowProxy* aParent,
694 : nsACString& aBaseURIString, float* aFullZoom,
695 : nsIPrincipal** aTriggeringPrincipal)
696 : {
697 0 : *aFullZoom = 1.0f;
698 0 : auto* opener = nsPIDOMWindowOuter::From(aParent);
699 0 : if (!opener) {
700 0 : nsCOMPtr<nsIPrincipal> nullPrincipal = NullPrincipal::Create();
701 0 : NS_ADDREF(*aTriggeringPrincipal = nullPrincipal);
702 0 : return NS_OK;
703 : }
704 :
705 0 : nsCOMPtr<nsIDocument> doc = opener->GetDoc();
706 0 : NS_ADDREF(*aTriggeringPrincipal = doc->NodePrincipal());
707 0 : nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
708 0 : if (!baseURI) {
709 0 : NS_ERROR("nsIDocument didn't return a base URI");
710 0 : return NS_ERROR_FAILURE;
711 : }
712 :
713 0 : baseURI->GetSpec(aBaseURIString);
714 :
715 : RefPtr<nsDocShell> openerDocShell =
716 0 : static_cast<nsDocShell*>(opener->GetDocShell());
717 0 : if (!openerDocShell) {
718 0 : return NS_OK;
719 : }
720 :
721 0 : nsCOMPtr<nsIContentViewer> cv;
722 0 : nsresult rv = openerDocShell->GetContentViewer(getter_AddRefs(cv));
723 0 : if (NS_SUCCEEDED(rv) && cv) {
724 0 : cv->GetFullZoom(aFullZoom);
725 : }
726 :
727 0 : return NS_OK;
728 : }
729 :
730 : nsresult
731 0 : ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
732 : mozIDOMWindowProxy* aParent,
733 : bool aIframeMoz,
734 : uint32_t aChromeFlags,
735 : bool aCalledFromJS,
736 : bool aPositionSpecified,
737 : bool aSizeSpecified,
738 : nsIURI* aURI,
739 : const nsAString& aName,
740 : const nsACString& aFeatures,
741 : bool aForceNoOpener,
742 : bool* aWindowIsNew,
743 : mozIDOMWindowProxy** aReturn)
744 : {
745 0 : *aReturn = nullptr;
746 :
747 0 : nsAutoPtr<IPCTabContext> ipcContext;
748 0 : TabId openerTabId = TabId(0);
749 0 : nsAutoCString features(aFeatures);
750 0 : nsAutoString name(aName);
751 :
752 : nsresult rv;
753 :
754 0 : MOZ_ASSERT(!aParent || aTabOpener,
755 : "If aParent is non-null, we should have an aTabOpener");
756 :
757 : // Cache the boolean preference for allowing noopener windows to open in a
758 : // separate process.
759 : static bool sNoopenerNewProcess = false;
760 : static bool sNoopenerNewProcessInited = false;
761 0 : if (!sNoopenerNewProcessInited) {
762 : Preferences::AddBoolVarCache(&sNoopenerNewProcess,
763 0 : "dom.noopener.newprocess.enabled");
764 0 : sNoopenerNewProcessInited = true;
765 : }
766 :
767 : // Check if we should load in a different process. We always want to load in a
768 : // different process if we have noopener set, but we also might if we can't
769 : // load in the current process.
770 0 : bool loadInDifferentProcess = aForceNoOpener && sNoopenerNewProcess;
771 0 : if (aTabOpener && !loadInDifferentProcess && aURI) {
772 0 : nsCOMPtr<nsIWebBrowserChrome3> browserChrome3;
773 0 : rv = aTabOpener->GetWebBrowserChrome(getter_AddRefs(browserChrome3));
774 0 : if (NS_SUCCEEDED(rv) && browserChrome3) {
775 : bool shouldLoad;
776 0 : rv = browserChrome3->ShouldLoadURIInThisProcess(aURI, &shouldLoad);
777 0 : loadInDifferentProcess = NS_SUCCEEDED(rv) && !shouldLoad;
778 : }
779 : }
780 :
781 : // If we're in a content process and we have noopener set, there's no reason
782 : // to load in our process, so let's load it elsewhere!
783 0 : if (loadInDifferentProcess) {
784 0 : nsAutoCString baseURIString;
785 : float fullZoom;
786 0 : nsCOMPtr<nsIPrincipal> triggeringPrincipal;
787 0 : rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom,
788 0 : getter_AddRefs(triggeringPrincipal));
789 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
790 0 : return rv;
791 : }
792 :
793 0 : URIParams uriToLoad;
794 0 : SerializeURI(aURI, uriToLoad);
795 0 : Unused << SendCreateWindowInDifferentProcess(aTabOpener,
796 : aChromeFlags,
797 : aCalledFromJS,
798 : aPositionSpecified,
799 : aSizeSpecified,
800 : uriToLoad,
801 : features,
802 : baseURIString,
803 : fullZoom,
804 : name,
805 0 : Principal(triggeringPrincipal));
806 :
807 : // We return NS_ERROR_ABORT, so that the caller knows that we've abandoned
808 : // the window open as far as it is concerned.
809 0 : return NS_ERROR_ABORT;
810 : }
811 :
812 0 : if (aTabOpener) {
813 0 : PopupIPCTabContext context;
814 0 : openerTabId = aTabOpener->GetTabId();
815 0 : context.opener() = openerTabId;
816 0 : context.isMozBrowserElement() = aTabOpener->IsMozBrowserElement();
817 0 : ipcContext = new IPCTabContext(context);
818 : } else {
819 : // It's possible to not have a TabChild opener in the case
820 : // of ServiceWorker::OpenWindow.
821 0 : UnsafeIPCTabContext unsafeTabContext;
822 0 : ipcContext = new IPCTabContext(unsafeTabContext);
823 : }
824 :
825 0 : MOZ_ASSERT(ipcContext);
826 0 : TabId tabId(nsContentUtils::GenerateTabId());
827 :
828 : // We need to assign a TabGroup to the PBrowser actor before we send it to the
829 : // parent. Otherwise, the parent could send messages to us before we have a
830 : // proper TabGroup for that actor.
831 0 : RefPtr<TabGroup> tabGroup;
832 0 : if (aTabOpener && !aForceNoOpener) {
833 : // The new actor will use the same tab group as the opener.
834 0 : tabGroup = aTabOpener->TabGroup();
835 : } else {
836 0 : tabGroup = new TabGroup();
837 : }
838 :
839 0 : TabContext newTabContext = aTabOpener ? *aTabOpener : TabContext();
840 : RefPtr<TabChild> newChild = new TabChild(this, tabId, tabGroup,
841 0 : newTabContext, aChromeFlags);
842 0 : if (NS_FAILED(newChild->Init())) {
843 0 : return NS_ERROR_ABORT;
844 : }
845 :
846 0 : if (aTabOpener) {
847 0 : MOZ_ASSERT(ipcContext->type() == IPCTabContext::TPopupIPCTabContext);
848 0 : ipcContext->get_PopupIPCTabContext().opener() = aTabOpener;
849 : }
850 :
851 0 : nsCOMPtr<nsIEventTarget> target = tabGroup->EventTargetFor(TaskCategory::Other);
852 0 : SetEventTargetForActor(newChild, target);
853 :
854 0 : Unused << SendPBrowserConstructor(
855 : // We release this ref in DeallocPBrowserChild
856 0 : RefPtr<TabChild>(newChild).forget().take(),
857 0 : tabId, TabId(0), *ipcContext, aChromeFlags,
858 0 : GetID(), IsForBrowser());
859 :
860 0 : nsTArray<FrameScriptInfo> frameScripts;
861 0 : nsCString urlToLoad;
862 :
863 0 : PRenderFrameChild* renderFrame = newChild->SendPRenderFrameConstructor();
864 0 : TextureFactoryIdentifier textureFactoryIdentifier;
865 0 : uint64_t layersId = 0;
866 0 : CompositorOptions compositorOptions;
867 0 : uint32_t maxTouchPoints = 0;
868 0 : DimensionInfo dimensionInfo;
869 :
870 0 : nsCOMPtr<nsPIDOMWindowInner> parentTopInnerWindow;
871 0 : if (aParent) {
872 : nsCOMPtr<nsPIDOMWindowOuter> parentTopWindow =
873 0 : nsPIDOMWindowOuter::From(aParent)->GetTop();
874 0 : if (parentTopWindow) {
875 0 : parentTopInnerWindow = parentTopWindow->GetCurrentInnerWindow();
876 : }
877 : }
878 :
879 : // Send down the request to open the window.
880 0 : RefPtr<CreateWindowPromise> windowCreated;
881 0 : if (aIframeMoz) {
882 0 : MOZ_ASSERT(aTabOpener);
883 0 : nsAutoCString url;
884 0 : if (aURI) {
885 0 : aURI->GetSpec(url);
886 : } else {
887 : // We can't actually send a nullptr up as the URI, since IPDL doesn't let us
888 : // send nullptr's for primitives. We indicate that the nsString for the URI
889 : // should be converted to a nullptr by voiding the string.
890 0 : url.SetIsVoid(true);
891 : }
892 :
893 : // NOTE: BrowserFrameOpenWindowPromise is the same type as
894 : // CreateWindowPromise, and this code depends on that fact.
895 : windowCreated =
896 0 : newChild->SendBrowserFrameOpenWindow(aTabOpener, renderFrame, NS_ConvertUTF8toUTF16(url),
897 0 : name, NS_ConvertUTF8toUTF16(features));
898 : } else {
899 0 : nsAutoCString baseURIString;
900 : float fullZoom;
901 0 : nsCOMPtr<nsIPrincipal> triggeringPrincipal;
902 0 : rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom,
903 0 : getter_AddRefs(triggeringPrincipal));
904 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
905 0 : return rv;
906 : }
907 :
908 : windowCreated =
909 0 : SendCreateWindow(aTabOpener, newChild, renderFrame,
910 : aChromeFlags, aCalledFromJS, aPositionSpecified,
911 : aSizeSpecified,
912 : features,
913 : baseURIString,
914 : fullZoom,
915 0 : Principal(triggeringPrincipal));
916 : }
917 :
918 : // Await the promise being resolved. When the promise is resolved, we'll set
919 : // the `ready` local variable, which will cause us to exit our nested event
920 : // loop.
921 : //
922 : // NOTE: We need to run this callback on the StableStateEventTarget because we
923 : // need to resolve our runnable and exit from the nested event loop before
924 : // processing any events which were sent after the reply to CreateWindow was
925 : // sent.
926 0 : bool ready = false;
927 : windowCreated->Then(nsContentUtils::GetStableStateEventTarget(), __func__,
928 0 : [&] (const CreatedWindowInfo& info) {
929 0 : MOZ_RELEASE_ASSERT(NS_IsMainThread(),
930 : "windowCreated->Then must run on the main thread");
931 0 : rv = info.rv();
932 0 : *aWindowIsNew = info.windowOpened();
933 0 : frameScripts = info.frameScripts();
934 0 : urlToLoad = info.urlToLoad();
935 0 : textureFactoryIdentifier = info.textureFactoryIdentifier();
936 0 : layersId = info.layersId();
937 0 : compositorOptions = info.compositorOptions();
938 0 : maxTouchPoints = info.maxTouchPoints();
939 0 : dimensionInfo = info.dimensions();
940 0 : ready = true;
941 0 : },
942 0 : [&] (const CreateWindowPromise::RejectValueType aReason) {
943 0 : MOZ_RELEASE_ASSERT(NS_IsMainThread(),
944 : "windowCreated->Then must run on the main thread");
945 0 : NS_WARNING("windowCreated promise rejected");
946 0 : rv = NS_ERROR_NOT_AVAILABLE;
947 0 : ready = true;
948 0 : });
949 :
950 : // =======================
951 : // Begin Nested Event Loop
952 : // =======================
953 :
954 : // We have to wait for a response from either SendCreateWindow or
955 : // SendBrowserFrameOpenWindow with information we're going to need to return
956 : // from this function, So we spin a nested event loop until they get back to
957 : // us.
958 :
959 : // Prevent the docshell from becoming active while the nested event loop is
960 : // spinning.
961 0 : newChild->AddPendingDocShellBlocker();
962 0 : auto removePendingDocShellBlocker = MakeScopeExit([&] {
963 0 : if (newChild) {
964 0 : newChild->RemovePendingDocShellBlocker();
965 : }
966 0 : });
967 :
968 : // Suspend our window if we have one to make sure we don't re-enter it.
969 0 : if (parentTopInnerWindow) {
970 0 : parentTopInnerWindow->Suspend();
971 : }
972 :
973 : {
974 0 : AutoNoJSAPI nojsapi;
975 :
976 : // Spin the event loop until we get a response. Callers of this function
977 : // already have to guard against an inner event loop spinning in the
978 : // non-e10s case because of the need to spin one to create a new chrome
979 : // window.
980 0 : SpinEventLoopUntil([&] () { return ready; });
981 0 : MOZ_RELEASE_ASSERT(ready,
982 : "We are on the main thread, so we should not exit this "
983 : "loop without ready being true.");
984 : }
985 :
986 0 : if (parentTopInnerWindow) {
987 0 : parentTopInnerWindow->Resume();
988 : }
989 :
990 : // =====================
991 : // End Nested Event Loop
992 : // =====================
993 :
994 : // Handle the error which we got back from the parent process, if we got
995 : // one.
996 0 : if (NS_FAILED(rv)) {
997 0 : PRenderFrameChild::Send__delete__(renderFrame);
998 0 : return rv;
999 : }
1000 :
1001 0 : if (!*aWindowIsNew) {
1002 0 : PRenderFrameChild::Send__delete__(renderFrame);
1003 0 : return NS_ERROR_ABORT;
1004 : }
1005 :
1006 : // If the TabChild has been torn down, we don't need to do this anymore.
1007 0 : if (NS_WARN_IF(!newChild->IPCOpen())) {
1008 0 : return NS_ERROR_ABORT;
1009 : }
1010 :
1011 0 : if (layersId == 0) { // if renderFrame is invalid.
1012 0 : PRenderFrameChild::Send__delete__(renderFrame);
1013 0 : renderFrame = nullptr;
1014 : }
1015 :
1016 0 : ShowInfo showInfo(EmptyString(), false, false, true, false, 0, 0, 0);
1017 0 : auto* opener = nsPIDOMWindowOuter::From(aParent);
1018 : nsIDocShell* openerShell;
1019 0 : if (opener && (openerShell = opener->GetDocShell())) {
1020 0 : nsCOMPtr<nsILoadContext> context = do_QueryInterface(openerShell);
1021 0 : showInfo = ShowInfo(EmptyString(), false,
1022 0 : context->UsePrivateBrowsing(), true, false,
1023 : aTabOpener->mDPI, aTabOpener->mRounding,
1024 0 : aTabOpener->mDefaultScale);
1025 : }
1026 :
1027 0 : newChild->SetMaxTouchPoints(maxTouchPoints);
1028 :
1029 : // Set the opener window for this window before we start loading the document
1030 : // inside of it. We have to do this before loading the remote scripts, because
1031 : // they can poke at the document and cause the nsDocument to be created before
1032 : // the openerwindow
1033 0 : nsCOMPtr<mozIDOMWindowProxy> windowProxy = do_GetInterface(newChild->WebNavigation());
1034 0 : if (!aForceNoOpener && windowProxy && aParent) {
1035 0 : nsPIDOMWindowOuter* outer = nsPIDOMWindowOuter::From(windowProxy);
1036 0 : nsPIDOMWindowOuter* parent = nsPIDOMWindowOuter::From(aParent);
1037 0 : outer->SetOpenerWindow(parent, *aWindowIsNew);
1038 : }
1039 :
1040 : // Unfortunately we don't get a window unless we've shown the frame. That's
1041 : // pretty bogus; see bug 763602.
1042 0 : newChild->DoFakeShow(textureFactoryIdentifier, layersId, compositorOptions,
1043 0 : renderFrame, showInfo);
1044 :
1045 0 : newChild->RecvUpdateDimensions(dimensionInfo);
1046 :
1047 0 : for (size_t i = 0; i < frameScripts.Length(); i++) {
1048 0 : FrameScriptInfo& info = frameScripts[i];
1049 0 : if (!newChild->RecvLoadRemoteScript(info.url(), info.runInGlobalScope())) {
1050 0 : MOZ_CRASH();
1051 : }
1052 : }
1053 :
1054 0 : if (!urlToLoad.IsEmpty()) {
1055 0 : newChild->RecvLoadURL(urlToLoad, showInfo);
1056 : }
1057 :
1058 0 : nsCOMPtr<mozIDOMWindowProxy> win = do_GetInterface(newChild->WebNavigation());
1059 0 : win.forget(aReturn);
1060 0 : return NS_OK;
1061 : }
1062 :
1063 : void
1064 0 : ContentChild::GetProcessName(nsAString& aName) const
1065 : {
1066 0 : aName.Assign(mProcessName);
1067 0 : }
1068 :
1069 : bool
1070 0 : ContentChild::IsAlive() const
1071 : {
1072 0 : return mIsAlive;
1073 : }
1074 :
1075 : bool
1076 9 : ContentChild::IsShuttingDown() const
1077 : {
1078 9 : return mShuttingDown;
1079 : }
1080 :
1081 : void
1082 0 : ContentChild::GetProcessName(nsACString& aName) const
1083 : {
1084 0 : aName.Assign(NS_ConvertUTF16toUTF8(mProcessName));
1085 0 : }
1086 :
1087 : /* static */ void
1088 0 : ContentChild::AppendProcessId(nsACString& aName)
1089 : {
1090 0 : if (!aName.IsEmpty()) {
1091 0 : aName.Append(' ');
1092 : }
1093 0 : unsigned pid = getpid();
1094 0 : aName.Append(nsPrintfCString("(pid %u)", pid));
1095 0 : }
1096 :
1097 : void
1098 2 : ContentChild::InitGraphicsDeviceData(const ContentDeviceData& aData)
1099 : {
1100 2 : gfxPlatform::InitChild(aData);
1101 2 : }
1102 :
1103 : void
1104 2 : ContentChild::InitXPCOM(const XPCOMInitData& aXPCOMInit,
1105 : const mozilla::dom::ipc::StructuredCloneData& aInitialData)
1106 : {
1107 2 : SET_PREF_PHASE(pref_initPhase::BEGIN_ALL_PREFS);
1108 6067 : for (unsigned int i = 0; i < aXPCOMInit.prefs().Length(); i++) {
1109 6065 : Preferences::SetPreference(aXPCOMInit.prefs().ElementAt(i));
1110 : }
1111 2 : SET_PREF_PHASE(pref_initPhase::END_ALL_PREFS);
1112 : // Do this as early as possible to get the parent process to initialize the
1113 : // background thread since we'll likely need database information very soon.
1114 2 : BackgroundChild::Startup();
1115 :
1116 : nsCOMPtr<nsIIPCBackgroundChildCreateCallback> callback =
1117 4 : new BackgroundChildPrimer();
1118 2 : if (!BackgroundChild::GetOrCreateForCurrentThread(callback)) {
1119 0 : MOZ_CRASH("Failed to create PBackgroundChild!");
1120 : }
1121 :
1122 4 : nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
1123 2 : if (!svc) {
1124 0 : NS_WARNING("Couldn't acquire console service");
1125 0 : return;
1126 : }
1127 :
1128 2 : mConsoleListener = new ConsoleListener(this);
1129 2 : if (NS_FAILED(svc->RegisterListener(mConsoleListener)))
1130 0 : NS_WARNING("Couldn't register console listener for child process");
1131 :
1132 2 : mAvailableDictionaries = aXPCOMInit.dictionaries();
1133 :
1134 2 : RecvSetOffline(aXPCOMInit.isOffline());
1135 2 : RecvSetConnectivity(aXPCOMInit.isConnected());
1136 2 : LocaleService::GetInstance()->AssignAppLocales(aXPCOMInit.appLocales());
1137 2 : LocaleService::GetInstance()->AssignRequestedLocales(aXPCOMInit.requestedLocales());
1138 :
1139 2 : RecvSetCaptivePortalState(aXPCOMInit.captivePortalState());
1140 2 : RecvBidiKeyboardNotify(aXPCOMInit.isLangRTL(), aXPCOMInit.haveBidiKeyboards());
1141 :
1142 : // Create the CPOW manager as soon as possible.
1143 2 : SendPJavaScriptConstructor();
1144 :
1145 2 : if (aXPCOMInit.domainPolicy().active()) {
1146 0 : nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
1147 0 : MOZ_ASSERT(ssm);
1148 0 : ssm->ActivateDomainPolicyInternal(getter_AddRefs(mPolicy));
1149 0 : if (!mPolicy) {
1150 0 : MOZ_CRASH("Failed to activate domain policy.");
1151 : }
1152 0 : mPolicy->ApplyClone(&aXPCOMInit.domainPolicy());
1153 : }
1154 :
1155 4 : nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1"));
1156 4 : if (nsCOMPtr<nsIClipboardProxy> clipboardProxy = do_QueryInterface(clipboard)) {
1157 2 : clipboardProxy->SetCapabilities(aXPCOMInit.clipboardCaps());
1158 : }
1159 :
1160 : {
1161 4 : AutoJSAPI jsapi;
1162 2 : if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
1163 0 : MOZ_CRASH();
1164 : }
1165 4 : ErrorResult rv;
1166 4 : JS::RootedValue data(jsapi.cx());
1167 4 : mozilla::dom::ipc::StructuredCloneData id;
1168 2 : id.Copy(aInitialData);
1169 2 : id.Read(jsapi.cx(), &data, rv);
1170 2 : if (NS_WARN_IF(rv.Failed())) {
1171 0 : MOZ_CRASH();
1172 : }
1173 2 : ProcessGlobal* global = ProcessGlobal::Get();
1174 2 : global->SetInitialProcessData(data);
1175 : }
1176 :
1177 : // The stylesheet cache is not ready yet. Store this URL for future use.
1178 4 : nsCOMPtr<nsIURI> ucsURL = DeserializeURI(aXPCOMInit.userContentSheetURL());
1179 2 : nsLayoutStylesheetCache::SetUserContentCSSURL(ucsURL);
1180 :
1181 : // This will register cross-process observer.
1182 2 : mozilla::dom::time::InitializeDateCacheCleaner();
1183 :
1184 2 : GfxInfoBase::SetFeatureStatus(aXPCOMInit.gfxFeatureStatus());
1185 :
1186 2 : DataStorage::SetCachedStorageEntries(aXPCOMInit.dataStorage());
1187 : }
1188 :
1189 : mozilla::ipc::IPCResult
1190 0 : ContentChild::RecvRequestMemoryReport(const uint32_t& aGeneration,
1191 : const bool& aAnonymize,
1192 : const bool& aMinimizeMemoryUsage,
1193 : const MaybeFileDesc& aDMDFile)
1194 : {
1195 0 : nsCString process;
1196 0 : GetProcessName(process);
1197 0 : AppendProcessId(process);
1198 :
1199 0 : MemoryReportRequestClient::Start(
1200 0 : aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, process);
1201 0 : return IPC_OK();
1202 : }
1203 :
1204 : PCycleCollectWithLogsChild*
1205 0 : ContentChild::AllocPCycleCollectWithLogsChild(const bool& aDumpAllTraces,
1206 : const FileDescriptor& aGCLog,
1207 : const FileDescriptor& aCCLog)
1208 : {
1209 0 : auto* actor = new CycleCollectWithLogsChild(aGCLog, aCCLog);
1210 : // Return actor with refcount 0, which is safe because it has a non-XPCOM type.
1211 0 : return actor;
1212 : }
1213 :
1214 : mozilla::ipc::IPCResult
1215 0 : ContentChild::RecvPCycleCollectWithLogsConstructor(PCycleCollectWithLogsChild* aActor,
1216 : const bool& aDumpAllTraces,
1217 : const FileDescriptor& aGCLog,
1218 : const FileDescriptor& aCCLog)
1219 : {
1220 : // Take a reference here, where the XPCOM type is regained.
1221 0 : RefPtr<CycleCollectWithLogsChild> sink = static_cast<CycleCollectWithLogsChild*>(aActor);
1222 0 : nsCOMPtr<nsIMemoryInfoDumper> dumper = do_GetService("@mozilla.org/memory-info-dumper;1");
1223 :
1224 0 : dumper->DumpGCAndCCLogsToSink(aDumpAllTraces, sink);
1225 :
1226 : // The actor's destructor is called when the last reference goes away...
1227 0 : return IPC_OK();
1228 : }
1229 :
1230 : bool
1231 0 : ContentChild::DeallocPCycleCollectWithLogsChild(PCycleCollectWithLogsChild* /* aActor */)
1232 : {
1233 : // ...so when we get here, there's nothing for us to do.
1234 : //
1235 : // Also, we're already in ~CycleCollectWithLogsChild (q.v.) at
1236 : // this point, so we shouldn't touch the actor in any case.
1237 0 : return true;
1238 : }
1239 :
1240 : mozilla::ipc::IPCResult
1241 0 : ContentChild::RecvInitContentBridgeChild(Endpoint<PContentBridgeChild>&& aEndpoint)
1242 : {
1243 0 : ContentBridgeChild::Create(Move(aEndpoint));
1244 0 : return IPC_OK();
1245 : }
1246 :
1247 : mozilla::ipc::IPCResult
1248 0 : ContentChild::RecvInitGMPService(Endpoint<PGMPServiceChild>&& aGMPService)
1249 : {
1250 0 : if (!GMPServiceChild::Create(Move(aGMPService))) {
1251 0 : return IPC_FAIL_NO_REASON(this);
1252 : }
1253 0 : return IPC_OK();
1254 : }
1255 :
1256 : mozilla::ipc::IPCResult
1257 2 : ContentChild::RecvInitProfiler(Endpoint<PProfilerChild>&& aEndpoint)
1258 : {
1259 : #ifdef MOZ_GECKO_PROFILER
1260 2 : mProfilerController = ChildProfilerController::Create(Move(aEndpoint));
1261 : #endif
1262 2 : return IPC_OK();
1263 : }
1264 :
1265 : mozilla::ipc::IPCResult
1266 3 : ContentChild::RecvGMPsChanged(nsTArray<GMPCapabilityData>&& capabilities)
1267 : {
1268 3 : GeckoMediaPluginServiceChild::UpdateGMPCapabilities(Move(capabilities));
1269 3 : return IPC_OK();
1270 : }
1271 :
1272 : mozilla::ipc::IPCResult
1273 2 : ContentChild::RecvInitProcessHangMonitor(Endpoint<PProcessHangMonitorChild>&& aHangMonitor)
1274 : {
1275 2 : CreateHangMonitorChild(Move(aHangMonitor));
1276 2 : return IPC_OK();
1277 : }
1278 :
1279 : mozilla::ipc::IPCResult
1280 2 : ContentChild::RecvInitRendering(Endpoint<PCompositorManagerChild>&& aCompositor,
1281 : Endpoint<PImageBridgeChild>&& aImageBridge,
1282 : Endpoint<PVRManagerChild>&& aVRBridge,
1283 : Endpoint<PVideoDecoderManagerChild>&& aVideoManager,
1284 : nsTArray<uint32_t>&& namespaces)
1285 : {
1286 2 : MOZ_ASSERT(namespaces.Length() == 3);
1287 :
1288 2 : if (!CompositorManagerChild::Init(Move(aCompositor), namespaces[0])) {
1289 0 : return IPC_FAIL_NO_REASON(this);
1290 : }
1291 2 : if (!CompositorManagerChild::CreateContentCompositorBridge(namespaces[1])) {
1292 0 : return IPC_FAIL_NO_REASON(this);
1293 : }
1294 2 : if (!ImageBridgeChild::InitForContent(Move(aImageBridge), namespaces[2])) {
1295 0 : return IPC_FAIL_NO_REASON(this);
1296 : }
1297 2 : if (!gfx::VRManagerChild::InitForContent(Move(aVRBridge))) {
1298 0 : return IPC_FAIL_NO_REASON(this);
1299 : }
1300 2 : VideoDecoderManagerChild::InitForContent(Move(aVideoManager));
1301 2 : return IPC_OK();
1302 : }
1303 :
1304 : mozilla::ipc::IPCResult
1305 0 : ContentChild::RecvReinitRendering(Endpoint<PCompositorManagerChild>&& aCompositor,
1306 : Endpoint<PImageBridgeChild>&& aImageBridge,
1307 : Endpoint<PVRManagerChild>&& aVRBridge,
1308 : Endpoint<PVideoDecoderManagerChild>&& aVideoManager,
1309 : nsTArray<uint32_t>&& namespaces)
1310 : {
1311 0 : MOZ_ASSERT(namespaces.Length() == 3);
1312 0 : nsTArray<RefPtr<TabChild>> tabs = TabChild::GetAll();
1313 :
1314 : // Zap all the old layer managers we have lying around.
1315 0 : for (const auto& tabChild : tabs) {
1316 0 : if (tabChild->LayersId()) {
1317 0 : tabChild->InvalidateLayers();
1318 : }
1319 : }
1320 :
1321 : // Re-establish singleton bridges to the compositor.
1322 0 : if (!CompositorManagerChild::Init(Move(aCompositor), namespaces[0])) {
1323 0 : return IPC_FAIL_NO_REASON(this);
1324 : }
1325 0 : if (!CompositorManagerChild::CreateContentCompositorBridge(namespaces[1])) {
1326 0 : return IPC_FAIL_NO_REASON(this);
1327 : }
1328 0 : if (!ImageBridgeChild::ReinitForContent(Move(aImageBridge), namespaces[2])) {
1329 0 : return IPC_FAIL_NO_REASON(this);
1330 : }
1331 0 : if (!gfx::VRManagerChild::ReinitForContent(Move(aVRBridge))) {
1332 0 : return IPC_FAIL_NO_REASON(this);
1333 : }
1334 0 : gfxPlatform::GetPlatform()->CompositorUpdated();
1335 :
1336 : // Establish new PLayerTransactions.
1337 0 : for (const auto& tabChild : tabs) {
1338 0 : if (tabChild->LayersId()) {
1339 0 : tabChild->ReinitRendering();
1340 : }
1341 : }
1342 :
1343 0 : VideoDecoderManagerChild::InitForContent(Move(aVideoManager));
1344 0 : return IPC_OK();
1345 : }
1346 :
1347 : mozilla::ipc::IPCResult
1348 0 : ContentChild::RecvReinitRenderingForDeviceReset()
1349 : {
1350 0 : gfxPlatform::GetPlatform()->CompositorUpdated();
1351 :
1352 0 : nsTArray<RefPtr<TabChild>> tabs = TabChild::GetAll();
1353 0 : for (const auto& tabChild : tabs) {
1354 0 : if (tabChild->LayersId()) {
1355 0 : tabChild->ReinitRenderingForDeviceReset();
1356 : }
1357 : }
1358 0 : return IPC_OK();
1359 : }
1360 :
1361 : #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
1362 :
1363 : #include <stdlib.h>
1364 :
1365 : static bool
1366 : GetAppPaths(nsCString &aAppPath, nsCString &aAppBinaryPath, nsCString &aAppDir)
1367 : {
1368 : nsAutoCString appPath;
1369 : nsAutoCString appBinaryPath(
1370 : (CommandLine::ForCurrentProcess()->argv()[0]).c_str());
1371 :
1372 : nsAutoCString::const_iterator start, end;
1373 : appBinaryPath.BeginReading(start);
1374 : appBinaryPath.EndReading(end);
1375 : if (RFindInReadable(NS_LITERAL_CSTRING(".app/Contents/MacOS/"), start, end)) {
1376 : end = start;
1377 : ++end; ++end; ++end; ++end;
1378 : appBinaryPath.BeginReading(start);
1379 : appPath.Assign(Substring(start, end));
1380 : } else {
1381 : return false;
1382 : }
1383 :
1384 : nsCOMPtr<nsIFile> app, appBinary;
1385 : nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(appPath),
1386 : true, getter_AddRefs(app));
1387 : if (NS_FAILED(rv)) {
1388 : return false;
1389 : }
1390 : rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(appBinaryPath),
1391 : true, getter_AddRefs(appBinary));
1392 : if (NS_FAILED(rv)) {
1393 : return false;
1394 : }
1395 :
1396 : nsCOMPtr<nsIFile> appDir;
1397 : nsCOMPtr<nsIProperties> dirSvc =
1398 : do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
1399 : if (!dirSvc) {
1400 : return false;
1401 : }
1402 : rv = dirSvc->Get(NS_GRE_DIR,
1403 : NS_GET_IID(nsIFile), getter_AddRefs(appDir));
1404 : if (NS_FAILED(rv)) {
1405 : return false;
1406 : }
1407 : bool exists;
1408 : rv = appDir->Exists(&exists);
1409 : if (NS_FAILED(rv) || !exists) {
1410 : return false;
1411 : }
1412 :
1413 : // appDir points to .app/Contents/Resources, for our purposes we want
1414 : // .app/Contents.
1415 : nsCOMPtr<nsIFile> appDirParent;
1416 : rv = appDir->GetParent(getter_AddRefs(appDirParent));
1417 : if (NS_FAILED(rv)) {
1418 : return false;
1419 : }
1420 :
1421 : bool isLink;
1422 : app->IsSymlink(&isLink);
1423 : if (isLink) {
1424 : app->GetNativeTarget(aAppPath);
1425 : } else {
1426 : app->GetNativePath(aAppPath);
1427 : }
1428 : appBinary->IsSymlink(&isLink);
1429 : if (isLink) {
1430 : appBinary->GetNativeTarget(aAppBinaryPath);
1431 : } else {
1432 : appBinary->GetNativePath(aAppBinaryPath);
1433 : }
1434 : appDirParent->IsSymlink(&isLink);
1435 : if (isLink) {
1436 : appDirParent->GetNativeTarget(aAppDir);
1437 : } else {
1438 : appDirParent->GetNativePath(aAppDir);
1439 : }
1440 :
1441 : return true;
1442 : }
1443 :
1444 : // This function is only used in an |#ifdef DEBUG| path.
1445 : #ifdef DEBUG
1446 : // Given a path to a file, return the directory which contains it.
1447 : static nsAutoCString
1448 : GetDirectoryPath(const char *aPath) {
1449 : nsCOMPtr<nsIFile> file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
1450 : if (!file ||
1451 : NS_FAILED(file->InitWithNativePath(nsDependentCString(aPath)))) {
1452 : MOZ_CRASH("Failed to create or init an nsIFile");
1453 : }
1454 : nsCOMPtr<nsIFile> directoryFile;
1455 : if (NS_FAILED(file->GetParent(getter_AddRefs(directoryFile))) ||
1456 : !directoryFile) {
1457 : MOZ_CRASH("Failed to get parent for an nsIFile");
1458 : }
1459 : directoryFile->Normalize();
1460 : nsAutoCString directoryPath;
1461 : if (NS_FAILED(directoryFile->GetNativePath(directoryPath))) {
1462 : MOZ_CRASH("Failed to get path for an nsIFile");
1463 : }
1464 : return directoryPath;
1465 : }
1466 : #endif // DEBUG
1467 :
1468 : static bool
1469 : StartMacOSContentSandbox()
1470 : {
1471 : int sandboxLevel = GetEffectiveContentSandboxLevel();
1472 : if (sandboxLevel < 1) {
1473 : return false;
1474 : }
1475 :
1476 : nsAutoCString appPath, appBinaryPath, appDir;
1477 : if (!GetAppPaths(appPath, appBinaryPath, appDir)) {
1478 : MOZ_CRASH("Error resolving child process path");
1479 : }
1480 :
1481 : // During sandboxed content process startup, before reaching
1482 : // this point, NS_OS_TEMP_DIR is modified to refer to a sandbox-
1483 : // writable temporary directory
1484 : nsCOMPtr<nsIFile> tempDir;
1485 : nsresult rv = nsDirectoryService::gService->Get(NS_OS_TEMP_DIR,
1486 : NS_GET_IID(nsIFile), getter_AddRefs(tempDir));
1487 : if (NS_FAILED(rv)) {
1488 : MOZ_CRASH("Failed to get NS_OS_TEMP_DIR");
1489 : }
1490 :
1491 : nsAutoCString tempDirPath;
1492 : tempDir->Normalize();
1493 : rv = tempDir->GetNativePath(tempDirPath);
1494 : if (NS_FAILED(rv)) {
1495 : MOZ_CRASH("Failed to get NS_OS_TEMP_DIR path");
1496 : }
1497 :
1498 : ContentChild* cc = ContentChild::GetSingleton();
1499 :
1500 : nsCOMPtr<nsIFile> profileDir;
1501 : cc->GetProfileDir(getter_AddRefs(profileDir));
1502 : nsCString profileDirPath;
1503 : if (profileDir) {
1504 : profileDir->Normalize();
1505 : rv = profileDir->GetNativePath(profileDirPath);
1506 : if (NS_FAILED(rv) || profileDirPath.IsEmpty()) {
1507 : MOZ_CRASH("Failed to get profile path");
1508 : }
1509 : }
1510 :
1511 : bool isFileProcess = cc->GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE);
1512 : char *developer_repo_dir = nullptr;
1513 : if (mozilla::IsDevelopmentBuild()) {
1514 : // If this is a developer build the resources in the .app are symlinks to
1515 : // outside of the .app. Therefore in non-release builds we allow reads from
1516 : // the whole repository. MOZ_DEVELOPER_REPO_DIR is set by mach run.
1517 : developer_repo_dir = PR_GetEnv("MOZ_DEVELOPER_REPO_DIR");
1518 : }
1519 :
1520 : MacSandboxInfo info;
1521 : info.type = MacSandboxType_Content;
1522 : info.level = sandboxLevel;
1523 : info.hasFilePrivileges = isFileProcess;
1524 : info.shouldLog = Preferences::GetBool("security.sandbox.logging.enabled") ||
1525 : PR_GetEnv("MOZ_SANDBOX_LOGGING");
1526 : info.appPath.assign(appPath.get());
1527 : info.appBinaryPath.assign(appBinaryPath.get());
1528 : info.appDir.assign(appDir.get());
1529 : info.appTempDir.assign(tempDirPath.get());
1530 :
1531 : // These paths are used to whitelist certain directories used by the testing
1532 : // system. They should not be considered a public API, and are only intended
1533 : // for use in automation.
1534 : nsAdoptingCString testingReadPath1 =
1535 : Preferences::GetCString("security.sandbox.content.mac.testing_read_path1");
1536 : if (!testingReadPath1.IsEmpty()) {
1537 : info.testingReadPath1.assign(testingReadPath1.get());
1538 : }
1539 : nsAdoptingCString testingReadPath2 =
1540 : Preferences::GetCString("security.sandbox.content.mac.testing_read_path2");
1541 : if (!testingReadPath2.IsEmpty()) {
1542 : info.testingReadPath2.assign(testingReadPath2.get());
1543 : }
1544 : if (developer_repo_dir) {
1545 : info.testingReadPath3.assign(developer_repo_dir);
1546 : }
1547 :
1548 : if (profileDir) {
1549 : info.hasSandboxedProfile = true;
1550 : info.profileDir.assign(profileDirPath.get());
1551 : } else {
1552 : info.hasSandboxedProfile = false;
1553 : }
1554 :
1555 : #ifdef DEBUG
1556 : // When a content process dies intentionally (|NoteIntentionalCrash|), for
1557 : // tests it wants to log that it did this. Allow writing to this location
1558 : // that the testrunner wants.
1559 : char *bloatLog = PR_GetEnv("XPCOM_MEM_BLOAT_LOG");
1560 : if (bloatLog != nullptr) {
1561 : // |bloatLog| points to a specific file, but we actually write to a sibling
1562 : // of that path.
1563 : nsAutoCString bloatDirectoryPath = GetDirectoryPath(bloatLog);
1564 : info.debugWriteDir.assign(bloatDirectoryPath.get());
1565 : }
1566 : #endif // DEBUG
1567 :
1568 : std::string err;
1569 : if (!mozilla::StartMacSandbox(info, err)) {
1570 : NS_WARNING(err.c_str());
1571 : MOZ_CRASH("sandbox_init() failed");
1572 : }
1573 :
1574 : return true;
1575 : }
1576 : #endif
1577 :
1578 : mozilla::ipc::IPCResult
1579 0 : ContentChild::RecvSetProcessSandbox(const MaybeFileDesc& aBroker)
1580 : {
1581 : // We may want to move the sandbox initialization somewhere else
1582 : // at some point; see bug 880808.
1583 : #if defined(MOZ_CONTENT_SANDBOX)
1584 : bool sandboxEnabled = true;
1585 : #if defined(XP_LINUX)
1586 : #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 19
1587 : // For B2G >= KitKat, sandboxing is mandatory; this has already
1588 : // been enforced by ContentParent::StartUp().
1589 : MOZ_ASSERT(SandboxInfo::Get().CanSandboxContent());
1590 : #else
1591 : // Otherwise, sandboxing is best-effort.
1592 : if (!SandboxInfo::Get().CanSandboxContent()) {
1593 : sandboxEnabled = false;
1594 : } else {
1595 : // This triggers the initialization of cubeb, which needs to happen
1596 : // before seccomp is enabled (Bug 1259508). It also increases the startup
1597 : // time of the content process, because cubeb is usually initialized
1598 : // when it is actually needed. This call here is no longer required
1599 : // once Bug 1104619 (remoting audio) is resolved.
1600 : Unused << CubebUtils::GetCubebContext();
1601 : }
1602 :
1603 : #endif /* MOZ_WIDGET_GONK && ANDROID_VERSION >= 19 */
1604 : if (sandboxEnabled) {
1605 : int brokerFd = -1;
1606 : if (aBroker.type() == MaybeFileDesc::TFileDescriptor) {
1607 : auto fd = aBroker.get_FileDescriptor().ClonePlatformHandle();
1608 : brokerFd = fd.release();
1609 : // brokerFd < 0 means to allow direct filesystem access, so
1610 : // make absolutely sure that doesn't happen if the parent
1611 : // didn't intend it.
1612 : MOZ_RELEASE_ASSERT(brokerFd >= 0);
1613 : }
1614 : // Allow user overrides of seccomp-bpf syscall filtering
1615 : std::vector<int> syscallWhitelist;
1616 : nsAdoptingCString extraSyscalls =
1617 : Preferences::GetCString("security.sandbox.content.syscall_whitelist");
1618 : if (extraSyscalls) {
1619 : for (const nsACString& callNrString : extraSyscalls.Split(',')) {
1620 : nsresult rv;
1621 : int callNr = PromiseFlatCString(callNrString).ToInteger(&rv);
1622 : if (NS_SUCCEEDED(rv)) {
1623 : syscallWhitelist.push_back(callNr);
1624 : }
1625 : }
1626 : }
1627 : sandboxEnabled = SetContentProcessSandbox(brokerFd, syscallWhitelist);
1628 : }
1629 : #elif defined(XP_WIN)
1630 : mozilla::SandboxTarget::Instance()->StartSandbox();
1631 : #elif defined(XP_MACOSX)
1632 : sandboxEnabled = StartMacOSContentSandbox();
1633 : #endif
1634 :
1635 : #if defined(MOZ_CRASHREPORTER)
1636 : CrashReporter::AnnotateCrashReport(
1637 : NS_LITERAL_CSTRING("ContentSandboxEnabled"),
1638 : sandboxEnabled? NS_LITERAL_CSTRING("1") : NS_LITERAL_CSTRING("0"));
1639 : #if defined(XP_LINUX) && !defined(OS_ANDROID)
1640 : nsAutoCString flagsString;
1641 : flagsString.AppendInt(SandboxInfo::Get().AsInteger());
1642 :
1643 : CrashReporter::AnnotateCrashReport(
1644 : NS_LITERAL_CSTRING("ContentSandboxCapabilities"), flagsString);
1645 : #endif /* XP_LINUX && !OS_ANDROID */
1646 : CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("RemoteType"),
1647 : NS_ConvertUTF16toUTF8(GetRemoteType()));
1648 : #endif /* MOZ_CRASHREPORTER */
1649 : #endif /* MOZ_CONTENT_SANDBOX */
1650 :
1651 0 : return IPC_OK();
1652 : }
1653 :
1654 : mozilla::ipc::IPCResult
1655 2 : ContentChild::RecvBidiKeyboardNotify(const bool& aIsLangRTL,
1656 : const bool& aHaveBidiKeyboards)
1657 : {
1658 : // bidi is always of type PuppetBidiKeyboard* (because in the child, the only
1659 : // possible implementation of nsIBidiKeyboard is PuppetBidiKeyboard).
1660 2 : PuppetBidiKeyboard* bidi = static_cast<PuppetBidiKeyboard*>(nsContentUtils::GetBidiKeyboard());
1661 2 : if (bidi) {
1662 2 : bidi->SetBidiKeyboardInfo(aIsLangRTL, aHaveBidiKeyboards);
1663 : }
1664 2 : return IPC_OK();
1665 : }
1666 :
1667 3 : static StaticRefPtr<CancelableRunnable> gFirstIdleTask;
1668 :
1669 : static void
1670 1 : FirstIdle(void)
1671 : {
1672 1 : MOZ_ASSERT(gFirstIdleTask);
1673 1 : gFirstIdleTask = nullptr;
1674 1 : ContentChild::GetSingleton()->SendFirstIdle();
1675 1 : }
1676 :
1677 : mozilla::jsipc::PJavaScriptChild *
1678 2 : ContentChild::AllocPJavaScriptChild()
1679 : {
1680 2 : MOZ_ASSERT(ManagedPJavaScriptChild().IsEmpty());
1681 :
1682 2 : return nsIContentChild::AllocPJavaScriptChild();
1683 : }
1684 :
1685 : bool
1686 0 : ContentChild::DeallocPJavaScriptChild(PJavaScriptChild *aChild)
1687 : {
1688 0 : return nsIContentChild::DeallocPJavaScriptChild(aChild);
1689 : }
1690 :
1691 : PBrowserChild*
1692 1 : ContentChild::AllocPBrowserChild(const TabId& aTabId,
1693 : const TabId& aSameTabGroupAs,
1694 : const IPCTabContext& aContext,
1695 : const uint32_t& aChromeFlags,
1696 : const ContentParentId& aCpID,
1697 : const bool& aIsForBrowser)
1698 : {
1699 1 : return nsIContentChild::AllocPBrowserChild(aTabId,
1700 : aSameTabGroupAs,
1701 : aContext,
1702 : aChromeFlags,
1703 : aCpID,
1704 1 : aIsForBrowser);
1705 : }
1706 :
1707 : bool
1708 0 : ContentChild::SendPBrowserConstructor(PBrowserChild* aActor,
1709 : const TabId& aTabId,
1710 : const TabId& aSameTabGroupAs,
1711 : const IPCTabContext& aContext,
1712 : const uint32_t& aChromeFlags,
1713 : const ContentParentId& aCpID,
1714 : const bool& aIsForBrowser)
1715 : {
1716 0 : if (IsShuttingDown()) {
1717 0 : return false;
1718 : }
1719 :
1720 0 : return PContentChild::SendPBrowserConstructor(aActor,
1721 : aTabId,
1722 : aSameTabGroupAs,
1723 : aContext,
1724 : aChromeFlags,
1725 : aCpID,
1726 0 : aIsForBrowser);
1727 : }
1728 :
1729 : mozilla::ipc::IPCResult
1730 1 : ContentChild::RecvPBrowserConstructor(PBrowserChild* aActor,
1731 : const TabId& aTabId,
1732 : const TabId& aSameTabGroupAs,
1733 : const IPCTabContext& aContext,
1734 : const uint32_t& aChromeFlags,
1735 : const ContentParentId& aCpID,
1736 : const bool& aIsForBrowser)
1737 : {
1738 1 : MOZ_ASSERT(!IsShuttingDown());
1739 :
1740 : static bool hasRunOnce = false;
1741 1 : if (!hasRunOnce) {
1742 1 : hasRunOnce = true;
1743 1 : MOZ_ASSERT(!gFirstIdleTask);
1744 2 : RefPtr<CancelableRunnable> firstIdleTask = NewCancelableRunnableFunction(FirstIdle);
1745 1 : gFirstIdleTask = firstIdleTask;
1746 1 : NS_IdleDispatchToCurrentThread(firstIdleTask.forget());
1747 : }
1748 :
1749 : return nsIContentChild::RecvPBrowserConstructor(aActor,
1750 : aTabId,
1751 : aSameTabGroupAs,
1752 : aContext,
1753 : aChromeFlags,
1754 : aCpID,
1755 1 : aIsForBrowser);
1756 : }
1757 :
1758 : void
1759 0 : ContentChild::GetAvailableDictionaries(InfallibleTArray<nsString>& aDictionaries)
1760 : {
1761 0 : aDictionaries = mAvailableDictionaries;
1762 0 : }
1763 :
1764 : PFileDescriptorSetChild*
1765 0 : ContentChild::SendPFileDescriptorSetConstructor(const FileDescriptor& aFD)
1766 : {
1767 0 : if (IsShuttingDown()) {
1768 0 : return nullptr;
1769 : }
1770 :
1771 0 : return PContentChild::SendPFileDescriptorSetConstructor(aFD);
1772 : }
1773 :
1774 : PFileDescriptorSetChild*
1775 0 : ContentChild::AllocPFileDescriptorSetChild(const FileDescriptor& aFD)
1776 : {
1777 0 : return nsIContentChild::AllocPFileDescriptorSetChild(aFD);
1778 : }
1779 :
1780 : bool
1781 0 : ContentChild::DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor)
1782 : {
1783 0 : return nsIContentChild::DeallocPFileDescriptorSetChild(aActor);
1784 : }
1785 :
1786 : bool
1787 0 : ContentChild::DeallocPBrowserChild(PBrowserChild* aIframe)
1788 : {
1789 0 : return nsIContentChild::DeallocPBrowserChild(aIframe);
1790 : }
1791 :
1792 : PIPCBlobInputStreamChild*
1793 0 : ContentChild::AllocPIPCBlobInputStreamChild(const nsID& aID,
1794 : const uint64_t& aSize)
1795 : {
1796 0 : return nsIContentChild::AllocPIPCBlobInputStreamChild(aID, aSize);
1797 : }
1798 :
1799 : bool
1800 0 : ContentChild::DeallocPIPCBlobInputStreamChild(PIPCBlobInputStreamChild* aActor)
1801 : {
1802 0 : return nsIContentChild::DeallocPIPCBlobInputStreamChild(aActor);
1803 : }
1804 :
1805 : mozilla::PRemoteSpellcheckEngineChild *
1806 0 : ContentChild::AllocPRemoteSpellcheckEngineChild()
1807 : {
1808 0 : MOZ_CRASH("Default Constructor for PRemoteSpellcheckEngineChild should never be called");
1809 : return nullptr;
1810 : }
1811 :
1812 : bool
1813 0 : ContentChild::DeallocPRemoteSpellcheckEngineChild(PRemoteSpellcheckEngineChild *child)
1814 : {
1815 0 : delete child;
1816 0 : return true;
1817 : }
1818 :
1819 : PPresentationChild*
1820 0 : ContentChild::AllocPPresentationChild()
1821 : {
1822 0 : MOZ_CRASH("We should never be manually allocating PPresentationChild actors");
1823 : return nullptr;
1824 : }
1825 :
1826 : bool
1827 0 : ContentChild::DeallocPPresentationChild(PPresentationChild* aActor)
1828 : {
1829 0 : delete aActor;
1830 0 : return true;
1831 : }
1832 :
1833 : PFlyWebPublishedServerChild*
1834 0 : ContentChild::AllocPFlyWebPublishedServerChild(const nsString& name,
1835 : const FlyWebPublishOptions& params)
1836 : {
1837 0 : MOZ_CRASH("We should never be manually allocating PFlyWebPublishedServerChild actors");
1838 : return nullptr;
1839 : }
1840 :
1841 : bool
1842 0 : ContentChild::DeallocPFlyWebPublishedServerChild(PFlyWebPublishedServerChild* aActor)
1843 : {
1844 : RefPtr<FlyWebPublishedServerChild> actor =
1845 0 : dont_AddRef(static_cast<FlyWebPublishedServerChild*>(aActor));
1846 0 : return true;
1847 : }
1848 :
1849 : mozilla::ipc::IPCResult
1850 0 : ContentChild::RecvNotifyPresentationReceiverLaunched(PBrowserChild* aIframe,
1851 : const nsString& aSessionId)
1852 : {
1853 : nsCOMPtr<nsIDocShell> docShell =
1854 0 : do_GetInterface(static_cast<TabChild*>(aIframe)->WebNavigation());
1855 0 : NS_WARNING_ASSERTION(docShell, "WebNavigation failed");
1856 :
1857 : nsCOMPtr<nsIPresentationService> service =
1858 0 : do_GetService(PRESENTATION_SERVICE_CONTRACTID);
1859 0 : NS_WARNING_ASSERTION(service, "presentation service is missing");
1860 :
1861 0 : Unused << NS_WARN_IF(NS_FAILED(static_cast<PresentationIPCService*>(service.get())->MonitorResponderLoading(aSessionId, docShell)));
1862 :
1863 0 : return IPC_OK();
1864 : }
1865 :
1866 : mozilla::ipc::IPCResult
1867 0 : ContentChild::RecvNotifyPresentationReceiverCleanUp(const nsString& aSessionId)
1868 : {
1869 : nsCOMPtr<nsIPresentationService> service =
1870 0 : do_GetService(PRESENTATION_SERVICE_CONTRACTID);
1871 0 : NS_WARNING_ASSERTION(service, "presentation service is missing");
1872 :
1873 0 : Unused << NS_WARN_IF(NS_FAILED(service->UntrackSessionInfo(aSessionId, nsIPresentationService::ROLE_RECEIVER)));
1874 :
1875 0 : return IPC_OK();
1876 : }
1877 :
1878 : mozilla::ipc::IPCResult
1879 0 : ContentChild::RecvNotifyEmptyHTTPCache()
1880 : {
1881 0 : MOZ_ASSERT(NS_IsMainThread());
1882 0 : nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
1883 0 : obs->NotifyObservers(nullptr, "cacheservice:empty-cache", nullptr);
1884 0 : return IPC_OK();
1885 : }
1886 :
1887 : PHalChild*
1888 2 : ContentChild::AllocPHalChild()
1889 : {
1890 2 : return CreateHalChild();
1891 : }
1892 :
1893 : bool
1894 0 : ContentChild::DeallocPHalChild(PHalChild* aHal)
1895 : {
1896 0 : delete aHal;
1897 0 : return true;
1898 : }
1899 :
1900 : devtools::PHeapSnapshotTempFileHelperChild*
1901 0 : ContentChild::AllocPHeapSnapshotTempFileHelperChild()
1902 : {
1903 0 : return devtools::HeapSnapshotTempFileHelperChild::Create();
1904 : }
1905 :
1906 : bool
1907 0 : ContentChild::DeallocPHeapSnapshotTempFileHelperChild(
1908 : devtools::PHeapSnapshotTempFileHelperChild* aHeapSnapshotHelper)
1909 : {
1910 0 : delete aHeapSnapshotHelper;
1911 0 : return true;
1912 : }
1913 :
1914 : PTestShellChild*
1915 0 : ContentChild::AllocPTestShellChild()
1916 : {
1917 0 : return new TestShellChild();
1918 : }
1919 :
1920 : bool
1921 0 : ContentChild::DeallocPTestShellChild(PTestShellChild* shell)
1922 : {
1923 0 : delete shell;
1924 0 : return true;
1925 : }
1926 :
1927 : jsipc::CPOWManager*
1928 11 : ContentChild::GetCPOWManager()
1929 : {
1930 11 : if (PJavaScriptChild* c = LoneManagedOrNullAsserts(ManagedPJavaScriptChild())) {
1931 11 : return CPOWManagerFor(c);
1932 : }
1933 0 : return CPOWManagerFor(SendPJavaScriptConstructor());
1934 : }
1935 :
1936 : mozilla::ipc::IPCResult
1937 0 : ContentChild::RecvPTestShellConstructor(PTestShellChild* actor)
1938 : {
1939 0 : return IPC_OK();
1940 : }
1941 :
1942 : PScriptCacheChild*
1943 2 : ContentChild::AllocPScriptCacheChild(const FileDescOrError& cacheFile, const bool& wantCacheData)
1944 : {
1945 2 : return new loader::ScriptCacheChild();
1946 : }
1947 :
1948 : bool
1949 2 : ContentChild::DeallocPScriptCacheChild(PScriptCacheChild* cache)
1950 : {
1951 2 : delete static_cast<loader::ScriptCacheChild*>(cache);
1952 2 : return true;
1953 : }
1954 :
1955 : mozilla::ipc::IPCResult
1956 2 : ContentChild::RecvPScriptCacheConstructor(PScriptCacheChild* actor, const FileDescOrError& cacheFile, const bool& wantCacheData)
1957 : {
1958 4 : Maybe<FileDescriptor> fd;
1959 2 : if (cacheFile.type() == cacheFile.TFileDescriptor) {
1960 2 : fd.emplace(cacheFile.get_FileDescriptor());
1961 : }
1962 :
1963 2 : static_cast<loader::ScriptCacheChild*>(actor)->Init(fd, wantCacheData);
1964 4 : return IPC_OK();
1965 : }
1966 :
1967 : PNeckoChild*
1968 2 : ContentChild::AllocPNeckoChild()
1969 : {
1970 2 : return new NeckoChild();
1971 : }
1972 :
1973 : bool
1974 0 : ContentChild::DeallocPNeckoChild(PNeckoChild* necko)
1975 : {
1976 0 : delete necko;
1977 0 : return true;
1978 : }
1979 :
1980 : PPrintingChild*
1981 0 : ContentChild::AllocPPrintingChild()
1982 : {
1983 : // The ContentParent should never attempt to allocate the nsPrintingProxy,
1984 : // which implements PPrintingChild. Instead, the nsPrintingProxy service is
1985 : // requested and instantiated via XPCOM, and the constructor of
1986 : // nsPrintingProxy sets up the IPC connection.
1987 0 : MOZ_CRASH("Should never get here!");
1988 : return nullptr;
1989 : }
1990 :
1991 : bool
1992 0 : ContentChild::DeallocPPrintingChild(PPrintingChild* printing)
1993 : {
1994 0 : return true;
1995 : }
1996 :
1997 : PChildToParentStreamChild*
1998 0 : ContentChild::SendPChildToParentStreamConstructor(PChildToParentStreamChild* aActor)
1999 : {
2000 0 : if (IsShuttingDown()) {
2001 0 : return nullptr;
2002 : }
2003 :
2004 0 : return PContentChild::SendPChildToParentStreamConstructor(aActor);
2005 : }
2006 :
2007 : PChildToParentStreamChild*
2008 0 : ContentChild::AllocPChildToParentStreamChild()
2009 : {
2010 0 : return nsIContentChild::AllocPChildToParentStreamChild();
2011 : }
2012 :
2013 : bool
2014 0 : ContentChild::DeallocPChildToParentStreamChild(PChildToParentStreamChild* aActor)
2015 : {
2016 0 : return nsIContentChild::DeallocPChildToParentStreamChild(aActor);
2017 : }
2018 :
2019 : PParentToChildStreamChild*
2020 0 : ContentChild::AllocPParentToChildStreamChild()
2021 : {
2022 0 : return nsIContentChild::AllocPParentToChildStreamChild();
2023 : }
2024 :
2025 : bool
2026 0 : ContentChild::DeallocPParentToChildStreamChild(PParentToChildStreamChild* aActor)
2027 : {
2028 0 : return nsIContentChild::DeallocPParentToChildStreamChild(aActor);
2029 : }
2030 :
2031 : PPSMContentDownloaderChild*
2032 0 : ContentChild::AllocPPSMContentDownloaderChild(const uint32_t& aCertType)
2033 : {
2034 : // NB: We don't need aCertType in the child actor.
2035 0 : RefPtr<PSMContentDownloaderChild> child = new PSMContentDownloaderChild();
2036 0 : return child.forget().take();
2037 : }
2038 :
2039 : bool
2040 0 : ContentChild::DeallocPPSMContentDownloaderChild(PPSMContentDownloaderChild* aListener)
2041 : {
2042 0 : auto* listener = static_cast<PSMContentDownloaderChild*>(aListener);
2043 0 : RefPtr<PSMContentDownloaderChild> child = dont_AddRef(listener);
2044 0 : return true;
2045 : }
2046 :
2047 : PExternalHelperAppChild*
2048 0 : ContentChild::AllocPExternalHelperAppChild(const OptionalURIParams& uri,
2049 : const nsCString& aMimeContentType,
2050 : const nsCString& aContentDisposition,
2051 : const uint32_t& aContentDispositionHint,
2052 : const nsString& aContentDispositionFilename,
2053 : const bool& aForceSave,
2054 : const int64_t& aContentLength,
2055 : const bool& aWasFileChannel,
2056 : const OptionalURIParams& aReferrer,
2057 : PBrowserChild* aBrowser)
2058 : {
2059 0 : auto *child = new ExternalHelperAppChild();
2060 0 : child->AddRef();
2061 0 : return child;
2062 : }
2063 :
2064 : bool
2065 0 : ContentChild::DeallocPExternalHelperAppChild(PExternalHelperAppChild* aService)
2066 : {
2067 0 : ExternalHelperAppChild *child = static_cast<ExternalHelperAppChild*>(aService);
2068 0 : child->Release();
2069 0 : return true;
2070 : }
2071 :
2072 : PHandlerServiceChild*
2073 0 : ContentChild::AllocPHandlerServiceChild()
2074 : {
2075 0 : auto* actor = new HandlerServiceChild();
2076 0 : actor->AddRef();
2077 0 : return actor;
2078 : }
2079 :
2080 0 : bool ContentChild::DeallocPHandlerServiceChild(PHandlerServiceChild* aHandlerServiceChild)
2081 : {
2082 0 : static_cast<HandlerServiceChild*>(aHandlerServiceChild)->Release();
2083 0 : return true;
2084 : }
2085 :
2086 : media::PMediaChild*
2087 0 : ContentChild::AllocPMediaChild()
2088 : {
2089 0 : return media::AllocPMediaChild();
2090 : }
2091 :
2092 : bool
2093 0 : ContentChild::DeallocPMediaChild(media::PMediaChild *aActor)
2094 : {
2095 0 : return media::DeallocPMediaChild(aActor);
2096 : }
2097 :
2098 : PStorageChild*
2099 0 : ContentChild::AllocPStorageChild()
2100 : {
2101 0 : MOZ_CRASH("We should never be manually allocating PStorageChild actors");
2102 : return nullptr;
2103 : }
2104 :
2105 : bool
2106 0 : ContentChild::DeallocPStorageChild(PStorageChild* aActor)
2107 : {
2108 0 : StorageDBChild* child = static_cast<StorageDBChild*>(aActor);
2109 0 : child->ReleaseIPDLReference();
2110 0 : return true;
2111 : }
2112 :
2113 : PSpeechSynthesisChild*
2114 0 : ContentChild::AllocPSpeechSynthesisChild()
2115 : {
2116 : #ifdef MOZ_WEBSPEECH
2117 0 : MOZ_CRASH("No one should be allocating PSpeechSynthesisChild actors");
2118 : #else
2119 : return nullptr;
2120 : #endif
2121 : }
2122 :
2123 : bool
2124 0 : ContentChild::DeallocPSpeechSynthesisChild(PSpeechSynthesisChild* aActor)
2125 : {
2126 : #ifdef MOZ_WEBSPEECH
2127 0 : delete aActor;
2128 0 : return true;
2129 : #else
2130 : return false;
2131 : #endif
2132 : }
2133 :
2134 : PWebrtcGlobalChild *
2135 0 : ContentChild::AllocPWebrtcGlobalChild()
2136 : {
2137 : #ifdef MOZ_WEBRTC
2138 0 : auto *child = new WebrtcGlobalChild();
2139 0 : return child;
2140 : #else
2141 : return nullptr;
2142 : #endif
2143 : }
2144 :
2145 : bool
2146 0 : ContentChild::DeallocPWebrtcGlobalChild(PWebrtcGlobalChild *aActor)
2147 : {
2148 : #ifdef MOZ_WEBRTC
2149 0 : delete static_cast<WebrtcGlobalChild*>(aActor);
2150 0 : return true;
2151 : #else
2152 : return false;
2153 : #endif
2154 : }
2155 :
2156 :
2157 : mozilla::ipc::IPCResult
2158 2 : ContentChild::RecvRegisterChrome(InfallibleTArray<ChromePackage>&& packages,
2159 : InfallibleTArray<SubstitutionMapping>&& resources,
2160 : InfallibleTArray<OverrideMapping>&& overrides,
2161 : const nsCString& locale,
2162 : const bool& reset)
2163 : {
2164 4 : nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
2165 : nsChromeRegistryContent* chromeRegistry =
2166 2 : static_cast<nsChromeRegistryContent*>(registrySvc.get());
2167 2 : chromeRegistry->RegisterRemoteChrome(packages, resources, overrides,
2168 4 : locale, reset);
2169 4 : return IPC_OK();
2170 : }
2171 :
2172 : mozilla::ipc::IPCResult
2173 0 : ContentChild::RecvRegisterChromeItem(const ChromeRegistryItem& item)
2174 : {
2175 0 : nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
2176 : nsChromeRegistryContent* chromeRegistry =
2177 0 : static_cast<nsChromeRegistryContent*>(registrySvc.get());
2178 0 : switch (item.type()) {
2179 : case ChromeRegistryItem::TChromePackage:
2180 0 : chromeRegistry->RegisterPackage(item.get_ChromePackage());
2181 0 : break;
2182 :
2183 : case ChromeRegistryItem::TOverrideMapping:
2184 0 : chromeRegistry->RegisterOverride(item.get_OverrideMapping());
2185 0 : break;
2186 :
2187 : case ChromeRegistryItem::TSubstitutionMapping:
2188 0 : chromeRegistry->RegisterSubstitution(item.get_SubstitutionMapping());
2189 0 : break;
2190 :
2191 : default:
2192 0 : MOZ_ASSERT(false, "bad chrome item");
2193 : return IPC_FAIL_NO_REASON(this);
2194 : }
2195 :
2196 0 : return IPC_OK();
2197 : }
2198 :
2199 : mozilla::ipc::IPCResult
2200 0 : ContentChild::RecvClearImageCache(const bool& privateLoader, const bool& chrome)
2201 : {
2202 0 : imgLoader* loader = privateLoader ? imgLoader::PrivateBrowsingLoader() :
2203 0 : imgLoader::NormalLoader();
2204 :
2205 0 : loader->ClearCache(chrome);
2206 0 : return IPC_OK();
2207 : }
2208 :
2209 : mozilla::ipc::IPCResult
2210 2 : ContentChild::RecvSetOffline(const bool& offline)
2211 : {
2212 4 : nsCOMPtr<nsIIOService> io (do_GetIOService());
2213 2 : NS_ASSERTION(io, "IO Service can not be null");
2214 :
2215 2 : io->SetOffline(offline);
2216 :
2217 4 : return IPC_OK();
2218 : }
2219 :
2220 : mozilla::ipc::IPCResult
2221 2 : ContentChild::RecvSetConnectivity(const bool& connectivity)
2222 : {
2223 4 : nsCOMPtr<nsIIOService> io(do_GetIOService());
2224 4 : nsCOMPtr<nsIIOServiceInternal> ioInternal(do_QueryInterface(io));
2225 2 : NS_ASSERTION(ioInternal, "IO Service can not be null");
2226 :
2227 2 : ioInternal->SetConnectivity(connectivity);
2228 :
2229 4 : return IPC_OK();
2230 : }
2231 :
2232 : mozilla::ipc::IPCResult
2233 2 : ContentChild::RecvSetCaptivePortalState(const int32_t& aState)
2234 : {
2235 4 : nsCOMPtr<nsICaptivePortalService> cps = do_GetService(NS_CAPTIVEPORTAL_CID);
2236 2 : if (!cps) {
2237 0 : return IPC_OK();
2238 : }
2239 :
2240 : mozilla::net::CaptivePortalService *portal =
2241 2 : static_cast<mozilla::net::CaptivePortalService*>(cps.get());
2242 2 : portal->SetStateInChild(aState);
2243 :
2244 2 : return IPC_OK();
2245 : }
2246 :
2247 : void
2248 0 : ContentChild::ActorDestroy(ActorDestroyReason why)
2249 : {
2250 0 : if (mForceKillTimer) {
2251 0 : mForceKillTimer->Cancel();
2252 0 : mForceKillTimer = nullptr;
2253 : }
2254 :
2255 0 : if (AbnormalShutdown == why) {
2256 0 : NS_WARNING("shutting down early because of crash!");
2257 0 : ProcessChild::QuickExit();
2258 : }
2259 :
2260 : #ifndef NS_FREE_PERMANENT_DATA
2261 : // In release builds, there's no point in the content process
2262 : // going through the full XPCOM shutdown path, because it doesn't
2263 : // keep persistent state.
2264 : ProcessChild::QuickExit();
2265 : #else
2266 0 : if (gFirstIdleTask) {
2267 0 : gFirstIdleTask->Cancel();
2268 : }
2269 :
2270 0 : nsHostObjectProtocolHandler::RemoveDataEntries();
2271 :
2272 0 : mAlertObservers.Clear();
2273 :
2274 0 : mIdleObservers.Clear();
2275 :
2276 0 : nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
2277 0 : if (svc) {
2278 0 : svc->UnregisterListener(mConsoleListener);
2279 0 : mConsoleListener->mChild = nullptr;
2280 : }
2281 0 : mIsAlive = false;
2282 :
2283 : # ifdef MOZ_CRASHREPORTER
2284 0 : CrashReporterClient::DestroySingleton();
2285 : # endif
2286 0 : XRE_ShutdownChildProcess();
2287 : #endif // NS_FREE_PERMANENT_DATA
2288 0 : }
2289 :
2290 : void
2291 0 : ContentChild::ProcessingError(Result aCode, const char* aReason)
2292 : {
2293 0 : switch (aCode) {
2294 : case MsgDropped:
2295 0 : NS_WARNING("MsgDropped in ContentChild");
2296 0 : return;
2297 :
2298 : case MsgNotKnown:
2299 : case MsgNotAllowed:
2300 : case MsgPayloadError:
2301 : case MsgProcessingError:
2302 : case MsgRouteError:
2303 : case MsgValueError:
2304 0 : break;
2305 :
2306 : default:
2307 0 : MOZ_CRASH("not reached");
2308 : }
2309 :
2310 : #if defined(MOZ_CRASHREPORTER) && !defined(MOZ_B2G)
2311 0 : nsDependentCString reason(aReason);
2312 0 : CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ipc_channel_error"), reason);
2313 : #endif
2314 0 : MOZ_CRASH("Content child abort due to IPC error");
2315 : }
2316 :
2317 : nsresult
2318 0 : ContentChild::AddRemoteAlertObserver(const nsString& aData,
2319 : nsIObserver* aObserver)
2320 : {
2321 0 : NS_ASSERTION(aObserver, "Adding a null observer?");
2322 0 : mAlertObservers.AppendElement(new AlertObserver(aObserver, aData));
2323 0 : return NS_OK;
2324 : }
2325 :
2326 : mozilla::ipc::IPCResult
2327 23 : ContentChild::RecvPreferenceUpdate(const PrefSetting& aPref)
2328 : {
2329 23 : Preferences::SetPreference(aPref);
2330 23 : return IPC_OK();
2331 : }
2332 :
2333 : mozilla::ipc::IPCResult
2334 0 : ContentChild::RecvVarUpdate(const GfxVarUpdate& aVar)
2335 : {
2336 0 : gfx::gfxVars::ApplyUpdate(aVar);
2337 0 : return IPC_OK();
2338 : }
2339 :
2340 : mozilla::ipc::IPCResult
2341 0 : ContentChild::RecvDataStoragePut(const nsString& aFilename,
2342 : const DataStorageItem& aItem)
2343 : {
2344 0 : RefPtr<DataStorage> storage = DataStorage::GetFromRawFileName(aFilename);
2345 0 : if (storage) {
2346 0 : storage->Put(aItem.key(), aItem.value(), aItem.type());
2347 : }
2348 0 : return IPC_OK();
2349 : }
2350 :
2351 : mozilla::ipc::IPCResult
2352 0 : ContentChild::RecvDataStorageRemove(const nsString& aFilename,
2353 : const nsCString& aKey,
2354 : const DataStorageType& aType)
2355 : {
2356 0 : RefPtr<DataStorage> storage = DataStorage::GetFromRawFileName(aFilename);
2357 0 : if (storage) {
2358 0 : storage->Remove(aKey, aType);
2359 : }
2360 0 : return IPC_OK();
2361 : }
2362 :
2363 : mozilla::ipc::IPCResult
2364 0 : ContentChild::RecvDataStorageClear(const nsString& aFilename)
2365 : {
2366 0 : RefPtr<DataStorage> storage = DataStorage::GetFromRawFileName(aFilename);
2367 0 : if (storage) {
2368 0 : storage->Clear();
2369 : }
2370 0 : return IPC_OK();
2371 : }
2372 :
2373 : mozilla::ipc::IPCResult
2374 0 : ContentChild::RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData)
2375 : {
2376 0 : for (uint32_t i = 0; i < mAlertObservers.Length();
2377 : /*we mutate the array during the loop; ++i iff no mutation*/) {
2378 0 : AlertObserver* observer = mAlertObservers[i];
2379 0 : if (observer->Observes(aData) && observer->Notify(aType)) {
2380 : // if aType == alertfinished, this alert is done. we can
2381 : // remove the observer.
2382 0 : if (aType.Equals(nsDependentCString("alertfinished"))) {
2383 0 : mAlertObservers.RemoveElementAt(i);
2384 0 : continue;
2385 : }
2386 : }
2387 0 : ++i;
2388 : }
2389 0 : return IPC_OK();
2390 : }
2391 :
2392 : mozilla::ipc::IPCResult
2393 1 : ContentChild::RecvNotifyVisited(const URIParams& aURI)
2394 : {
2395 2 : nsCOMPtr<nsIURI> newURI = DeserializeURI(aURI);
2396 1 : if (!newURI) {
2397 0 : return IPC_FAIL_NO_REASON(this);
2398 : }
2399 2 : nsCOMPtr<IHistory> history = services::GetHistoryService();
2400 1 : if (history) {
2401 1 : history->NotifyVisited(newURI);
2402 : }
2403 1 : return IPC_OK();
2404 : }
2405 :
2406 : mozilla::ipc::IPCResult
2407 18 : ContentChild::RecvLoadProcessScript(const nsString& aURL)
2408 : {
2409 18 : ProcessGlobal* global = ProcessGlobal::Get();
2410 18 : global->LoadScript(aURL);
2411 18 : return IPC_OK();
2412 : }
2413 :
2414 : mozilla::ipc::IPCResult
2415 2 : ContentChild::RecvAsyncMessage(const nsString& aMsg,
2416 : InfallibleTArray<CpowEntry>&& aCpows,
2417 : const IPC::Principal& aPrincipal,
2418 : const ClonedMessageData& aData)
2419 : {
2420 4 : NS_LossyConvertUTF16toASCII messageNameCStr(aMsg);
2421 4 : AUTO_PROFILER_LABEL_DYNAMIC("ContentChild::RecvAsyncMessage", EVENTS,
2422 : messageNameCStr.get());
2423 :
2424 4 : CrossProcessCpowHolder cpows(this, aCpows);
2425 : RefPtr<nsFrameMessageManager> cpm =
2426 4 : nsFrameMessageManager::GetChildProcessManager();
2427 2 : if (cpm) {
2428 4 : StructuredCloneData data;
2429 2 : ipc::UnpackClonedMessageDataForChild(aData, data);
2430 2 : cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
2431 : nullptr, aMsg, false, &data, &cpows, aPrincipal,
2432 2 : nullptr);
2433 : }
2434 4 : return IPC_OK();
2435 : }
2436 :
2437 : mozilla::ipc::IPCResult
2438 0 : ContentChild::RecvGeolocationUpdate(const GeoPosition& somewhere)
2439 : {
2440 : nsCOMPtr<nsIGeolocationUpdate> gs =
2441 0 : do_GetService("@mozilla.org/geolocation/service;1");
2442 0 : if (!gs) {
2443 0 : return IPC_OK();
2444 : }
2445 0 : nsCOMPtr<nsIDOMGeoPosition> position = somewhere;
2446 0 : gs->Update(position);
2447 0 : return IPC_OK();
2448 : }
2449 :
2450 : mozilla::ipc::IPCResult
2451 0 : ContentChild::RecvGeolocationError(const uint16_t& errorCode)
2452 : {
2453 : nsCOMPtr<nsIGeolocationUpdate> gs =
2454 0 : do_GetService("@mozilla.org/geolocation/service;1");
2455 0 : if (!gs) {
2456 0 : return IPC_OK();
2457 : }
2458 0 : gs->NotifyError(errorCode);
2459 0 : return IPC_OK();
2460 : }
2461 :
2462 : mozilla::ipc::IPCResult
2463 0 : ContentChild::RecvUpdateDictionaryList(InfallibleTArray<nsString>&& aDictionaries)
2464 : {
2465 0 : mAvailableDictionaries = aDictionaries;
2466 0 : mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking();
2467 0 : return IPC_OK();
2468 : }
2469 :
2470 : mozilla::ipc::IPCResult
2471 0 : ContentChild::RecvUpdateAppLocales(nsTArray<nsCString>&& aAppLocales)
2472 : {
2473 0 : LocaleService::GetInstance()->AssignAppLocales(aAppLocales);
2474 0 : return IPC_OK();
2475 : }
2476 :
2477 : mozilla::ipc::IPCResult
2478 0 : ContentChild::RecvUpdateRequestedLocales(nsTArray<nsCString>&& aRequestedLocales)
2479 : {
2480 0 : LocaleService::GetInstance()->AssignRequestedLocales(aRequestedLocales);
2481 0 : return IPC_OK();
2482 : }
2483 :
2484 : mozilla::ipc::IPCResult
2485 0 : ContentChild::RecvAddPermission(const IPC::Permission& permission)
2486 : {
2487 : #if MOZ_PERMISSIONS
2488 : nsCOMPtr<nsIPermissionManager> permissionManagerIface =
2489 0 : services::GetPermissionManager();
2490 : nsPermissionManager* permissionManager =
2491 0 : static_cast<nsPermissionManager*>(permissionManagerIface.get());
2492 0 : MOZ_ASSERT(permissionManager,
2493 : "We have no permissionManager in the Content process !");
2494 :
2495 : // note we do not need to force mUserContextId to the default here because
2496 : // the permission manager does that internally.
2497 0 : nsAutoCString originNoSuffix;
2498 0 : OriginAttributes attrs;
2499 0 : bool success = attrs.PopulateFromOrigin(permission.origin, originNoSuffix);
2500 0 : NS_ENSURE_TRUE(success, IPC_FAIL_NO_REASON(this));
2501 :
2502 0 : nsCOMPtr<nsIURI> uri;
2503 0 : nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
2504 0 : NS_ENSURE_SUCCESS(rv, IPC_OK());
2505 :
2506 0 : nsCOMPtr<nsIPrincipal> principal = mozilla::BasePrincipal::CreateCodebasePrincipal(uri, attrs);
2507 :
2508 : // child processes don't care about modification time.
2509 0 : int64_t modificationTime = 0;
2510 :
2511 0 : permissionManager->AddInternal(principal,
2512 0 : nsCString(permission.type),
2513 0 : permission.capability,
2514 : 0,
2515 0 : permission.expireType,
2516 0 : permission.expireTime,
2517 : modificationTime,
2518 : nsPermissionManager::eNotify,
2519 0 : nsPermissionManager::eNoDBOperation);
2520 : #endif
2521 :
2522 0 : return IPC_OK();
2523 : }
2524 :
2525 : mozilla::ipc::IPCResult
2526 0 : ContentChild::RecvFlushMemory(const nsString& reason)
2527 : {
2528 : nsCOMPtr<nsIObserverService> os =
2529 0 : mozilla::services::GetObserverService();
2530 0 : if (os) {
2531 0 : os->NotifyObservers(nullptr, "memory-pressure", reason.get());
2532 : }
2533 0 : return IPC_OK();
2534 : }
2535 :
2536 : mozilla::ipc::IPCResult
2537 0 : ContentChild::RecvActivateA11y(const uint32_t& aMainChromeTid,
2538 : const uint32_t& aMsaaID)
2539 : {
2540 : #ifdef ACCESSIBILITY
2541 : #ifdef XP_WIN
2542 : MOZ_ASSERT(aMainChromeTid != 0);
2543 : mMainChromeTid = aMainChromeTid;
2544 :
2545 : MOZ_ASSERT(aMsaaID != 0);
2546 : mMsaaID = aMsaaID;
2547 : #endif // XP_WIN
2548 :
2549 : // Start accessibility in content process if it's running in chrome
2550 : // process.
2551 0 : GetOrCreateAccService(nsAccessibilityService::eMainProcess);
2552 : #endif // ACCESSIBILITY
2553 0 : return IPC_OK();
2554 : }
2555 :
2556 : mozilla::ipc::IPCResult
2557 0 : ContentChild::RecvShutdownA11y()
2558 : {
2559 : #ifdef ACCESSIBILITY
2560 : // Try to shutdown accessibility in content process if it's shutting down in
2561 : // chrome process.
2562 0 : MaybeShutdownAccService(nsAccessibilityService::eMainProcess);
2563 : #endif
2564 0 : return IPC_OK();
2565 : }
2566 :
2567 : mozilla::ipc::IPCResult
2568 0 : ContentChild::RecvGarbageCollect()
2569 : {
2570 : // Rebroadcast the "child-gc-request" so that workers will GC.
2571 0 : nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
2572 0 : if (obs) {
2573 0 : obs->NotifyObservers(nullptr, "child-gc-request", nullptr);
2574 : }
2575 0 : nsJSContext::GarbageCollectNow(JS::gcreason::DOM_IPC);
2576 0 : return IPC_OK();
2577 : }
2578 :
2579 : mozilla::ipc::IPCResult
2580 0 : ContentChild::RecvCycleCollect()
2581 : {
2582 : // Rebroadcast the "child-cc-request" so that workers will CC.
2583 0 : nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
2584 0 : if (obs) {
2585 0 : obs->NotifyObservers(nullptr, "child-cc-request", nullptr);
2586 : }
2587 0 : nsJSContext::CycleCollectNow();
2588 0 : return IPC_OK();
2589 : }
2590 :
2591 : mozilla::ipc::IPCResult
2592 2 : ContentChild::RecvAppInfo(const nsCString& version, const nsCString& buildID,
2593 : const nsCString& name, const nsCString& UAName,
2594 : const nsCString& ID, const nsCString& vendor)
2595 : {
2596 2 : mAppInfo.version.Assign(version);
2597 2 : mAppInfo.buildID.Assign(buildID);
2598 2 : mAppInfo.name.Assign(name);
2599 2 : mAppInfo.UAName.Assign(UAName);
2600 2 : mAppInfo.ID.Assign(ID);
2601 2 : mAppInfo.vendor.Assign(vendor);
2602 :
2603 2 : return IPC_OK();
2604 : }
2605 :
2606 : mozilla::ipc::IPCResult
2607 2 : ContentChild::RecvRemoteType(const nsString& aRemoteType)
2608 : {
2609 2 : MOZ_ASSERT(DOMStringIsNull(mRemoteType));
2610 :
2611 2 : mRemoteType.Assign(aRemoteType);
2612 2 : return IPC_OK();
2613 : }
2614 :
2615 : const nsAString&
2616 4 : ContentChild::GetRemoteType() const
2617 : {
2618 4 : return mRemoteType;
2619 : }
2620 :
2621 : mozilla::ipc::IPCResult
2622 2 : ContentChild::RecvInitServiceWorkers(const ServiceWorkerConfiguration& aConfig)
2623 : {
2624 4 : RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
2625 2 : if (!swm) {
2626 : // browser shutdown began
2627 0 : return IPC_OK();
2628 : }
2629 2 : swm->LoadRegistrations(aConfig.serviceWorkerRegistrations());
2630 2 : return IPC_OK();
2631 : }
2632 :
2633 : mozilla::ipc::IPCResult
2634 2 : ContentChild::RecvInitBlobURLs(nsTArray<BlobURLRegistrationData>&& aRegistrations)
2635 : {
2636 2 : for (uint32_t i = 0; i < aRegistrations.Length(); ++i) {
2637 0 : BlobURLRegistrationData& registration = aRegistrations[i];
2638 0 : RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(registration.blob());
2639 0 : MOZ_ASSERT(blobImpl);
2640 :
2641 0 : nsHostObjectProtocolHandler::AddDataEntry(registration.url(),
2642 0 : registration.principal(),
2643 0 : blobImpl);
2644 : }
2645 :
2646 2 : return IPC_OK();
2647 : }
2648 :
2649 : mozilla::ipc::IPCResult
2650 0 : ContentChild::RecvLastPrivateDocShellDestroyed()
2651 : {
2652 0 : nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
2653 0 : obs->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
2654 0 : return IPC_OK();
2655 : }
2656 :
2657 : mozilla::ipc::IPCResult
2658 0 : ContentChild::RecvNotifyProcessPriorityChanged(
2659 : const hal::ProcessPriority& aPriority)
2660 : {
2661 0 : nsCOMPtr<nsIObserverService> os = services::GetObserverService();
2662 0 : NS_ENSURE_TRUE(os, IPC_OK());
2663 :
2664 0 : RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
2665 0 : props->SetPropertyAsInt32(NS_LITERAL_STRING("priority"),
2666 0 : static_cast<int32_t>(aPriority));
2667 :
2668 0 : os->NotifyObservers(static_cast<nsIPropertyBag2*>(props),
2669 0 : "ipc:process-priority-changed", nullptr);
2670 0 : return IPC_OK();
2671 : }
2672 :
2673 : mozilla::ipc::IPCResult
2674 0 : ContentChild::RecvMinimizeMemoryUsage()
2675 : {
2676 : nsCOMPtr<nsIMemoryReporterManager> mgr =
2677 0 : do_GetService("@mozilla.org/memory-reporter-manager;1");
2678 0 : NS_ENSURE_TRUE(mgr, IPC_OK());
2679 :
2680 0 : Unused << mgr->MinimizeMemoryUsage(/* callback = */ nullptr);
2681 0 : return IPC_OK();
2682 : }
2683 :
2684 : void
2685 0 : ContentChild::AddIdleObserver(nsIObserver* aObserver, uint32_t aIdleTimeInS)
2686 : {
2687 0 : MOZ_ASSERT(aObserver, "null idle observer");
2688 : // Make sure aObserver isn't released while we wait for the parent
2689 0 : aObserver->AddRef();
2690 0 : SendAddIdleObserver(reinterpret_cast<uint64_t>(aObserver), aIdleTimeInS);
2691 0 : mIdleObservers.PutEntry(aObserver);
2692 0 : }
2693 :
2694 : void
2695 0 : ContentChild::RemoveIdleObserver(nsIObserver* aObserver, uint32_t aIdleTimeInS)
2696 : {
2697 0 : MOZ_ASSERT(aObserver, "null idle observer");
2698 0 : SendRemoveIdleObserver(reinterpret_cast<uint64_t>(aObserver), aIdleTimeInS);
2699 0 : aObserver->Release();
2700 0 : mIdleObservers.RemoveEntry(aObserver);
2701 0 : }
2702 :
2703 : mozilla::ipc::IPCResult
2704 0 : ContentChild::RecvNotifyIdleObserver(const uint64_t& aObserver,
2705 : const nsCString& aTopic,
2706 : const nsString& aTimeStr)
2707 : {
2708 0 : nsIObserver* observer = reinterpret_cast<nsIObserver*>(aObserver);
2709 0 : if (mIdleObservers.Contains(observer)) {
2710 0 : observer->Observe(nullptr, aTopic.get(), aTimeStr.get());
2711 : } else {
2712 0 : NS_WARNING("Received notification for an idle observer that was removed.");
2713 : }
2714 0 : return IPC_OK();
2715 : }
2716 :
2717 : mozilla::ipc::IPCResult
2718 2 : ContentChild::RecvLoadAndRegisterSheet(const URIParams& aURI, const uint32_t& aType)
2719 : {
2720 4 : nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
2721 2 : if (!uri) {
2722 0 : return IPC_OK();
2723 : }
2724 :
2725 2 : nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
2726 2 : if (sheetService) {
2727 2 : sheetService->LoadAndRegisterSheet(uri, aType);
2728 : }
2729 :
2730 2 : return IPC_OK();
2731 : }
2732 :
2733 : mozilla::ipc::IPCResult
2734 0 : ContentChild::RecvUnregisterSheet(const URIParams& aURI, const uint32_t& aType)
2735 : {
2736 0 : nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
2737 0 : if (!uri) {
2738 0 : return IPC_OK();
2739 : }
2740 :
2741 0 : nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
2742 0 : if (sheetService) {
2743 0 : sheetService->UnregisterSheet(uri, aType);
2744 : }
2745 :
2746 0 : return IPC_OK();
2747 : }
2748 :
2749 : POfflineCacheUpdateChild*
2750 0 : ContentChild::AllocPOfflineCacheUpdateChild(const URIParams& manifestURI,
2751 : const URIParams& documentURI,
2752 : const PrincipalInfo& aLoadingPrincipalInfo,
2753 : const bool& stickDocument)
2754 : {
2755 0 : MOZ_CRASH("unused");
2756 : return nullptr;
2757 : }
2758 :
2759 : bool
2760 0 : ContentChild::DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* actor)
2761 : {
2762 : OfflineCacheUpdateChild* offlineCacheUpdate =
2763 0 : static_cast<OfflineCacheUpdateChild*>(actor);
2764 0 : NS_RELEASE(offlineCacheUpdate);
2765 0 : return true;
2766 : }
2767 :
2768 : mozilla::ipc::IPCResult
2769 0 : ContentChild::RecvDomainSetChanged(const uint32_t& aSetType,
2770 : const uint32_t& aChangeType,
2771 : const OptionalURIParams& aDomain)
2772 : {
2773 0 : if (aChangeType == ACTIVATE_POLICY) {
2774 0 : if (mPolicy) {
2775 0 : return IPC_OK();
2776 : }
2777 0 : nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
2778 0 : MOZ_ASSERT(ssm);
2779 0 : ssm->ActivateDomainPolicyInternal(getter_AddRefs(mPolicy));
2780 0 : if (!mPolicy) {
2781 0 : return IPC_FAIL_NO_REASON(this);
2782 : }
2783 0 : return IPC_OK();
2784 : }
2785 0 : if (!mPolicy) {
2786 0 : MOZ_ASSERT_UNREACHABLE("If the domain policy is not active yet,"
2787 : " the first message should be ACTIVATE_POLICY");
2788 : return IPC_FAIL_NO_REASON(this);
2789 : }
2790 :
2791 0 : NS_ENSURE_TRUE(mPolicy, IPC_FAIL_NO_REASON(this));
2792 :
2793 0 : if (aChangeType == DEACTIVATE_POLICY) {
2794 0 : mPolicy->Deactivate();
2795 0 : mPolicy = nullptr;
2796 0 : return IPC_OK();
2797 : }
2798 :
2799 0 : nsCOMPtr<nsIDomainSet> set;
2800 0 : switch(aSetType) {
2801 : case BLACKLIST:
2802 0 : mPolicy->GetBlacklist(getter_AddRefs(set));
2803 0 : break;
2804 : case SUPER_BLACKLIST:
2805 0 : mPolicy->GetSuperBlacklist(getter_AddRefs(set));
2806 0 : break;
2807 : case WHITELIST:
2808 0 : mPolicy->GetWhitelist(getter_AddRefs(set));
2809 0 : break;
2810 : case SUPER_WHITELIST:
2811 0 : mPolicy->GetSuperWhitelist(getter_AddRefs(set));
2812 0 : break;
2813 : default:
2814 0 : NS_NOTREACHED("Unexpected setType");
2815 0 : return IPC_FAIL_NO_REASON(this);
2816 : }
2817 :
2818 0 : MOZ_ASSERT(set);
2819 :
2820 0 : nsCOMPtr<nsIURI> uri = DeserializeURI(aDomain);
2821 :
2822 0 : switch(aChangeType) {
2823 : case ADD_DOMAIN:
2824 0 : NS_ENSURE_TRUE(uri, IPC_FAIL_NO_REASON(this));
2825 0 : set->Add(uri);
2826 0 : break;
2827 : case REMOVE_DOMAIN:
2828 0 : NS_ENSURE_TRUE(uri, IPC_FAIL_NO_REASON(this));
2829 0 : set->Remove(uri);
2830 0 : break;
2831 : case CLEAR_DOMAINS:
2832 0 : set->Clear();
2833 0 : break;
2834 : default:
2835 0 : NS_NOTREACHED("Unexpected changeType");
2836 0 : return IPC_FAIL_NO_REASON(this);
2837 : }
2838 :
2839 0 : return IPC_OK();
2840 : }
2841 :
2842 : void
2843 0 : ContentChild::StartForceKillTimer()
2844 : {
2845 0 : if (mForceKillTimer) {
2846 0 : return;
2847 : }
2848 :
2849 0 : int32_t timeoutSecs = Preferences::GetInt("dom.ipc.tabs.shutdownTimeoutSecs", 5);
2850 0 : if (timeoutSecs > 0) {
2851 0 : mForceKillTimer = do_CreateInstance("@mozilla.org/timer;1");
2852 0 : MOZ_ASSERT(mForceKillTimer);
2853 0 : mForceKillTimer->InitWithNamedFuncCallback(
2854 : ContentChild::ForceKillTimerCallback,
2855 : this,
2856 0 : timeoutSecs * 1000,
2857 : nsITimer::TYPE_ONE_SHOT,
2858 0 : "dom::ContentChild::StartForceKillTimer");
2859 : }
2860 : }
2861 :
2862 : /* static */ void
2863 0 : ContentChild::ForceKillTimerCallback(nsITimer* aTimer, void* aClosure)
2864 : {
2865 0 : ProcessChild::QuickExit();
2866 0 : }
2867 :
2868 : mozilla::ipc::IPCResult
2869 0 : ContentChild::RecvShutdown()
2870 : {
2871 : // If we receive the shutdown message from within a nested event loop, we want
2872 : // to wait for that event loop to finish. Otherwise we could prematurely
2873 : // terminate an "unload" or "pagehide" event handler (which might be doing a
2874 : // sync XHR, for example).
2875 : #if defined(MOZ_CRASHREPORTER)
2876 0 : CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"),
2877 0 : NS_LITERAL_CSTRING("RecvShutdown"));
2878 : #endif
2879 0 : nsCOMPtr<nsIThread> thread;
2880 0 : nsresult rv = NS_GetMainThread(getter_AddRefs(thread));
2881 0 : if (NS_SUCCEEDED(rv) && thread) {
2882 0 : RefPtr<nsThread> mainThread(thread.forget().downcast<nsThread>());
2883 0 : if (mainThread->RecursionDepth() > 1) {
2884 : // We're in a nested event loop. Let's delay for an arbitrary period of
2885 : // time (100ms) in the hopes that the event loop will have finished by
2886 : // then.
2887 0 : MessageLoop::current()->PostDelayedTask(
2888 0 : NewRunnableMethod(
2889 : "dom::ContentChild::RecvShutdown", this, &ContentChild::RecvShutdown),
2890 0 : 100);
2891 0 : return IPC_OK();
2892 : }
2893 : }
2894 :
2895 0 : mShuttingDown = true;
2896 :
2897 0 : if (mPolicy) {
2898 0 : mPolicy->Deactivate();
2899 0 : mPolicy = nullptr;
2900 : }
2901 :
2902 0 : nsCOMPtr<nsIObserverService> os = services::GetObserverService();
2903 0 : if (os) {
2904 0 : os->NotifyObservers(static_cast<nsIContentChild*>(this),
2905 0 : "content-child-shutdown", nullptr);
2906 : }
2907 :
2908 : #if defined(XP_WIN)
2909 : mozilla::widget::StopAudioSession();
2910 : #endif
2911 :
2912 0 : GetIPCChannel()->SetAbortOnError(false);
2913 :
2914 : #ifdef MOZ_GECKO_PROFILER
2915 0 : if (mProfilerController) {
2916 0 : nsCString shutdownProfile = mProfilerController->GrabShutdownProfileAndShutdown();
2917 0 : mProfilerController = nullptr;
2918 : // Send the shutdown profile to the parent process through our own
2919 : // message channel, which we know will survive for long enough.
2920 0 : Unused << SendShutdownProfile(shutdownProfile);
2921 : }
2922 : #endif
2923 :
2924 : // Start a timer that will insure we quickly exit after a reasonable
2925 : // period of time. Prevents shutdown hangs after our connection to the
2926 : // parent closes.
2927 0 : StartForceKillTimer();
2928 :
2929 : #if defined(MOZ_CRASHREPORTER)
2930 0 : CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"),
2931 0 : NS_LITERAL_CSTRING("SendFinishShutdown"));
2932 : #endif
2933 : // Ignore errors here. If this fails, the parent will kill us after a
2934 : // timeout.
2935 0 : Unused << SendFinishShutdown();
2936 0 : return IPC_OK();
2937 : }
2938 :
2939 : PBrowserOrId
2940 3 : ContentChild::GetBrowserOrId(TabChild* aTabChild)
2941 : {
2942 6 : if (!aTabChild ||
2943 3 : this == aTabChild->Manager()) {
2944 3 : return PBrowserOrId(aTabChild);
2945 : }
2946 0 : return PBrowserOrId(aTabChild->GetTabId());
2947 : }
2948 :
2949 : mozilla::ipc::IPCResult
2950 0 : ContentChild::RecvUpdateWindow(const uintptr_t& aChildId)
2951 : {
2952 : #if defined(XP_WIN)
2953 : NS_ASSERTION(aChildId, "Expected child hwnd value for remote plugin instance.");
2954 : mozilla::plugins::PluginInstanceParent* parentInstance =
2955 : mozilla::plugins::PluginInstanceParent::LookupPluginInstanceByID(aChildId);
2956 : if (parentInstance) {
2957 : // sync! update call to the plugin instance that forces the
2958 : // plugin to paint its child window.
2959 : parentInstance->CallUpdateWindow();
2960 : }
2961 : return IPC_OK();
2962 : #else
2963 0 : MOZ_ASSERT(false, "ContentChild::RecvUpdateWindow calls unexpected on this platform.");
2964 : return IPC_FAIL_NO_REASON(this);
2965 : #endif
2966 : }
2967 :
2968 : PContentPermissionRequestChild*
2969 0 : ContentChild::AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionRequest>& aRequests,
2970 : const IPC::Principal& aPrincipal,
2971 : const TabId& aTabId)
2972 : {
2973 0 : MOZ_CRASH("unused");
2974 : return nullptr;
2975 : }
2976 :
2977 : bool
2978 0 : ContentChild::DeallocPContentPermissionRequestChild(PContentPermissionRequestChild* actor)
2979 : {
2980 0 : nsContentPermissionUtils::NotifyRemoveContentPermissionRequestChild(actor);
2981 0 : auto child = static_cast<RemotePermissionRequest*>(actor);
2982 0 : child->IPDLRelease();
2983 0 : return true;
2984 : }
2985 :
2986 : PWebBrowserPersistDocumentChild*
2987 0 : ContentChild::AllocPWebBrowserPersistDocumentChild(PBrowserChild* aBrowser,
2988 : const uint64_t& aOuterWindowID)
2989 : {
2990 0 : return new WebBrowserPersistDocumentChild();
2991 : }
2992 :
2993 : mozilla::ipc::IPCResult
2994 0 : ContentChild::RecvPWebBrowserPersistDocumentConstructor(PWebBrowserPersistDocumentChild *aActor,
2995 : PBrowserChild* aBrowser,
2996 : const uint64_t& aOuterWindowID)
2997 : {
2998 0 : if (NS_WARN_IF(!aBrowser)) {
2999 0 : return IPC_FAIL_NO_REASON(this);
3000 : }
3001 : nsCOMPtr<nsIDocument> rootDoc =
3002 0 : static_cast<TabChild*>(aBrowser)->GetDocument();
3003 0 : nsCOMPtr<nsIDocument> foundDoc;
3004 0 : if (aOuterWindowID) {
3005 0 : foundDoc = nsContentUtils::GetSubdocumentWithOuterWindowId(rootDoc, aOuterWindowID);
3006 : } else {
3007 0 : foundDoc = rootDoc;
3008 : }
3009 :
3010 0 : if (!foundDoc) {
3011 0 : aActor->SendInitFailure(NS_ERROR_NO_CONTENT);
3012 : } else {
3013 0 : static_cast<WebBrowserPersistDocumentChild*>(aActor)->Start(foundDoc);
3014 : }
3015 0 : return IPC_OK();
3016 : }
3017 :
3018 : bool
3019 0 : ContentChild::DeallocPWebBrowserPersistDocumentChild(PWebBrowserPersistDocumentChild* aActor)
3020 : {
3021 0 : delete aActor;
3022 0 : return true;
3023 : }
3024 :
3025 : mozilla::ipc::IPCResult
3026 0 : ContentChild::RecvSetAudioSessionData(const nsID& aId,
3027 : const nsString& aDisplayName,
3028 : const nsString& aIconPath)
3029 : {
3030 : #if defined(XP_WIN)
3031 : if (NS_FAILED(mozilla::widget::RecvAudioSessionData(aId, aDisplayName,
3032 : aIconPath))) {
3033 : return IPC_OK();
3034 : }
3035 :
3036 : // Ignore failures here; we can't really do anything about them
3037 : mozilla::widget::StartAudioSession();
3038 : return IPC_OK();
3039 : #else
3040 0 : NS_RUNTIMEABORT("Not Reached!");
3041 0 : return IPC_FAIL_NO_REASON(this);
3042 : #endif
3043 : }
3044 :
3045 : // This code goes here rather than nsGlobalWindow.cpp because nsGlobalWindow.cpp
3046 : // can't include ContentChild.h since it includes windows.h.
3047 :
3048 : static uint64_t gNextWindowID = 0;
3049 :
3050 : // We use only 53 bits for the window ID so that it can be converted to and from
3051 : // a JS value without loss of precision. The upper bits of the window ID hold the
3052 : // process ID. The lower bits identify the window.
3053 : static const uint64_t kWindowIDTotalBits = 53;
3054 : static const uint64_t kWindowIDProcessBits = 22;
3055 : static const uint64_t kWindowIDWindowBits = kWindowIDTotalBits - kWindowIDProcessBits;
3056 :
3057 : // Try to return a window ID that is unique across processes and that will never
3058 : // be recycled.
3059 : uint64_t
3060 12 : NextWindowID()
3061 : {
3062 12 : uint64_t processID = 0;
3063 12 : if (XRE_IsContentProcess()) {
3064 3 : ContentChild* cc = ContentChild::GetSingleton();
3065 3 : processID = cc->GetID();
3066 : }
3067 :
3068 12 : MOZ_RELEASE_ASSERT(processID < (uint64_t(1) << kWindowIDProcessBits));
3069 12 : uint64_t processBits = processID & ((uint64_t(1) << kWindowIDProcessBits) - 1);
3070 :
3071 : // Make sure no actual window ends up with mWindowID == 0.
3072 12 : uint64_t windowID = ++gNextWindowID;
3073 :
3074 12 : MOZ_RELEASE_ASSERT(windowID < (uint64_t(1) << kWindowIDWindowBits));
3075 12 : uint64_t windowBits = windowID & ((uint64_t(1) << kWindowIDWindowBits) - 1);
3076 :
3077 12 : return (processBits << kWindowIDWindowBits) | windowBits;
3078 : }
3079 :
3080 : mozilla::ipc::IPCResult
3081 0 : ContentChild::RecvInvokeDragSession(nsTArray<IPCDataTransfer>&& aTransfers,
3082 : const uint32_t& aAction)
3083 : {
3084 : nsCOMPtr<nsIDragService> dragService =
3085 0 : do_GetService("@mozilla.org/widget/dragservice;1");
3086 0 : if (dragService) {
3087 0 : dragService->StartDragSession();
3088 0 : nsCOMPtr<nsIDragSession> session;
3089 0 : dragService->GetCurrentSession(getter_AddRefs(session));
3090 0 : if (session) {
3091 0 : session->SetDragAction(aAction);
3092 : // Check if we are receiving any file objects. If we are we will want
3093 : // to hide any of the other objects coming in from content.
3094 0 : bool hasFiles = false;
3095 0 : for (uint32_t i = 0; i < aTransfers.Length() && !hasFiles; ++i) {
3096 0 : auto& items = aTransfers[i].items();
3097 0 : for (uint32_t j = 0; j < items.Length() && !hasFiles; ++j) {
3098 0 : if (items[j].data().type() == IPCDataTransferData::TIPCBlob) {
3099 0 : hasFiles = true;
3100 : }
3101 : }
3102 : }
3103 :
3104 : // Add the entries from the IPC to the new DataTransfer
3105 : nsCOMPtr<DataTransfer> dataTransfer =
3106 0 : new DataTransfer(nullptr, eDragStart, false, -1);
3107 0 : for (uint32_t i = 0; i < aTransfers.Length(); ++i) {
3108 0 : auto& items = aTransfers[i].items();
3109 0 : for (uint32_t j = 0; j < items.Length(); ++j) {
3110 0 : const IPCDataTransferItem& item = items[j];
3111 0 : RefPtr<nsVariantCC> variant = new nsVariantCC();
3112 0 : if (item.data().type() == IPCDataTransferData::TnsString) {
3113 0 : const nsString& data = item.data().get_nsString();
3114 0 : variant->SetAsAString(data);
3115 0 : } else if (item.data().type() == IPCDataTransferData::TShmem) {
3116 0 : Shmem data = item.data().get_Shmem();
3117 0 : variant->SetAsACString(nsDependentCString(data.get<char>(), data.Size<char>()));
3118 0 : Unused << DeallocShmem(data);
3119 0 : } else if (item.data().type() == IPCDataTransferData::TIPCBlob) {
3120 : RefPtr<BlobImpl> blobImpl =
3121 0 : IPCBlobUtils::Deserialize(item.data().get_IPCBlob());
3122 0 : variant->SetAsISupports(blobImpl);
3123 : } else {
3124 0 : continue;
3125 : }
3126 : // We should hide this data from content if we have a file, and we aren't a file.
3127 0 : bool hidden = hasFiles && item.data().type() != IPCDataTransferData::TIPCBlob;
3128 0 : dataTransfer->SetDataWithPrincipalFromOtherProcess(
3129 0 : NS_ConvertUTF8toUTF16(item.flavor()), variant, i,
3130 0 : nsContentUtils::GetSystemPrincipal(), hidden);
3131 : }
3132 : }
3133 0 : session->SetDataTransfer(dataTransfer);
3134 : }
3135 : }
3136 0 : return IPC_OK();
3137 : }
3138 :
3139 : mozilla::ipc::IPCResult
3140 0 : ContentChild::RecvEndDragSession(const bool& aDoneDrag,
3141 : const bool& aUserCancelled,
3142 : const LayoutDeviceIntPoint& aDragEndPoint,
3143 : const uint32_t& aKeyModifiers)
3144 : {
3145 : nsCOMPtr<nsIDragService> dragService =
3146 0 : do_GetService("@mozilla.org/widget/dragservice;1");
3147 0 : if (dragService) {
3148 0 : if (aUserCancelled) {
3149 0 : nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
3150 0 : if (dragSession) {
3151 0 : dragSession->UserCancelled();
3152 : }
3153 : }
3154 0 : static_cast<nsBaseDragService*>(dragService.get())->SetDragEndPoint(aDragEndPoint);
3155 0 : dragService->EndDragSession(aDoneDrag, aKeyModifiers);
3156 : }
3157 0 : return IPC_OK();
3158 : }
3159 :
3160 : mozilla::ipc::IPCResult
3161 0 : ContentChild::RecvPush(const nsCString& aScope,
3162 : const IPC::Principal& aPrincipal,
3163 : const nsString& aMessageId)
3164 : {
3165 0 : PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Nothing());
3166 0 : Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
3167 0 : return IPC_OK();
3168 : }
3169 :
3170 : mozilla::ipc::IPCResult
3171 0 : ContentChild::RecvPushWithData(const nsCString& aScope,
3172 : const IPC::Principal& aPrincipal,
3173 : const nsString& aMessageId,
3174 : InfallibleTArray<uint8_t>&& aData)
3175 : {
3176 0 : PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Some(aData));
3177 0 : Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
3178 0 : return IPC_OK();
3179 : }
3180 :
3181 : mozilla::ipc::IPCResult
3182 0 : ContentChild::RecvPushSubscriptionChange(const nsCString& aScope,
3183 : const IPC::Principal& aPrincipal)
3184 : {
3185 0 : PushSubscriptionChangeDispatcher dispatcher(aScope, aPrincipal);
3186 0 : Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
3187 0 : return IPC_OK();
3188 : }
3189 :
3190 : mozilla::ipc::IPCResult
3191 0 : ContentChild::RecvPushError(const nsCString& aScope, const IPC::Principal& aPrincipal,
3192 : const nsString& aMessage, const uint32_t& aFlags)
3193 : {
3194 0 : PushErrorDispatcher dispatcher(aScope, aPrincipal, aMessage, aFlags);
3195 0 : Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
3196 0 : return IPC_OK();
3197 : }
3198 :
3199 : mozilla::ipc::IPCResult
3200 0 : ContentChild::RecvNotifyPushSubscriptionModifiedObservers(const nsCString& aScope,
3201 : const IPC::Principal& aPrincipal)
3202 : {
3203 0 : PushSubscriptionModifiedDispatcher dispatcher(aScope, aPrincipal);
3204 0 : Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
3205 0 : return IPC_OK();
3206 : }
3207 :
3208 : mozilla::ipc::IPCResult
3209 0 : ContentChild::RecvBlobURLRegistration(const nsCString& aURI,
3210 : const IPCBlob& aBlob,
3211 : const IPC::Principal& aPrincipal)
3212 : {
3213 0 : RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(aBlob);
3214 0 : MOZ_ASSERT(blobImpl);
3215 :
3216 0 : nsHostObjectProtocolHandler::AddDataEntry(aURI, aPrincipal, blobImpl);
3217 0 : return IPC_OK();
3218 : }
3219 :
3220 : mozilla::ipc::IPCResult
3221 0 : ContentChild::RecvBlobURLUnregistration(const nsCString& aURI)
3222 : {
3223 0 : nsHostObjectProtocolHandler::RemoveDataEntry(aURI,
3224 0 : /* aBroadcastToOtherProcesses = */ false);
3225 0 : return IPC_OK();
3226 : }
3227 :
3228 : mozilla::ipc::IPCResult
3229 0 : ContentChild::RecvDispatchLocalStorageChange(const nsString& aDocumentURI,
3230 : const nsString& aKey,
3231 : const nsString& aOldValue,
3232 : const nsString& aNewValue,
3233 : const IPC::Principal& aPrincipal,
3234 : const bool& aIsPrivate)
3235 : {
3236 0 : LocalStorage::DispatchStorageEvent(aDocumentURI, aKey, aOldValue, aNewValue,
3237 0 : aPrincipal, aIsPrivate, nullptr, true);
3238 0 : return IPC_OK();
3239 : }
3240 :
3241 : #if defined(XP_WIN) && defined(ACCESSIBILITY)
3242 : bool
3243 : ContentChild::SendGetA11yContentId()
3244 : {
3245 : return PContentChild::SendGetA11yContentId(&mMsaaID);
3246 : }
3247 : #endif // defined(XP_WIN) && defined(ACCESSIBILITY)
3248 :
3249 : void
3250 0 : ContentChild::CreateGetFilesRequest(const nsAString& aDirectoryPath,
3251 : bool aRecursiveFlag,
3252 : nsID& aUUID,
3253 : GetFilesHelperChild* aChild)
3254 : {
3255 0 : MOZ_ASSERT(aChild);
3256 0 : MOZ_ASSERT(!mGetFilesPendingRequests.GetWeak(aUUID));
3257 :
3258 0 : Unused << SendGetFilesRequest(aUUID, nsString(aDirectoryPath),
3259 : aRecursiveFlag);
3260 0 : mGetFilesPendingRequests.Put(aUUID, aChild);
3261 0 : }
3262 :
3263 : void
3264 0 : ContentChild::DeleteGetFilesRequest(nsID& aUUID, GetFilesHelperChild* aChild)
3265 : {
3266 0 : MOZ_ASSERT(aChild);
3267 0 : MOZ_ASSERT(mGetFilesPendingRequests.GetWeak(aUUID));
3268 :
3269 0 : Unused << SendDeleteGetFilesRequest(aUUID);
3270 0 : mGetFilesPendingRequests.Remove(aUUID);
3271 0 : }
3272 :
3273 : mozilla::ipc::IPCResult
3274 0 : ContentChild::RecvGetFilesResponse(const nsID& aUUID,
3275 : const GetFilesResponseResult& aResult)
3276 : {
3277 0 : GetFilesHelperChild* child = mGetFilesPendingRequests.GetWeak(aUUID);
3278 : // This object can already been deleted in case DeleteGetFilesRequest has
3279 : // been called when the response was sending by the parent.
3280 0 : if (!child) {
3281 0 : return IPC_OK();
3282 : }
3283 :
3284 0 : if (aResult.type() == GetFilesResponseResult::TGetFilesResponseFailure) {
3285 0 : child->Finished(aResult.get_GetFilesResponseFailure().errorCode());
3286 : } else {
3287 0 : MOZ_ASSERT(aResult.type() == GetFilesResponseResult::TGetFilesResponseSuccess);
3288 :
3289 : const nsTArray<IPCBlob>& ipcBlobs =
3290 0 : aResult.get_GetFilesResponseSuccess().blobs();
3291 :
3292 0 : bool succeeded = true;
3293 0 : for (uint32_t i = 0; succeeded && i < ipcBlobs.Length(); ++i) {
3294 0 : RefPtr<BlobImpl> impl = IPCBlobUtils::Deserialize(ipcBlobs[i]);
3295 0 : succeeded = child->AppendBlobImpl(impl);
3296 : }
3297 :
3298 0 : child->Finished(succeeded ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
3299 : }
3300 :
3301 0 : mGetFilesPendingRequests.Remove(aUUID);
3302 0 : return IPC_OK();
3303 : }
3304 :
3305 : /* static */ void
3306 0 : ContentChild::FatalErrorIfNotUsingGPUProcess(const char* const aProtocolName,
3307 : const char* const aErrorMsg,
3308 : base::ProcessId aOtherPid)
3309 : {
3310 : // If we're communicating with the same process or the UI process then we
3311 : // want to crash normally. Otherwise we want to just warn as the other end
3312 : // must be the GPU process and it crashing shouldn't be fatal for us.
3313 0 : if (aOtherPid == base::GetCurrentProcId() ||
3314 0 : (GetSingleton() && GetSingleton()->OtherPid() == aOtherPid)) {
3315 0 : mozilla::ipc::FatalError(aProtocolName, aErrorMsg, false);
3316 : } else {
3317 0 : nsAutoCString formattedMessage("IPDL error [");
3318 0 : formattedMessage.AppendASCII(aProtocolName);
3319 0 : formattedMessage.AppendLiteral(R"(]: ")");
3320 0 : formattedMessage.AppendASCII(aErrorMsg);
3321 0 : formattedMessage.AppendLiteral(R"(".)");
3322 0 : NS_WARNING(formattedMessage.get());
3323 : }
3324 0 : }
3325 :
3326 : PURLClassifierChild*
3327 0 : ContentChild::AllocPURLClassifierChild(const Principal& aPrincipal,
3328 : const bool& aUseTrackingProtection,
3329 : bool* aSuccess)
3330 : {
3331 0 : *aSuccess = true;
3332 0 : return new URLClassifierChild();
3333 : }
3334 :
3335 : bool
3336 0 : ContentChild::DeallocPURLClassifierChild(PURLClassifierChild* aActor)
3337 : {
3338 0 : MOZ_ASSERT(aActor);
3339 0 : delete aActor;
3340 0 : return true;
3341 : }
3342 :
3343 : PURLClassifierLocalChild*
3344 0 : ContentChild::AllocPURLClassifierLocalChild(const URIParams& aUri,
3345 : const nsCString& aTables)
3346 : {
3347 0 : return new URLClassifierLocalChild();
3348 : }
3349 :
3350 : bool
3351 0 : ContentChild::DeallocPURLClassifierLocalChild(PURLClassifierLocalChild* aActor)
3352 : {
3353 0 : MOZ_ASSERT(aActor);
3354 0 : delete aActor;
3355 0 : return true;
3356 : }
3357 :
3358 : // The IPC code will call this method asking us to assign an event target to new
3359 : // actors created by the ContentParent.
3360 : already_AddRefed<nsIEventTarget>
3361 3 : ContentChild::GetConstructedEventTarget(const Message& aMsg)
3362 : {
3363 : // Currently we only set targets for PBrowser.
3364 3 : if (aMsg.type() != PContent::Msg_PBrowserConstructor__ID) {
3365 2 : return nullptr;
3366 : }
3367 :
3368 1 : return nsIContentChild::GetConstructedEventTarget(aMsg);
3369 : }
3370 :
3371 : void
3372 0 : ContentChild::FileCreationRequest(nsID& aUUID, FileCreatorHelper* aHelper,
3373 : const nsAString& aFullPath,
3374 : const nsAString& aType,
3375 : const nsAString& aName,
3376 : const Optional<int64_t>& aLastModified,
3377 : bool aExistenceCheck,
3378 : bool aIsFromNsIFile)
3379 : {
3380 0 : MOZ_ASSERT(aHelper);
3381 :
3382 0 : bool lastModifiedPassed = false;
3383 0 : int64_t lastModified = 0;
3384 0 : if (aLastModified.WasPassed()) {
3385 0 : lastModifiedPassed = true;
3386 0 : lastModified = aLastModified.Value();
3387 : }
3388 :
3389 0 : Unused << SendFileCreationRequest(aUUID, nsString(aFullPath), nsString(aType),
3390 0 : nsString(aName), lastModifiedPassed,
3391 : lastModified, aExistenceCheck,
3392 : aIsFromNsIFile);
3393 0 : mFileCreationPending.Put(aUUID, aHelper);
3394 0 : }
3395 :
3396 : mozilla::ipc::IPCResult
3397 0 : ContentChild::RecvFileCreationResponse(const nsID& aUUID,
3398 : const FileCreationResult& aResult)
3399 : {
3400 0 : FileCreatorHelper* helper = mFileCreationPending.GetWeak(aUUID);
3401 0 : if (!helper) {
3402 0 : return IPC_FAIL_NO_REASON(this);
3403 : }
3404 :
3405 0 : if (aResult.type() == FileCreationResult::TFileCreationErrorResult) {
3406 0 : helper->ResponseReceived(nullptr,
3407 0 : aResult.get_FileCreationErrorResult().errorCode());
3408 : } else {
3409 0 : MOZ_ASSERT(aResult.type() == FileCreationResult::TFileCreationSuccessResult);
3410 :
3411 : RefPtr<BlobImpl> impl =
3412 0 : IPCBlobUtils::Deserialize(aResult.get_FileCreationSuccessResult().blob());
3413 0 : helper->ResponseReceived(impl, NS_OK);
3414 : }
3415 :
3416 0 : mFileCreationPending.Remove(aUUID);
3417 0 : return IPC_OK();
3418 : }
3419 :
3420 : mozilla::ipc::IPCResult
3421 1 : ContentChild::RecvActivate(PBrowserChild* aTab)
3422 : {
3423 1 : TabChild* tab = static_cast<TabChild*>(aTab);
3424 1 : return tab->RecvActivate();
3425 : }
3426 :
3427 : mozilla::ipc::IPCResult
3428 0 : ContentChild::RecvDeactivate(PBrowserChild* aTab)
3429 : {
3430 0 : TabChild* tab = static_cast<TabChild*>(aTab);
3431 0 : return tab->RecvDeactivate();
3432 : }
3433 :
3434 : mozilla::ipc::IPCResult
3435 1 : ContentChild::RecvParentActivated(PBrowserChild* aTab, const bool& aActivated)
3436 : {
3437 1 : TabChild* tab = static_cast<TabChild*>(aTab);
3438 1 : return tab->RecvParentActivated(aActivated);
3439 : }
3440 :
3441 : mozilla::ipc::IPCResult
3442 0 : ContentChild::RecvProvideAnonymousTemporaryFile(const uint64_t& aID,
3443 : const FileDescOrError& aFDOrError)
3444 : {
3445 0 : nsAutoPtr<AnonymousTemporaryFileCallback> callback;
3446 0 : mPendingAnonymousTemporaryFiles.Remove(aID, &callback);
3447 0 : MOZ_ASSERT(callback);
3448 :
3449 0 : PRFileDesc* prfile = nullptr;
3450 0 : if (aFDOrError.type() == FileDescOrError::Tnsresult) {
3451 0 : DebugOnly<nsresult> rv = aFDOrError.get_nsresult();
3452 0 : MOZ_ASSERT(NS_FAILED(rv));
3453 : } else {
3454 0 : auto rawFD = aFDOrError.get_FileDescriptor().ClonePlatformHandle();
3455 0 : prfile = PR_ImportFile(PROsfd(rawFD.release()));
3456 : }
3457 0 : (*callback)(prfile);
3458 0 : return IPC_OK();
3459 : }
3460 :
3461 : nsresult
3462 0 : ContentChild::AsyncOpenAnonymousTemporaryFile(const AnonymousTemporaryFileCallback& aCallback)
3463 : {
3464 0 : MOZ_ASSERT(NS_IsMainThread());
3465 :
3466 : static uint64_t id = 0;
3467 0 : auto newID = id++;
3468 0 : if (!SendRequestAnonymousTemporaryFile(newID)) {
3469 0 : return NS_ERROR_FAILURE;
3470 : }
3471 :
3472 : // Remember the association with the callback.
3473 0 : MOZ_ASSERT(!mPendingAnonymousTemporaryFiles.Get(newID));
3474 0 : mPendingAnonymousTemporaryFiles.LookupOrAdd(newID, aCallback);
3475 0 : return NS_OK;
3476 : }
3477 :
3478 : mozilla::ipc::IPCResult
3479 3 : ContentChild::RecvSetPermissionsWithKey(const nsCString& aPermissionKey,
3480 : nsTArray<IPC::Permission>&& aPerms)
3481 : {
3482 : nsCOMPtr<nsIPermissionManager> permissionManager =
3483 6 : services::GetPermissionManager();
3484 3 : permissionManager->SetPermissionsWithKey(aPermissionKey, aPerms);
3485 6 : return IPC_OK();
3486 : }
3487 :
3488 : mozilla::ipc::IPCResult
3489 2 : ContentChild::RecvRefreshScreens(nsTArray<ScreenDetails>&& aScreens)
3490 : {
3491 2 : ScreenManager& screenManager = ScreenManager::GetSingleton();
3492 2 : screenManager.Refresh(Move(aScreens));
3493 2 : return IPC_OK();
3494 : }
3495 :
3496 : already_AddRefed<nsIEventTarget>
3497 1 : ContentChild::GetEventTargetFor(TabChild* aTabChild)
3498 : {
3499 1 : return IToplevelProtocol::GetActorEventTarget(aTabChild);
3500 : }
3501 :
3502 : mozilla::ipc::IPCResult
3503 3 : ContentChild::RecvSetPluginList(const uint32_t& aPluginEpoch,
3504 : nsTArray<plugins::PluginTag>&& aPluginTags,
3505 : nsTArray<plugins::FakePluginTag>&& aFakePluginTags)
3506 : {
3507 6 : RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
3508 3 : host->SetPluginsInContent(aPluginEpoch, aPluginTags, aFakePluginTags);
3509 6 : return IPC_OK();
3510 : }
3511 :
3512 : mozilla::ipc::IPCResult
3513 2 : ContentChild::RecvShareCodeCoverageMutex(const CrossProcessMutexHandle& aHandle)
3514 : {
3515 : #ifdef MOZ_CODE_COVERAGE
3516 2 : CodeCoverageHandler::Init(aHandle);
3517 2 : return IPC_OK();
3518 : #else
3519 : NS_RUNTIMEABORT("Shouldn't receive this message in non-code coverage builds!");
3520 : return IPC_FAIL_NO_REASON(this);
3521 : #endif
3522 : }
3523 :
3524 : mozilla::ipc::IPCResult
3525 2 : ContentChild::RecvDumpCodeCoverageCounters()
3526 : {
3527 : #ifdef MOZ_CODE_COVERAGE
3528 2 : CodeCoverageHandler::DumpCounters(0);
3529 0 : return IPC_OK();
3530 : #else
3531 : NS_RUNTIMEABORT("Shouldn't receive this message in non-code coverage builds!");
3532 : return IPC_FAIL_NO_REASON(this);
3533 : #endif
3534 : }
3535 :
3536 : mozilla::ipc::IPCResult
3537 0 : ContentChild::RecvResetCodeCoverageCounters()
3538 : {
3539 : #ifdef MOZ_CODE_COVERAGE
3540 0 : CodeCoverageHandler::ResetCounters(0);
3541 0 : return IPC_OK();
3542 : #else
3543 : NS_RUNTIMEABORT("Shouldn't receive this message in non-code coverage builds!");
3544 : return IPC_FAIL_NO_REASON(this);
3545 : #endif
3546 : }
3547 :
3548 : already_AddRefed<nsIEventTarget>
3549 91 : ContentChild::GetSpecificMessageEventTarget(const Message& aMsg)
3550 : {
3551 182 : if (aMsg.type() == PJavaScript::Msg_DropTemporaryStrongReferences__ID
3552 91 : || aMsg.type() == PJavaScript::Msg_DropObject__ID) {
3553 3 : return do_AddRef(SystemGroup::EventTargetFor(TaskCategory::Other));
3554 : }
3555 :
3556 88 : return nullptr;
3557 : }
3558 :
3559 : } // namespace dom
3560 9 : } // namespace mozilla
|