2016-01-08 23:40:26 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2009-08-12 20:18:08 +04:00
|
|
|
|
2012-06-28 04:15:32 +04:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
2010-08-21 03:24:40 +04:00
|
|
|
# include <gtk/gtk.h>
|
2019-05-31 19:19:48 +03:00
|
|
|
# include <gdk/gdkx.h>
|
2010-08-21 03:24:40 +04:00
|
|
|
#endif
|
|
|
|
|
2010-07-19 22:33:33 +04:00
|
|
|
#include "ContentChild.h"
|
2014-09-27 03:21:57 +04:00
|
|
|
|
2014-11-18 20:50:25 +03:00
|
|
|
#include "GeckoProfiler.h"
|
2019-04-10 01:39:01 +03:00
|
|
|
#include "BrowserChild.h"
|
2015-08-26 02:42:21 +03:00
|
|
|
#include "HandlerServiceChild.h"
|
2009-08-12 20:18:08 +04:00
|
|
|
|
2012-09-05 04:36:16 +04:00
|
|
|
#include "mozilla/Attributes.h"
|
2018-04-30 04:21:20 +03:00
|
|
|
#include "mozilla/BackgroundHangMonitor.h"
|
2019-08-06 12:24:34 +03:00
|
|
|
#include "mozilla/BenchmarkStorageChild.h"
|
2015-04-22 17:58:15 +03:00
|
|
|
#include "mozilla/LookAndFeel.h"
|
2018-12-05 23:44:53 +03:00
|
|
|
#include "mozilla/MemoryTelemetry.h"
|
2018-07-17 22:37:48 +03:00
|
|
|
#include "mozilla/NullPrincipal.h"
|
2019-05-21 22:01:31 +03:00
|
|
|
#include "mozilla/PerfStats.h"
|
2014-06-11 09:44:06 +04:00
|
|
|
#include "mozilla/Preferences.h"
|
2015-01-17 05:34:47 +03:00
|
|
|
#include "mozilla/ProcessHangMonitorIPC.h"
|
2018-11-14 21:07:28 +03:00
|
|
|
#include "mozilla/RemoteDecoderManagerChild.h"
|
2016-09-02 10:12:24 +03:00
|
|
|
#include "mozilla/Unused.h"
|
2019-07-26 04:10:23 +03:00
|
|
|
#include "mozilla/StaticPrefs_dom.h"
|
2019-10-30 02:33:45 +03:00
|
|
|
#include "mozilla/StaticPrefs_media.h"
|
2017-08-29 14:05:40 +03:00
|
|
|
#include "mozilla/TelemetryIPC.h"
|
2019-06-11 05:01:34 +03:00
|
|
|
#include "mozilla/RemoteDecoderManagerChild.h"
|
2015-09-22 22:09:42 +03:00
|
|
|
#include "mozilla/devtools/HeapSnapshotTempFileHelperChild.h"
|
2014-11-13 03:31:00 +03:00
|
|
|
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
|
2019-03-14 21:51:09 +03:00
|
|
|
#include "mozilla/dom/BrowsingContext.h"
|
|
|
|
#include "mozilla/dom/BrowsingContextGroup.h"
|
2019-05-07 05:29:48 +03:00
|
|
|
#include "mozilla/dom/BrowserBridgeHost.h"
|
2017-11-09 08:19:59 +03:00
|
|
|
#include "mozilla/dom/ClientManager.h"
|
2017-11-01 20:19:38 +03:00
|
|
|
#include "mozilla/dom/ClientOpenWindowOpActors.h"
|
2017-06-14 17:44:17 +03:00
|
|
|
#include "mozilla/dom/ChildProcessMessageManager.h"
|
2018-08-03 01:03:50 +03:00
|
|
|
#include "mozilla/dom/ContentProcessMessageManager.h"
|
2015-03-24 17:29:16 +03:00
|
|
|
#include "mozilla/dom/ContentParent.h"
|
2015-04-08 21:48:11 +03:00
|
|
|
#include "mozilla/dom/DataTransfer.h"
|
2016-11-04 21:13:52 +03:00
|
|
|
#include "mozilla/dom/DocGroup.h"
|
2011-10-06 02:15:45 +04:00
|
|
|
#include "mozilla/dom/ExternalHelperAppChild.h"
|
2016-07-14 10:04:21 +03:00
|
|
|
#include "mozilla/dom/GetFilesHelper.h"
|
2019-04-26 21:04:02 +03:00
|
|
|
#include "mozilla/dom/IPCBlobInputStreamChild.h"
|
2017-04-24 13:16:49 +03:00
|
|
|
#include "mozilla/dom/IPCBlobUtils.h"
|
2019-01-28 22:02:02 +03:00
|
|
|
#include "mozilla/dom/JSWindowActorService.h"
|
2018-11-29 23:47:20 +03:00
|
|
|
#include "mozilla/dom/LSObject.h"
|
2017-01-27 03:35:53 +03:00
|
|
|
#include "mozilla/dom/MemoryReportRequest.h"
|
2017-12-07 11:32:52 +03:00
|
|
|
#include "mozilla/dom/PLoginReputationChild.h"
|
2019-02-06 08:09:57 +03:00
|
|
|
#include "mozilla/dom/PSessionStorageObserverChild.h"
|
2019-11-01 00:22:33 +03:00
|
|
|
#include "mozilla/dom/PlaybackController.h"
|
2019-01-02 16:29:18 +03:00
|
|
|
#include "mozilla/dom/PostMessageEvent.h"
|
2016-09-01 21:17:03 +03:00
|
|
|
#include "mozilla/dom/PushNotifier.h"
|
2018-11-20 02:18:32 +03:00
|
|
|
#include "mozilla/dom/RemoteWorkerService.h"
|
2018-01-27 00:08:59 +03:00
|
|
|
#include "mozilla/dom/ServiceWorkerManager.h"
|
2019-03-05 17:46:10 +03:00
|
|
|
#include "mozilla/dom/SHEntryChild.h"
|
|
|
|
#include "mozilla/dom/SHistoryChild.h"
|
2016-11-04 21:13:52 +03:00
|
|
|
#include "mozilla/dom/TabGroup.h"
|
2016-11-19 00:54:57 +03:00
|
|
|
#include "mozilla/dom/URLClassifierChild.h"
|
2019-08-08 19:07:05 +03:00
|
|
|
#include "mozilla/dom/WindowGlobalChild.h"
|
2018-03-20 22:07:41 +03:00
|
|
|
#include "mozilla/dom/WorkerDebugger.h"
|
|
|
|
#include "mozilla/dom/WorkerDebuggerManager.h"
|
2018-06-23 06:35:49 +03:00
|
|
|
#include "mozilla/dom/ipc/SharedMap.h"
|
2016-08-04 21:33:42 +03:00
|
|
|
#include "mozilla/gfx/gfxVars.h"
|
2018-02-15 02:07:53 +03:00
|
|
|
#include "mozilla/gfx/Logging.h"
|
2015-04-22 22:55:23 +03:00
|
|
|
#include "mozilla/psm/PSMContentListener.h"
|
2011-10-06 02:15:45 +04:00
|
|
|
#include "mozilla/hal_sandbox/PHalChild.h"
|
2013-11-27 11:59:41 +04:00
|
|
|
#include "mozilla/ipc/BackgroundChild.h"
|
2014-09-27 03:21:57 +04:00
|
|
|
#include "mozilla/ipc/FileDescriptorSetChild.h"
|
2014-05-13 21:13:00 +04:00
|
|
|
#include "mozilla/ipc/FileDescriptorUtils.h"
|
2013-01-18 00:06:36 +04:00
|
|
|
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
2016-04-11 11:12:33 +03:00
|
|
|
#include "mozilla/ipc/ProcessChild.h"
|
2017-03-14 14:28:58 +03:00
|
|
|
#include "mozilla/ipc/PChildToParentStreamChild.h"
|
2019-02-25 23:04:53 +03:00
|
|
|
#include "mozilla/ipc/PParentToChildStreamChild.h"
|
Bug 1348042 - Refactor LocaleService to operate in server-client mode. r=Ehsan,qdot
LocaleService serves two main functions. It is a central place for all code in the
engine to learn about locales, but it also does the language negotiation and selection.
The former is relevant in all processes, but the latter should only be performed
by the "main" process. In case of current Desktop Firefox, the parent process
is the one performing all the language negotiation, and content processes should
operate in the "client" mode.
In Fennec, there's a Java app on top of Gecko which should work as a "server"
and then all processes, including parent process of Gecko is merely a "client" for that.
This refactor finalizes this duality making it easily configurable to define in
which mode a given LocaleService operates.
The server-client model allows all clients to stay in sync with the server,
but operate transparently for all callers just returning the right values.
In order to initialize LocaleService in the client mode in child process with the
right locales I'm adding the list of app locales to the XPCOMInitData,
and then fire LocaleService::SetAppLocales in the child process initialization.
In order to keep the list up to date, I'm adding intl:app-locales-changed to
the list of observed topics, and when triggered, I send the updated list
to the child process, which updates LocaleService::SetAppLocales with the new
list.
MozReview-Commit-ID: K9X6berF3IO
--HG--
extra : rebase_source : ca5e502d064023fddfd63fe6fe5eccefce8dee52
2017-03-26 08:09:45 +03:00
|
|
|
#include "mozilla/intl/LocaleService.h"
|
2009-08-12 22:31:48 +04:00
|
|
|
#include "mozilla/ipc/TestShellChild.h"
|
2015-01-27 00:32:18 +03:00
|
|
|
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
2017-06-15 00:28:01 +03:00
|
|
|
#include "mozilla/jsipc/PJavaScript.h"
|
2016-01-08 22:17:39 +03:00
|
|
|
#include "mozilla/layers/APZChild.h"
|
2017-06-14 18:39:59 +03:00
|
|
|
#include "mozilla/layers/CompositorManagerChild.h"
|
2016-08-11 02:51:45 +03:00
|
|
|
#include "mozilla/layers/ContentProcessController.h"
|
2012-08-29 16:24:48 +04:00
|
|
|
#include "mozilla/layers/ImageBridgeChild.h"
|
2019-01-12 07:51:20 +03:00
|
|
|
#include "mozilla/layers/SynchronousTask.h" // for LaunchRDDProcess
|
2017-05-03 03:17:52 +03:00
|
|
|
#include "mozilla/loader/ScriptCacheActors.h"
|
2011-10-06 02:15:45 +04:00
|
|
|
#include "mozilla/net/NeckoChild.h"
|
2017-08-03 14:00:41 +03:00
|
|
|
#include "mozilla/net/CookieServiceChild.h"
|
2016-11-17 19:35:24 +03:00
|
|
|
#include "mozilla/net/CaptivePortalService.h"
|
2018-07-05 17:32:03 +03:00
|
|
|
#include "mozilla/PerformanceMetricsCollector.h"
|
2018-04-04 11:12:02 +03:00
|
|
|
#include "mozilla/PerformanceUtils.h"
|
2015-04-07 16:17:27 +03:00
|
|
|
#include "mozilla/plugins/PluginInstanceParent.h"
|
2014-10-29 18:05:36 +03:00
|
|
|
#include "mozilla/plugins/PluginModuleParent.h"
|
2018-07-22 14:51:30 +03:00
|
|
|
#include "mozilla/recordreplay/ParentIPC.h"
|
2017-03-09 14:30:26 +03:00
|
|
|
#include "mozilla/widget/ScreenManager.h"
|
2015-04-22 17:58:15 +03:00
|
|
|
#include "mozilla/widget/WidgetMessageUtils.h"
|
2016-05-19 00:17:34 +03:00
|
|
|
#include "nsBaseDragService.h"
|
2015-06-18 18:46:36 +03:00
|
|
|
#include "mozilla/media/MediaChild.h"
|
2015-06-10 19:48:22 +03:00
|
|
|
#include "mozilla/BasePrincipal.h"
|
2015-09-21 15:54:00 +03:00
|
|
|
#include "mozilla/WebBrowserPersistDocumentChild.h"
|
2018-01-11 01:27:18 +03:00
|
|
|
#include "mozilla/HangDetails.h"
|
2019-01-24 00:27:44 +03:00
|
|
|
#include "mozilla/LoadInfo.h"
|
2019-10-11 19:04:32 +03:00
|
|
|
#include "mozilla/UnderrunHandler.h"
|
2019-01-24 00:27:44 +03:00
|
|
|
#include "nsIChildProcessChannelListener.h"
|
|
|
|
#include "mozilla/net/HttpChannelChild.h"
|
|
|
|
#include "nsQueryObject.h"
|
2016-06-07 01:23:43 +03:00
|
|
|
#include "imgLoader.h"
|
2016-11-01 06:25:19 +03:00
|
|
|
#include "GMPServiceChild.h"
|
2018-03-20 22:07:41 +03:00
|
|
|
#include "nsISimpleEnumerator.h"
|
2018-06-30 08:53:12 +03:00
|
|
|
#include "nsIStringBundle.h"
|
2018-03-20 22:07:41 +03:00
|
|
|
#include "nsIWorkerDebuggerManager.h"
|
2018-08-22 07:22:01 +03:00
|
|
|
#include "nsGeolocation.h"
|
2019-06-21 22:49:10 +03:00
|
|
|
#include "audio_thread_priority.h"
|
2019-08-27 20:37:55 +03:00
|
|
|
#include "nsIConsoleService.h"
|
2019-10-11 19:04:32 +03:00
|
|
|
#include "audio_thread_priority.h"
|
2014-02-14 20:07:16 +04:00
|
|
|
|
2017-08-10 02:09:55 +03:00
|
|
|
#if !defined(XP_WIN)
|
|
|
|
# include "mozilla/Omnijar.h"
|
|
|
|
#endif
|
|
|
|
|
2017-05-30 22:06:14 +03:00
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
|
|
|
# include "ChildProfilerController.h"
|
|
|
|
#endif
|
|
|
|
|
2019-03-19 01:31:59 +03:00
|
|
|
#if defined(MOZ_SANDBOX)
|
2017-05-13 00:04:42 +03:00
|
|
|
# include "mozilla/SandboxSettings.h"
|
2014-03-13 02:48:15 +04:00
|
|
|
# if defined(XP_WIN)
|
2014-02-14 20:07:16 +04:00
|
|
|
# include "mozilla/sandboxTarget.h"
|
2014-11-25 02:22:13 +03:00
|
|
|
# elif defined(XP_LINUX)
|
|
|
|
# include "mozilla/Sandbox.h"
|
|
|
|
# include "mozilla/SandboxInfo.h"
|
2018-03-06 23:01:35 +03:00
|
|
|
# include "CubebUtils.h"
|
2014-11-25 02:22:13 +03:00
|
|
|
# elif defined(XP_MACOSX)
|
2014-02-28 01:18:01 +04:00
|
|
|
# include "mozilla/Sandbox.h"
|
2018-08-23 14:35:00 +03:00
|
|
|
# elif defined(__OpenBSD__)
|
|
|
|
# include <unistd.h>
|
2019-11-07 12:52:18 +03:00
|
|
|
# include <sys/stat.h>
|
|
|
|
# include <err.h>
|
|
|
|
# include <fstream>
|
|
|
|
# include "nsILineInputStream.h"
|
2019-11-08 10:31:09 +03:00
|
|
|
# include "SpecialSystemDirectory.h"
|
2014-02-14 20:07:16 +04:00
|
|
|
# endif
|
2019-10-14 18:08:47 +03:00
|
|
|
# if defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
|
|
|
|
# include "mozilla/SandboxTestingChild.h"
|
|
|
|
# endif
|
2014-03-13 02:48:15 +04:00
|
|
|
#endif
|
2014-02-14 20:07:16 +04:00
|
|
|
|
2016-08-23 07:09:32 +03:00
|
|
|
#include "mozilla/Unused.h"
|
2009-08-12 22:31:48 +04:00
|
|
|
|
2014-10-03 18:52:37 +04:00
|
|
|
#include "mozInlineSpellChecker.h"
|
2016-02-18 11:33:07 +03:00
|
|
|
#include "nsDocShell.h"
|
2018-10-30 03:13:29 +03:00
|
|
|
#include "nsDocShellLoadState.h"
|
2019-04-25 07:52:47 +03:00
|
|
|
#include "nsIDocShellTreeOwner.h"
|
2013-09-24 01:30:40 +04:00
|
|
|
#include "nsIConsoleListener.h"
|
2017-06-20 16:57:08 +03:00
|
|
|
#include "nsIContentViewer.h"
|
2014-05-13 21:13:00 +04:00
|
|
|
#include "nsICycleCollectorListener.h"
|
2016-08-22 15:52:45 +03:00
|
|
|
#include "nsIIdlePeriod.h"
|
2015-04-08 21:48:11 +03:00
|
|
|
#include "nsIDragService.h"
|
2013-09-24 01:30:40 +04:00
|
|
|
#include "nsIInterfaceRequestorUtils.h"
|
2011-02-16 21:43:23 +03:00
|
|
|
#include "nsIMemoryReporter.h"
|
2012-10-30 04:41:14 +04:00
|
|
|
#include "nsIMemoryInfoDumper.h"
|
2013-01-10 22:16:40 +04:00
|
|
|
#include "nsIMutable.h"
|
2010-07-21 22:42:32 +04:00
|
|
|
#include "nsIObserverService.h"
|
2012-08-09 06:58:06 +04:00
|
|
|
#include "nsIScriptSecurityManager.h"
|
2014-07-03 02:59:02 +04:00
|
|
|
#include "nsMemoryInfoDumper.h"
|
2010-07-21 22:42:32 +04:00
|
|
|
#include "nsServiceManagerUtils.h"
|
2013-08-27 21:10:39 +04:00
|
|
|
#include "nsStyleSheetService.h"
|
2015-10-07 18:17:42 +03:00
|
|
|
#include "nsVariant.h"
|
2009-08-26 03:39:30 +04:00
|
|
|
#include "nsXULAppAPI.h"
|
2010-09-24 05:39:32 +04:00
|
|
|
#include "nsIScriptError.h"
|
|
|
|
#include "nsIConsoleService.h"
|
2011-09-13 21:53:51 +04:00
|
|
|
#include "nsJSEnvironment.h"
|
2011-10-06 02:15:45 +04:00
|
|
|
#include "SandboxHal.h"
|
2012-04-10 23:57:20 +04:00
|
|
|
#include "nsDebugImpl.h"
|
2013-04-26 04:53:26 +04:00
|
|
|
#include "nsHashPropertyBag.h"
|
2012-08-16 05:46:03 +04:00
|
|
|
#include "nsLayoutStylesheetCache.h"
|
2014-02-01 03:02:30 +04:00
|
|
|
#include "nsThreadManager.h"
|
2014-06-24 21:11:36 +04:00
|
|
|
#include "nsAnonymousTemporaryFile.h"
|
2014-10-22 13:50:00 +04:00
|
|
|
#include "nsClipboardProxy.h"
|
2016-02-26 02:26:13 +03:00
|
|
|
#include "nsDirectoryService.h"
|
2015-02-18 16:10:27 +03:00
|
|
|
#include "nsDirectoryServiceUtils.h"
|
|
|
|
#include "nsDirectoryServiceDefs.h"
|
2015-04-14 04:08:00 +03:00
|
|
|
#include "nsContentPermissionHelper.h"
|
2017-06-06 20:39:46 +03:00
|
|
|
#include "nsPluginHost.h"
|
2016-05-19 13:25:22 +03:00
|
|
|
#ifdef NS_PRINTING
|
2016-05-16 12:40:54 +03:00
|
|
|
# include "nsPrintingProxy.h"
|
2016-05-19 13:25:22 +03:00
|
|
|
#endif
|
2018-01-12 01:14:09 +03:00
|
|
|
#include "nsWindowMemoryReporter.h"
|
2019-03-15 08:11:43 +03:00
|
|
|
#include "ReferrerInfo.h"
|
2009-08-26 03:07:22 +04:00
|
|
|
|
2012-11-09 13:55:54 +04:00
|
|
|
#include "IHistory.h"
|
2010-07-02 19:50:41 +04:00
|
|
|
#include "nsNetUtil.h"
|
|
|
|
|
2009-09-03 04:18:27 +04:00
|
|
|
#include "base/message_loop.h"
|
2012-07-18 03:59:45 +04:00
|
|
|
#include "base/process_util.h"
|
2009-09-03 04:18:27 +04:00
|
|
|
#include "base/task.h"
|
|
|
|
|
2010-03-11 08:33:00 +03:00
|
|
|
#include "nsChromeRegistryContent.h"
|
2010-08-31 22:58:35 +04:00
|
|
|
#include "nsFrameMessageManager.h"
|
2010-03-11 08:33:00 +03:00
|
|
|
|
2010-09-21 08:16:37 +04:00
|
|
|
#include "nsIGeolocationProvider.h"
|
2014-05-13 21:13:00 +04:00
|
|
|
#include "mozilla/dom/PCycleCollectWithLogsChild.h"
|
2010-09-21 08:16:37 +04:00
|
|
|
|
2013-09-24 01:30:40 +04:00
|
|
|
#include "nsIScriptSecurityManager.h"
|
2018-06-02 16:51:42 +03:00
|
|
|
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
2015-03-24 17:29:16 +03:00
|
|
|
|
2015-05-06 19:29:33 +03:00
|
|
|
#ifdef MOZ_WEBRTC
|
|
|
|
# include "signaling/src/peerconnection/WebrtcGlobalChild.h"
|
|
|
|
#endif
|
|
|
|
|
2010-10-09 22:07:38 +04:00
|
|
|
#include "nsPermission.h"
|
|
|
|
#include "nsPermissionManager.h"
|
|
|
|
|
2013-11-06 21:21:15 +04:00
|
|
|
#include "PermissionMessageUtils.h"
|
|
|
|
|
2011-11-11 04:17:46 +04:00
|
|
|
#if defined(MOZ_WIDGET_ANDROID)
|
2010-11-24 17:15:03 +03:00
|
|
|
# include "APKOpen.h"
|
|
|
|
#endif
|
|
|
|
|
2011-02-16 21:43:23 +03:00
|
|
|
#ifdef XP_WIN
|
|
|
|
# include <process.h>
|
|
|
|
# define getpid _getpid
|
2016-03-13 16:25:23 +03:00
|
|
|
# include "mozilla/widget/AudioSession.h"
|
2017-07-25 07:34:14 +03:00
|
|
|
# include "mozilla/audio/AudioNotificationReceiver.h"
|
2011-02-16 21:43:23 +03:00
|
|
|
#endif
|
|
|
|
|
2017-08-10 02:09:55 +03:00
|
|
|
#if defined(XP_MACOSX)
|
2018-10-18 23:44:47 +03:00
|
|
|
# include "nsMacUtilsImpl.h"
|
2017-08-10 02:09:55 +03:00
|
|
|
#endif /* XP_MACOSX */
|
|
|
|
|
2014-02-05 20:37:26 +04:00
|
|
|
#ifdef MOZ_X11
|
|
|
|
# include "mozilla/X11Util.h"
|
|
|
|
#endif
|
|
|
|
|
2011-07-21 08:37:32 +04:00
|
|
|
#ifdef ACCESSIBILITY
|
2016-08-08 18:35:56 +03:00
|
|
|
# include "nsAccessibilityService.h"
|
Bug 1303060: Changes to a11y to enable the serving of a COM handler; r=tbsaunde
MozReview-Commit-ID: GTQF3x1pBtX
A general outline of the COM handler (a.k.a. the "smart proxy"):
COM handlers are pieces of code that are loaded by the COM runtime along with
a proxy and are layered above that proxy. This enables the COM handler to
interpose itself between the caller and the proxy, thus providing the
opportunity for the handler to manipulate an interface's method calls before
those calls reach the proxy.
Handlers are regular COM components that live in DLLs and are declared in the
Windows registry. In order to allow for the specifying of a handler (and an
optional payload to be sent with the proxy), the mscom library allows its
clients to specify an implementation of the IHandlerProvider interface.
IHandlerProvider consists of 5 functions:
* GetHandler returns the CLSID of the component that should be loaded into
the COM client's process. If GetHandler returns a failure code, then no
handler is loaded.
* GetHandlerPayloadSize and WriteHandlerPayload are for obtaining the payload
data. These calls are made on a background thread but need to do their work
on the main thread. We declare the payload struct in IDL. MIDL generates two
functions, IA2Payload_Encode and IA2Payload_Decode, which are used by
mscom::StructToStream to read and write that struct to and from buffers.
* The a11y payload struct also includes an interface, IGeckoBackChannel, that
allows the handler to communicate directly with Gecko. IGeckoBackChannel
currently provides two methods: one to allow the handler to request fresh
cache information, and the other to provide Gecko with its IHandlerControl
interface.
* MarshalAs accepts an IID that specifies the interface that is about to be
proxied. We may want to send a more sophisticated proxy than the one that
is requested. The desired IID is returned by this function. In the case of
a11y interfaces, we should always return IAccessible2_3 if we are asked for
one of its parent interfaces. This allows us to eliminate round trips to
resolve more sophisticated interfaces later on.
* NewInstance, which is needed to ensure that all descendent proxies are also
imbued with the same handler code.
The main focus of this patch is as follows:
1. Provide an implementation of the IHandlerProvider interface;
2. Populate the handler payload (ie, the cache) with data;
3. Modify CreateHolderFromAccessible to specify the HandlerPayload object;
4. Receive the IHandlerControl interface from the handler DLL and move it
into the chrome process.
Some more information about IHandlerControl:
There is one IHandlerControl per handler DLL instance. It is the interface that
we call in Gecko when we need to dispatch an event to the handler. In order to
ensure that events are dispatched in the correct order, we need to dispatch
those events from the chrome main thread so that they occur in sequential order
with calls to NotifyWinEvent.
--HG--
extra : rebase_source : acb44dead7cc5488424720e1bf58862b7b30374f
2017-04-05 00:23:55 +03:00
|
|
|
# ifdef XP_WIN
|
|
|
|
# include "mozilla/a11y/AccessibleWrap.h"
|
|
|
|
# endif
|
2019-06-13 05:19:42 +03:00
|
|
|
# include "mozilla/a11y/DocAccessible.h"
|
|
|
|
# include "mozilla/a11y/DocManager.h"
|
|
|
|
# include "mozilla/a11y/OuterDocAccessible.h"
|
2011-07-21 08:37:32 +04:00
|
|
|
#endif
|
|
|
|
|
2014-10-08 20:15:23 +04:00
|
|
|
#include "mozilla/dom/File.h"
|
2019-08-07 04:46:03 +03:00
|
|
|
#include "mozilla/dom/MediaController.h"
|
2015-03-26 06:16:21 +03:00
|
|
|
#include "mozilla/dom/PPresentationChild.h"
|
2015-03-30 10:46:11 +03:00
|
|
|
#include "mozilla/dom/PresentationIPCService.h"
|
2013-01-18 00:17:33 +04:00
|
|
|
#include "mozilla/ipc/InputStreamUtils.h"
|
2019-02-25 23:04:53 +03:00
|
|
|
#include "mozilla/ipc/IPCStreamAlloc.h"
|
|
|
|
#include "mozilla/ipc/IPCStreamDestination.h"
|
|
|
|
#include "mozilla/ipc/IPCStreamSource.h"
|
2012-08-02 10:02:29 +04:00
|
|
|
|
2013-04-04 02:13:17 +04:00
|
|
|
#ifdef MOZ_WEBSPEECH
|
|
|
|
# include "mozilla/dom/PSpeechSynthesisChild.h"
|
|
|
|
#endif
|
|
|
|
|
2017-09-17 18:21:32 +03:00
|
|
|
#include "ClearOnShutdown.h"
|
2012-09-11 08:30:33 +04:00
|
|
|
#include "ProcessUtils.h"
|
2012-08-23 23:33:46 +04:00
|
|
|
#include "URIUtils.h"
|
2012-08-25 20:53:48 +04:00
|
|
|
#include "nsContentUtils.h"
|
|
|
|
#include "nsIPrincipal.h"
|
2015-03-24 17:29:16 +03:00
|
|
|
#include "DomainPolicy.h"
|
2015-09-10 23:50:58 +03:00
|
|
|
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
2019-04-25 07:52:47 +03:00
|
|
|
#include "mozilla/dom/TabContext.h"
|
2017-10-10 13:43:09 +03:00
|
|
|
#include "mozilla/ipc/CrashReporterClient.h"
|
2013-10-19 00:57:55 +04:00
|
|
|
#include "mozilla/net/NeckoMessageUtils.h"
|
2015-04-11 01:18:05 +03:00
|
|
|
#include "mozilla/widget/PuppetBidiKeyboard.h"
|
2014-07-02 02:24:27 +04:00
|
|
|
#include "mozilla/RemoteSpellCheckEngineChild.h"
|
2015-02-10 13:49:03 +03:00
|
|
|
#include "GMPServiceChild.h"
|
2017-01-17 07:05:46 +03:00
|
|
|
#include "GfxInfoBase.h"
|
2015-07-30 10:23:53 +03:00
|
|
|
#include "gfxPlatform.h"
|
2019-04-27 18:37:58 +03:00
|
|
|
#include "gfxPlatformFontList.h"
|
2015-07-31 22:11:48 +03:00
|
|
|
#include "nscore.h" // for NS_FREE_PERMANENT_DATA
|
2015-09-18 00:23:13 +03:00
|
|
|
#include "VRManagerChild.h"
|
2017-03-14 02:06:04 +03:00
|
|
|
#include "private/pprio.h"
|
2017-03-30 00:43:21 +03:00
|
|
|
#include "nsString.h"
|
2018-12-11 20:31:24 +03:00
|
|
|
#include "MMPrinter.h"
|
2011-11-21 02:40:53 +04:00
|
|
|
|
2017-02-07 16:34:23 +03:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
|
|
|
# include "nsAppRunner.h"
|
|
|
|
#endif
|
|
|
|
|
2017-06-14 11:50:44 +03:00
|
|
|
#ifdef MOZ_CODE_COVERAGE
|
|
|
|
# include "mozilla/CodeCoverageHandler.h"
|
|
|
|
#endif
|
2017-02-07 16:34:23 +03:00
|
|
|
|
2012-12-15 04:01:34 +04:00
|
|
|
using namespace mozilla;
|
2010-10-20 21:12:32 +04:00
|
|
|
using namespace mozilla::docshell;
|
2013-01-27 01:14:01 +04:00
|
|
|
using namespace mozilla::dom::ipc;
|
2015-06-18 18:46:36 +03:00
|
|
|
using namespace mozilla::media;
|
2014-10-28 18:59:08 +03:00
|
|
|
using namespace mozilla::embedding;
|
2015-02-10 13:49:03 +03:00
|
|
|
using namespace mozilla::gmp;
|
2012-07-18 03:59:45 +04:00
|
|
|
using namespace mozilla::hal_sandbox;
|
|
|
|
using namespace mozilla::ipc;
|
Bug 1348042 - Refactor LocaleService to operate in server-client mode. r=Ehsan,qdot
LocaleService serves two main functions. It is a central place for all code in the
engine to learn about locales, but it also does the language negotiation and selection.
The former is relevant in all processes, but the latter should only be performed
by the "main" process. In case of current Desktop Firefox, the parent process
is the one performing all the language negotiation, and content processes should
operate in the "client" mode.
In Fennec, there's a Java app on top of Gecko which should work as a "server"
and then all processes, including parent process of Gecko is merely a "client" for that.
This refactor finalizes this duality making it easily configurable to define in
which mode a given LocaleService operates.
The server-client model allows all clients to stay in sync with the server,
but operate transparently for all callers just returning the right values.
In order to initialize LocaleService in the client mode in child process with the
right locales I'm adding the list of app locales to the XPCOMInitData,
and then fire LocaleService::SetAppLocales in the child process initialization.
In order to keep the list up to date, I'm adding intl:app-locales-changed to
the list of observed topics, and when triggered, I send the updated list
to the child process, which updates LocaleService::SetAppLocales with the new
list.
MozReview-Commit-ID: K9X6berF3IO
--HG--
extra : rebase_source : ca5e502d064023fddfd63fe6fe5eccefce8dee52
2017-03-26 08:09:45 +03:00
|
|
|
using namespace mozilla::intl;
|
2012-07-18 03:59:45 +04:00
|
|
|
using namespace mozilla::layers;
|
2015-10-30 02:30:57 +03:00
|
|
|
using namespace mozilla::layout;
|
2012-07-18 03:59:45 +04:00
|
|
|
using namespace mozilla::net;
|
2013-07-03 11:24:32 +04:00
|
|
|
using namespace mozilla::jsipc;
|
2015-04-22 22:55:23 +03:00
|
|
|
using namespace mozilla::psm;
|
2015-04-11 01:18:05 +03:00
|
|
|
using namespace mozilla::widget;
|
2017-05-03 03:17:52 +03:00
|
|
|
using mozilla::loader::PScriptCacheChild;
|
2009-08-12 22:31:48 +04:00
|
|
|
|
2009-08-12 20:18:08 +04:00
|
|
|
namespace mozilla {
|
2017-01-26 21:59:50 +03:00
|
|
|
|
2009-08-12 20:18:08 +04:00
|
|
|
namespace dom {
|
2011-02-16 21:43:23 +03:00
|
|
|
|
2014-05-13 21:13:00 +04:00
|
|
|
// IPC sender for remote GC/CC logging.
|
2015-03-21 19:28:04 +03:00
|
|
|
class CycleCollectWithLogsChild final : public PCycleCollectWithLogsChild {
|
2014-05-13 21:13:00 +04:00
|
|
|
public:
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_INLINE_DECL_REFCOUNTING(CycleCollectWithLogsChild)
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
class Sink final : public nsICycleCollectorLogSink {
|
|
|
|
NS_DECL_ISUPPORTS
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
Sink(CycleCollectWithLogsChild* aActor, const FileDescriptor& aGCLog,
|
|
|
|
const FileDescriptor& aCCLog) {
|
|
|
|
mActor = aActor;
|
|
|
|
mGCLog = FileDescriptorToFILE(aGCLog, "w");
|
|
|
|
mCCLog = FileDescriptorToFILE(aCCLog, "w");
|
2018-11-24 01:07:41 +03:00
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_IMETHOD Open(FILE** aGCLog, FILE** aCCLog) override {
|
|
|
|
if (NS_WARN_IF(!mGCLog) || NS_WARN_IF(!mCCLog)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
*aGCLog = mGCLog;
|
|
|
|
*aCCLog = mCCLog;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_IMETHOD CloseGCLog() override {
|
|
|
|
MOZ_ASSERT(mGCLog);
|
|
|
|
fclose(mGCLog);
|
|
|
|
mGCLog = nullptr;
|
|
|
|
mActor->SendCloseGCLog();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_IMETHOD CloseCCLog() override {
|
|
|
|
MOZ_ASSERT(mCCLog);
|
|
|
|
fclose(mCCLog);
|
|
|
|
mCCLog = nullptr;
|
|
|
|
mActor->SendCloseCCLog();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_IMETHOD GetFilenameIdentifier(nsAString& aIdentifier) override {
|
|
|
|
return UnimplementedProperty();
|
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_IMETHOD SetFilenameIdentifier(const nsAString& aIdentifier) override {
|
|
|
|
return UnimplementedProperty();
|
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_IMETHOD GetProcessIdentifier(int32_t* aIdentifier) override {
|
|
|
|
return UnimplementedProperty();
|
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_IMETHOD SetProcessIdentifier(int32_t aIdentifier) override {
|
|
|
|
return UnimplementedProperty();
|
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_IMETHOD GetGcLog(nsIFile** aPath) override {
|
|
|
|
return UnimplementedProperty();
|
|
|
|
}
|
2018-11-24 01:07:41 +03:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_IMETHOD GetCcLog(nsIFile** aPath) override {
|
|
|
|
return UnimplementedProperty();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2018-11-24 01:07:41 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
~Sink() {
|
|
|
|
if (mGCLog) {
|
|
|
|
fclose(mGCLog);
|
|
|
|
mGCLog = nullptr;
|
|
|
|
}
|
|
|
|
if (mCCLog) {
|
|
|
|
fclose(mCCLog);
|
|
|
|
mCCLog = nullptr;
|
|
|
|
}
|
|
|
|
// The XPCOM refcount drives the IPC lifecycle;
|
|
|
|
Unused << mActor->Send__delete__(mActor);
|
2018-11-24 01:07:41 +03:00
|
|
|
}
|
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
nsresult UnimplementedProperty() {
|
|
|
|
MOZ_ASSERT(false,
|
|
|
|
"This object is a remote GC/CC logger;"
|
|
|
|
" this property isn't meaningful.");
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<CycleCollectWithLogsChild> mActor;
|
|
|
|
FILE* mGCLog;
|
|
|
|
FILE* mCCLog;
|
|
|
|
};
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
private:
|
|
|
|
~CycleCollectWithLogsChild() {}
|
2014-05-13 21:13:00 +04:00
|
|
|
};
|
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
NS_IMPL_ISUPPORTS(CycleCollectWithLogsChild::Sink, nsICycleCollectorLogSink);
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2010-09-15 20:44:57 +04:00
|
|
|
class AlertObserver {
|
|
|
|
public:
|
2016-01-05 12:59:30 +03:00
|
|
|
AlertObserver(nsIObserver* aObserver, const nsString& aData)
|
|
|
|
: mObserver(aObserver), mData(aData) {}
|
2010-09-15 20:44:57 +04:00
|
|
|
|
2016-11-14 12:40:37 +03:00
|
|
|
~AlertObserver() = default;
|
2010-09-15 20:44:57 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
bool ShouldRemoveFrom(nsIObserver* aObserver, const nsString& aData) const {
|
|
|
|
return (mObserver == aObserver && mData == aData);
|
|
|
|
}
|
2010-09-15 20:44:57 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
bool Observes(const nsString& aData) const { return mData.Equals(aData); }
|
2010-09-15 20:44:57 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
bool Notify(const nsCString& aType) const {
|
|
|
|
mObserver->Observe(nullptr, aType.get(), mData.get());
|
|
|
|
return true;
|
|
|
|
}
|
2010-09-15 20:44:57 +04:00
|
|
|
|
|
|
|
private:
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIObserver> mObserver;
|
|
|
|
nsString mData;
|
2010-09-15 20:44:57 +04:00
|
|
|
};
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
class ConsoleListener final : public nsIConsoleListener {
|
2010-09-24 05:39:32 +04:00
|
|
|
public:
|
2016-01-05 12:59:30 +03:00
|
|
|
explicit ConsoleListener(ContentChild* aChild) : mChild(aChild) {}
|
2010-09-24 05:39:32 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSICONSOLELISTENER
|
2010-09-24 05:39:32 +04:00
|
|
|
|
|
|
|
private:
|
2016-11-14 12:40:37 +03:00
|
|
|
~ConsoleListener() = default;
|
2014-06-23 23:56:07 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentChild* mChild;
|
|
|
|
friend class ContentChild;
|
2010-09-24 05:39:32 +04:00
|
|
|
};
|
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS(ConsoleListener, nsIConsoleListener)
|
2010-09-24 05:39:32 +04:00
|
|
|
|
2016-04-18 19:49:26 +03:00
|
|
|
// Before we send the error to the parent process (which
|
|
|
|
// involves copying the memory), truncate any long lines. CSS
|
|
|
|
// errors in particular share the memory for long lines with
|
|
|
|
// repeated errors, but the IPC communication we're about to do
|
|
|
|
// will break that sharing, so we better truncate now.
|
|
|
|
static void TruncateString(nsAString& aString) {
|
|
|
|
if (aString.Length() > 1000) {
|
|
|
|
aString.Truncate(1000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-24 05:39:32 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
ConsoleListener::Observe(nsIConsoleMessage* aMessage) {
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!mChild) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptError> scriptError = do_QueryInterface(aMessage);
|
|
|
|
if (scriptError) {
|
2016-04-19 16:59:03 +03:00
|
|
|
nsAutoString msg, sourceName, sourceLine;
|
2017-08-16 06:58:35 +03:00
|
|
|
nsCString category;
|
2016-01-05 12:59:30 +03:00
|
|
|
uint32_t lineNum, colNum, flags;
|
2019-04-02 01:42:34 +03:00
|
|
|
bool fromPrivateWindow, fromChromeContext;
|
2016-01-05 12:59:30 +03:00
|
|
|
|
|
|
|
nsresult rv = scriptError->GetErrorMessage(msg);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2016-04-18 19:49:26 +03:00
|
|
|
TruncateString(msg);
|
2016-01-05 12:59:30 +03:00
|
|
|
rv = scriptError->GetSourceName(sourceName);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2016-04-18 19:49:26 +03:00
|
|
|
TruncateString(sourceName);
|
2016-01-05 12:59:30 +03:00
|
|
|
rv = scriptError->GetSourceLine(sourceLine);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2016-04-18 19:49:26 +03:00
|
|
|
TruncateString(sourceLine);
|
2010-09-24 05:39:32 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
rv = scriptError->GetCategory(getter_Copies(category));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = scriptError->GetLineNumber(&lineNum);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = scriptError->GetColumnNumber(&colNum);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = scriptError->GetFlags(&flags);
|
2010-09-24 05:39:32 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-03-13 08:40:38 +03:00
|
|
|
rv = scriptError->GetIsFromPrivateWindow(&fromPrivateWindow);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2019-04-02 01:42:34 +03:00
|
|
|
rv = scriptError->GetIsFromChromeContext(&fromChromeContext);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2016-04-18 19:49:26 +03:00
|
|
|
|
2018-02-24 04:21:49 +03:00
|
|
|
{
|
|
|
|
AutoJSAPI jsapi;
|
|
|
|
jsapi.Init();
|
|
|
|
JSContext* cx = jsapi.cx();
|
|
|
|
|
|
|
|
JS::RootedValue stack(cx);
|
|
|
|
rv = scriptError->GetStack(&stack);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (stack.isObject()) {
|
2018-08-04 16:30:40 +03:00
|
|
|
// Because |stack| might be a cross-compartment wrapper, we can't use it
|
|
|
|
// with JSAutoRealm. Use the stackGlobal for that.
|
|
|
|
JS::RootedValue stackGlobal(cx);
|
|
|
|
rv = scriptError->GetStackGlobal(&stackGlobal);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
JSAutoRealm ar(cx, &stackGlobal.toObject());
|
2018-02-24 04:21:49 +03:00
|
|
|
|
|
|
|
StructuredCloneData data;
|
|
|
|
ErrorResult err;
|
|
|
|
data.Write(cx, stack, err);
|
|
|
|
if (err.Failed()) {
|
|
|
|
return err.StealNSResult();
|
|
|
|
}
|
|
|
|
|
|
|
|
ClonedMessageData cloned;
|
|
|
|
if (!data.BuildClonedMessageDataForChild(mChild, cloned)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2019-04-02 01:42:34 +03:00
|
|
|
mChild->SendScriptErrorWithStack(
|
|
|
|
msg, sourceName, sourceLine, lineNum, colNum, flags, category,
|
|
|
|
fromPrivateWindow, fromChromeContext, cloned);
|
2018-02-24 04:21:49 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
mChild->SendScriptError(msg, sourceName, sourceLine, lineNum, colNum, flags,
|
2019-08-27 20:37:55 +03:00
|
|
|
category, fromPrivateWindow, 0, fromChromeContext);
|
2010-09-24 05:39:32 +04:00
|
|
|
return NS_OK;
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
2017-08-08 09:07:55 +03:00
|
|
|
nsString msg;
|
2018-09-05 06:31:42 +03:00
|
|
|
nsresult rv = aMessage->GetMessageMoz(msg);
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
mChild->SendConsoleMessage(msg);
|
|
|
|
return NS_OK;
|
2010-09-24 05:39:32 +04:00
|
|
|
}
|
2010-07-21 22:42:32 +04:00
|
|
|
|
2017-08-09 23:59:27 +03:00
|
|
|
#ifdef NIGHTLY_BUILD
|
|
|
|
/**
|
2018-04-30 04:21:20 +03:00
|
|
|
* The singleton of this class is registered with the BackgroundHangMonitor as
|
2017-08-09 23:59:27 +03:00
|
|
|
* an annotator, so that the hang monitor can record whether or not there were
|
|
|
|
* pending input events when the thread hung.
|
|
|
|
*/
|
|
|
|
class PendingInputEventHangAnnotator final : public BackgroundHangAnnotator {
|
|
|
|
public:
|
2018-04-30 04:21:20 +03:00
|
|
|
virtual void AnnotateHang(BackgroundHangAnnotations& aAnnotations) override {
|
2017-08-09 23:59:27 +03:00
|
|
|
int32_t pending = ContentChild::GetSingleton()->GetPendingInputEvents();
|
|
|
|
if (pending > 0) {
|
|
|
|
aAnnotations.AddAnnotation(NS_LITERAL_STRING("PendingInput"), pending);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static PendingInputEventHangAnnotator sSingleton;
|
|
|
|
};
|
|
|
|
PendingInputEventHangAnnotator PendingInputEventHangAnnotator::sSingleton;
|
|
|
|
#endif
|
|
|
|
|
2017-09-16 01:48:37 +03:00
|
|
|
class ContentChild::ShutdownCanary final {};
|
|
|
|
|
2010-07-19 22:33:33 +04:00
|
|
|
ContentChild* ContentChild::sSingleton;
|
2017-09-16 01:48:37 +03:00
|
|
|
StaticAutoPtr<ContentChild::ShutdownCanary> ContentChild::sShutdownCanary;
|
2009-08-13 04:32:50 +04:00
|
|
|
|
2010-07-19 22:33:33 +04:00
|
|
|
ContentChild::ContentChild()
|
2013-01-11 15:19:02 +04:00
|
|
|
: mID(uint64_t(-1))
|
2016-10-20 21:34:16 +03:00
|
|
|
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
2017-06-07 02:35:51 +03:00
|
|
|
,
|
|
|
|
mMainChromeTid(0),
|
2016-10-20 21:34:16 +03:00
|
|
|
mMsaaID(0)
|
|
|
|
#endif
|
2018-06-16 17:21:46 +03:00
|
|
|
,
|
|
|
|
mIsForBrowser(false),
|
2016-01-05 12:59:30 +03:00
|
|
|
mIsAlive(true),
|
2016-09-03 02:23:00 +03:00
|
|
|
mShuttingDown(false) {
|
2016-01-05 12:59:30 +03:00
|
|
|
// This process is a content process, so it's clearly running in
|
|
|
|
// multiprocess mode!
|
|
|
|
nsDebugImpl::SetMultiprocessMode("Child");
|
2017-09-16 01:48:37 +03:00
|
|
|
|
|
|
|
// When ContentChild is created, the observer service does not even exist.
|
|
|
|
// When ContentChild::RecvSetXPCOMProcessAttributes is called (the first
|
|
|
|
// IPDL call made on this object), shutdown may have already happened. Thus
|
|
|
|
// we create a canary here that relies upon getting cleared if shutdown
|
|
|
|
// happens without requiring the observer service at this time.
|
|
|
|
if (!sShutdownCanary) {
|
|
|
|
sShutdownCanary = new ShutdownCanary();
|
|
|
|
ClearOnShutdown(&sShutdownCanary, ShutdownPhase::Shutdown);
|
|
|
|
}
|
2009-08-12 20:18:08 +04:00
|
|
|
}
|
|
|
|
|
2016-12-03 00:46:53 +03:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
# pragma warning(push)
|
|
|
|
# pragma warning( \
|
|
|
|
disable : 4722) /* Silence "destructor never returns" warning \
|
|
|
|
*/
|
|
|
|
#endif
|
|
|
|
|
2010-07-19 22:33:33 +04:00
|
|
|
ContentChild::~ContentChild() {
|
2016-07-29 10:13:10 +03:00
|
|
|
#ifndef NS_FREE_PERMANENT_DATA
|
2016-12-03 00:46:53 +03:00
|
|
|
MOZ_CRASH("Content Child shouldn't be destroyed.");
|
2016-07-29 10:13:10 +03:00
|
|
|
#endif
|
2009-08-12 20:18:08 +04:00
|
|
|
}
|
|
|
|
|
2016-12-03 00:46:53 +03:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
# pragma warning(pop)
|
|
|
|
#endif
|
|
|
|
|
2014-06-11 09:44:06 +04:00
|
|
|
NS_INTERFACE_MAP_BEGIN(ContentChild)
|
2015-10-30 02:30:57 +03:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
|
2019-02-25 23:04:55 +03:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
2014-06-11 09:44:06 +04:00
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
2017-02-05 08:52:38 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSetXPCOMProcessAttributes(
|
|
|
|
const XPCOMInitData& aXPCOMInit, const StructuredCloneData& aInitialData,
|
2017-09-15 00:15:27 +03:00
|
|
|
nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache,
|
2019-03-30 03:23:49 +03:00
|
|
|
nsTArray<SystemFontListEntry>&& aFontList,
|
|
|
|
const Maybe<SharedMemoryHandle>& aSharedUASheetHandle,
|
|
|
|
const uintptr_t& aSharedUASheetAddress) {
|
2017-09-16 01:48:37 +03:00
|
|
|
if (!sShutdownCanary) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-05-30 22:15:35 +03:00
|
|
|
mLookAndFeelCache = std::move(aLookAndFeelIntCache);
|
|
|
|
mFontList = std::move(aFontList);
|
2017-06-28 00:04:17 +03:00
|
|
|
gfx::gfxVars::SetValuesForInitialize(aXPCOMInit.gfxNonDefaultVarUpdates());
|
2019-03-30 03:23:49 +03:00
|
|
|
InitSharedUASheets(aSharedUASheetHandle, aSharedUASheetAddress);
|
2017-02-05 08:52:38 +03:00
|
|
|
InitXPCOM(aXPCOMInit, aInitialData);
|
2017-06-22 20:45:48 +03:00
|
|
|
InitGraphicsDeviceData(aXPCOMInit.contentDeviceData());
|
2017-03-29 08:43:44 +03:00
|
|
|
|
2017-02-05 08:52:38 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2010-07-19 22:33:33 +04:00
|
|
|
bool ContentChild::Init(MessageLoop* aIOLoop, base::ProcessId aParentPid,
|
2018-05-08 17:31:44 +03:00
|
|
|
const char* aParentBuildID, IPC::Channel* aChannel,
|
2017-02-05 08:52:38 +03:00
|
|
|
uint64_t aChildID, bool aIsForBrowser) {
|
2012-06-28 04:15:32 +04:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
2017-10-25 15:53:15 +03:00
|
|
|
// When running X11 only build we need to pass a display down
|
|
|
|
// to gtk_init because it's not going to use the one from the environment
|
|
|
|
// on its own when deciding which backend to use, and when starting under
|
|
|
|
// XWayland, it may choose to start with the wayland backend
|
|
|
|
// instead of the x11 backend.
|
2015-12-23 06:11:45 +03:00
|
|
|
// The DISPLAY environment variable is normally set by the parent process.
|
2017-10-25 15:53:15 +03:00
|
|
|
// The MOZ_GDK_DISPLAY environment variable is set from nsAppRunner.cpp
|
|
|
|
// when --display is set by the command line.
|
2017-04-27 00:29:32 +03:00
|
|
|
if (!gfxPlatform::IsHeadless()) {
|
2017-10-25 15:53:15 +03:00
|
|
|
const char* display_name = PR_GetEnv("MOZ_GDK_DISPLAY");
|
|
|
|
if (!display_name) {
|
2019-05-13 14:19:41 +03:00
|
|
|
bool waylandDisabled = true;
|
|
|
|
# ifdef MOZ_WAYLAND
|
|
|
|
waylandDisabled = IsWaylandDisabled();
|
2017-10-25 15:53:15 +03:00
|
|
|
# endif
|
2019-05-13 14:19:41 +03:00
|
|
|
if (waylandDisabled) {
|
|
|
|
display_name = PR_GetEnv("DISPLAY");
|
|
|
|
}
|
|
|
|
}
|
2017-04-27 00:29:32 +03:00
|
|
|
if (display_name) {
|
|
|
|
int argc = 3;
|
|
|
|
char option_name[] = "--display";
|
|
|
|
char* argv[] = {
|
|
|
|
// argv0 is unused because g_set_prgname() was called in
|
|
|
|
// XRE_InitChildProcess().
|
|
|
|
nullptr, option_name, const_cast<char*>(display_name), nullptr};
|
|
|
|
char** argvp = argv;
|
|
|
|
gtk_init(&argc, &argvp);
|
|
|
|
} else {
|
|
|
|
gtk_init(nullptr, nullptr);
|
|
|
|
}
|
2015-12-23 06:11:45 +03:00
|
|
|
}
|
2010-08-21 03:24:40 +04:00
|
|
|
#endif
|
2010-10-09 01:48:37 +04:00
|
|
|
|
2010-09-10 05:25:26 +04:00
|
|
|
#ifdef MOZ_X11
|
2017-04-27 00:29:32 +03:00
|
|
|
if (!gfxPlatform::IsHeadless()) {
|
|
|
|
// Do this after initializing GDK, or GDK will install its own handler.
|
|
|
|
XRE_InstallX11ErrorHandler();
|
|
|
|
}
|
2010-09-10 05:25:26 +04:00
|
|
|
#endif
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_ASSERTION(!sSingleton, "only one ContentChild per child");
|
2010-11-05 19:38:17 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Once we start sending IPC messages, we need the thread manager to be
|
|
|
|
// initialized so we can deal with the responses. Do that here before we
|
|
|
|
// try to construct the crash reporter.
|
2016-06-10 09:04:49 +03:00
|
|
|
nsresult rv = nsThreadManager::get().Init();
|
2016-01-05 12:59:30 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-01 03:02:30 +04:00
|
|
|
|
2018-07-22 14:51:30 +03:00
|
|
|
// Middleman processes use a special channel for forwarding messages to
|
|
|
|
// their own children.
|
|
|
|
if (recordreplay::IsMiddleman()) {
|
|
|
|
SetMiddlemanIPCChannel(recordreplay::parent::ChannelToUIProcess());
|
2019-05-28 19:00:33 +03:00
|
|
|
|
|
|
|
// Eagerly mark this child as connected, as using another IPC channel will
|
|
|
|
// cause that channel's protocol to be marked as connected instead and
|
|
|
|
// prevent this one from being able to send IPDL messages.
|
|
|
|
ActorConnected();
|
2018-07-22 14:51:30 +03:00
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!Open(aChannel, aParentPid, aIOLoop)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
sSingleton = this;
|
2009-08-13 04:32:50 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// If communications with the parent have broken down, take the process
|
|
|
|
// down so it's not hanging around.
|
2016-08-02 15:54:00 +03:00
|
|
|
GetIPCChannel()->SetAbortOnError(true);
|
2016-08-03 20:54:35 +03:00
|
|
|
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
|
|
|
GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_A11Y_REENTRY);
|
|
|
|
#endif
|
2015-02-13 22:10:56 +03:00
|
|
|
|
2018-05-08 17:31:44 +03:00
|
|
|
// This must be checked before any IPDL message, which may hit sentinel
|
2017-03-11 04:01:38 +03:00
|
|
|
// errors due to parent and content processes having different
|
|
|
|
// versions.
|
2018-05-08 17:31:44 +03:00
|
|
|
MessageChannel* channel = GetIPCChannel();
|
|
|
|
if (channel && !channel->SendBuildIDsMatchMessage(aParentBuildID)) {
|
|
|
|
// We need to quit this process if the buildID doesn't match the parent's.
|
|
|
|
// This can occur when an update occurred in the background.
|
|
|
|
ProcessChild::QuickExit();
|
|
|
|
}
|
2017-03-11 04:01:38 +03:00
|
|
|
|
2019-11-07 12:52:18 +03:00
|
|
|
#if defined(__OpenBSD__) && defined(MOZ_SANDBOX)
|
|
|
|
StartOpenBSDSandbox(GeckoProcessType_Content);
|
|
|
|
#endif
|
|
|
|
|
2014-02-05 20:37:26 +04:00
|
|
|
#ifdef MOZ_X11
|
2019-05-31 19:19:48 +03:00
|
|
|
# ifdef MOZ_WIDGET_GTK
|
|
|
|
if (GDK_IS_X11_DISPLAY(gdk_display_get_default()) &&
|
|
|
|
!gfxPlatform::IsHeadless()) {
|
2017-04-27 00:29:32 +03:00
|
|
|
// Send the parent our X socket to act as a proxy reference for our X
|
|
|
|
// resources.
|
|
|
|
int xSocketFd = ConnectionNumber(DefaultXDisplay());
|
|
|
|
SendBackUpXResources(FileDescriptor(xSocketFd));
|
|
|
|
}
|
2019-05-31 19:19:48 +03:00
|
|
|
# endif
|
2014-02-05 20:37:26 +04:00
|
|
|
#endif
|
|
|
|
|
2017-02-17 05:44:16 +03:00
|
|
|
CrashReporterClient::InitSingleton(this);
|
2010-11-24 17:15:03 +03:00
|
|
|
|
2017-02-05 08:52:38 +03:00
|
|
|
mID = aChildID;
|
|
|
|
mIsForBrowser = aIsForBrowser;
|
2014-02-13 14:42:41 +04:00
|
|
|
|
2017-10-06 11:31:35 +03:00
|
|
|
#ifdef NS_PRINTING
|
|
|
|
// Force the creation of the nsPrintingProxy so that it's IPC counterpart,
|
|
|
|
// PrintingParent, is always available for printing initiated from the parent.
|
|
|
|
RefPtr<nsPrintingProxy> printingProxy = nsPrintingProxy::GetInstance();
|
|
|
|
#endif
|
|
|
|
|
2017-07-25 06:27:40 +03:00
|
|
|
SetProcessName(NS_LITERAL_STRING("Web Content"));
|
2016-10-19 04:54:12 +03:00
|
|
|
|
2017-08-09 23:59:27 +03:00
|
|
|
#ifdef NIGHTLY_BUILD
|
2017-08-25 22:18:03 +03:00
|
|
|
// NOTE: We have to register the annotator on the main thread, as annotators
|
|
|
|
// only affect a single thread.
|
|
|
|
SystemGroup::Dispatch(
|
|
|
|
TaskCategory::Other,
|
|
|
|
NS_NewRunnableFunction("RegisterPendingInputEventHangAnnotator", [] {
|
2018-04-30 04:21:20 +03:00
|
|
|
BackgroundHangMonitor::RegisterAnnotator(
|
2017-08-25 22:18:03 +03:00
|
|
|
PendingInputEventHangAnnotator::sSingleton);
|
|
|
|
}));
|
2017-08-09 23:59:27 +03:00
|
|
|
#endif
|
|
|
|
|
2016-10-19 04:54:12 +03:00
|
|
|
return true;
|
2009-08-12 20:18:08 +04:00
|
|
|
}
|
|
|
|
|
2017-07-25 06:27:40 +03:00
|
|
|
void ContentChild::SetProcessName(const nsAString& aName) {
|
2016-01-05 12:59:30 +03:00
|
|
|
char* name;
|
|
|
|
if ((name = PR_GetEnv("MOZ_DEBUG_APP_PROCESS")) && aName.EqualsASCII(name)) {
|
2012-12-13 03:30:44 +04:00
|
|
|
#ifdef OS_POSIX
|
2016-01-05 12:59:30 +03:00
|
|
|
printf_stderr("\n\nCHILDCHILDCHILDCHILD\n [%s] debug me @%d\n\n", name,
|
|
|
|
getpid());
|
|
|
|
sleep(30);
|
2012-12-13 03:30:44 +04:00
|
|
|
#elif defined(OS_WIN)
|
2016-01-05 12:59:30 +03:00
|
|
|
// Windows has a decent JIT debugging story, so NS_DebugBreak does the
|
|
|
|
// right thing.
|
|
|
|
NS_DebugBreak(NS_DEBUG_BREAK,
|
|
|
|
"Invoking NS_DebugBreak() to debug child process", nullptr,
|
|
|
|
__FILE__, __LINE__);
|
2012-12-13 03:30:44 +04:00
|
|
|
#endif
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2012-12-13 03:30:44 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
mProcessName = aName;
|
2019-02-15 00:19:42 +03:00
|
|
|
NS_LossyConvertUTF16toASCII asciiName(aName);
|
|
|
|
mozilla::ipc::SetThisProcessName(asciiName.get());
|
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
|
|
|
profiler_set_process_name(asciiName);
|
|
|
|
#endif
|
2012-10-06 01:54:54 +04:00
|
|
|
}
|
|
|
|
|
2015-10-30 02:30:57 +03:00
|
|
|
NS_IMETHODIMP
|
2016-01-30 20:05:36 +03:00
|
|
|
ContentChild::ProvideWindow(mozIDOMWindowProxy* aParent, uint32_t aChromeFlags,
|
2015-10-30 02:30:57 +03:00
|
|
|
bool aCalledFromJS, bool aPositionSpecified,
|
|
|
|
bool aSizeSpecified, nsIURI* aURI,
|
|
|
|
const nsAString& aName, const nsACString& aFeatures,
|
2019-04-25 02:50:40 +03:00
|
|
|
bool aForceNoOpener, bool aForceNoReferrer,
|
2018-10-30 03:13:29 +03:00
|
|
|
nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
|
2019-08-02 23:48:33 +03:00
|
|
|
BrowsingContext** aReturn) {
|
2019-04-25 02:50:40 +03:00
|
|
|
return ProvideWindowCommon(
|
|
|
|
nullptr, aParent, false, aChromeFlags, aCalledFromJS, aPositionSpecified,
|
|
|
|
aSizeSpecified, aURI, aName, aFeatures, aForceNoOpener, aForceNoReferrer,
|
|
|
|
aLoadState, aWindowIsNew, aReturn);
|
2015-10-30 02:30:57 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2019-03-15 08:11:43 +03:00
|
|
|
static nsresult GetCreateWindowParams(mozIDOMWindowProxy* aParent,
|
|
|
|
nsDocShellLoadState* aLoadState,
|
2019-04-25 02:50:40 +03:00
|
|
|
bool aForceNoReferrer, float* aFullZoom,
|
2019-03-15 08:11:43 +03:00
|
|
|
nsIReferrerInfo** aReferrerInfo,
|
|
|
|
nsIPrincipal** aTriggeringPrincipal,
|
|
|
|
nsIContentSecurityPolicy** aCsp) {
|
2016-11-24 18:08:31 +03:00
|
|
|
*aFullZoom = 1.0f;
|
2019-02-21 18:00:32 +03:00
|
|
|
if (!aTriggeringPrincipal || !aCsp) {
|
|
|
|
NS_ERROR("aTriggeringPrincipal || aCsp is null");
|
2018-07-04 17:20:59 +03:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2019-03-15 08:11:43 +03:00
|
|
|
|
|
|
|
if (!aReferrerInfo) {
|
|
|
|
NS_ERROR("aReferrerInfo is null");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIReferrerInfo> referrerInfo;
|
2019-04-25 02:50:40 +03:00
|
|
|
if (aForceNoReferrer) {
|
2019-08-21 16:24:45 +03:00
|
|
|
referrerInfo = new ReferrerInfo(nullptr, ReferrerPolicy::_empty, false);
|
2019-04-25 02:50:40 +03:00
|
|
|
}
|
|
|
|
if (aLoadState && !referrerInfo) {
|
2019-03-15 08:11:43 +03:00
|
|
|
referrerInfo = aLoadState->GetReferrerInfo();
|
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
auto* opener = nsPIDOMWindowOuter::From(aParent);
|
|
|
|
if (!opener) {
|
2018-07-04 17:20:59 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> nullPrincipal =
|
|
|
|
NullPrincipal::CreateWithoutOriginAttributes();
|
2019-03-15 08:11:43 +03:00
|
|
|
if (!referrerInfo) {
|
2019-08-21 16:24:45 +03:00
|
|
|
referrerInfo = new ReferrerInfo(nullptr, ReferrerPolicy::_empty);
|
2019-03-15 08:11:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
referrerInfo.swap(*aReferrerInfo);
|
2017-07-05 22:57:47 +03:00
|
|
|
NS_ADDREF(*aTriggeringPrincipal = nullPrincipal);
|
2016-11-24 18:08:31 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2019-01-02 16:05:23 +03:00
|
|
|
nsCOMPtr<Document> doc = opener->GetDoc();
|
2017-07-05 22:57:47 +03:00
|
|
|
NS_ADDREF(*aTriggeringPrincipal = doc->NodePrincipal());
|
2019-02-21 18:00:32 +03:00
|
|
|
|
2019-05-22 02:14:27 +03:00
|
|
|
nsCOMPtr<nsIContentSecurityPolicy> csp = doc->GetCsp();
|
2019-02-21 18:00:32 +03:00
|
|
|
if (csp) {
|
|
|
|
csp.forget(aCsp);
|
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
|
|
|
|
if (!baseURI) {
|
2019-01-02 16:05:23 +03:00
|
|
|
NS_ERROR("Document didn't return a base URI");
|
2016-11-24 18:08:31 +03:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2019-03-15 08:11:43 +03:00
|
|
|
if (!referrerInfo) {
|
2019-06-06 10:23:37 +03:00
|
|
|
referrerInfo = new ReferrerInfo();
|
|
|
|
referrerInfo->InitWithDocument(doc);
|
2017-11-30 16:42:05 +03:00
|
|
|
}
|
|
|
|
|
2019-03-15 08:11:43 +03:00
|
|
|
referrerInfo.swap(*aReferrerInfo);
|
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
RefPtr<nsDocShell> openerDocShell =
|
|
|
|
static_cast<nsDocShell*>(opener->GetDocShell());
|
|
|
|
if (!openerDocShell) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContentViewer> cv;
|
|
|
|
nsresult rv = openerDocShell->GetContentViewer(getter_AddRefs(cv));
|
|
|
|
if (NS_SUCCEEDED(rv) && cv) {
|
|
|
|
cv->GetFullZoom(aFullZoom);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2015-10-30 02:30:57 +03:00
|
|
|
nsresult ContentChild::ProvideWindowCommon(
|
2019-04-10 01:39:01 +03:00
|
|
|
BrowserChild* aTabOpener, mozIDOMWindowProxy* aParent, bool aIframeMoz,
|
2015-10-30 02:30:57 +03:00
|
|
|
uint32_t aChromeFlags, bool aCalledFromJS, bool aPositionSpecified,
|
|
|
|
bool aSizeSpecified, nsIURI* aURI, const nsAString& aName,
|
2019-04-25 02:50:40 +03:00
|
|
|
const nsACString& aFeatures, bool aForceNoOpener, bool aForceNoReferrer,
|
2018-10-30 03:13:29 +03:00
|
|
|
nsDocShellLoadState* aLoadState, bool* aWindowIsNew,
|
2019-08-02 23:48:33 +03:00
|
|
|
BrowsingContext** aReturn) {
|
2016-01-05 12:59:30 +03:00
|
|
|
*aReturn = nullptr;
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsAutoPtr<IPCTabContext> ipcContext;
|
|
|
|
TabId openerTabId = TabId(0);
|
2016-11-24 18:08:31 +03:00
|
|
|
nsAutoCString features(aFeatures);
|
2017-06-05 20:31:19 +03:00
|
|
|
nsAutoString name(aName);
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
nsresult rv;
|
2017-06-05 20:31:19 +03:00
|
|
|
|
|
|
|
MOZ_ASSERT(!aParent || aTabOpener,
|
|
|
|
"If aParent is non-null, we should have an aTabOpener");
|
|
|
|
|
|
|
|
// Cache the boolean preference for allowing noopener windows to open in a
|
|
|
|
// separate process.
|
|
|
|
static bool sNoopenerNewProcess = false;
|
|
|
|
static bool sNoopenerNewProcessInited = false;
|
|
|
|
if (!sNoopenerNewProcessInited) {
|
|
|
|
Preferences::AddBoolVarCache(&sNoopenerNewProcess,
|
|
|
|
"dom.noopener.newprocess.enabled");
|
|
|
|
sNoopenerNewProcessInited = true;
|
|
|
|
}
|
|
|
|
|
2019-10-11 22:59:10 +03:00
|
|
|
bool useRemoteSubframes =
|
|
|
|
aChromeFlags & nsIWebBrowserChrome::CHROME_FISSION_WINDOW;
|
|
|
|
|
|
|
|
// Check if we should load in a different process. Under Fission, we never
|
|
|
|
// want to do this, since the Fission process selection logic will handle
|
|
|
|
// everything for us. Outside of Fission, we always want to load in a
|
2017-06-05 20:31:19 +03:00
|
|
|
// different process if we have noopener set, but we also might if we can't
|
|
|
|
// load in the current process.
|
2019-10-11 22:59:10 +03:00
|
|
|
bool loadInDifferentProcess =
|
|
|
|
aForceNoOpener && sNoopenerNewProcess && !useRemoteSubframes;
|
2017-07-05 20:11:33 +03:00
|
|
|
if (aTabOpener && !loadInDifferentProcess && aURI) {
|
2019-06-27 22:22:12 +03:00
|
|
|
nsCOMPtr<nsILoadContext> context;
|
|
|
|
if (aParent) {
|
|
|
|
context = do_GetInterface(aTabOpener->WebNavigation());
|
|
|
|
}
|
|
|
|
// Only special-case cross-process loads if Fission is disabled. With
|
|
|
|
// Fission enabled, the initial in-process load will automatically be
|
|
|
|
// retargeted to the correct process.
|
|
|
|
if (!(context && context->UseRemoteSubframes())) {
|
|
|
|
nsCOMPtr<nsIWebBrowserChrome3> browserChrome3;
|
|
|
|
rv = aTabOpener->GetWebBrowserChrome(getter_AddRefs(browserChrome3));
|
|
|
|
if (NS_SUCCEEDED(rv) && browserChrome3) {
|
|
|
|
bool shouldLoad;
|
|
|
|
rv = browserChrome3->ShouldLoadURIInThisProcess(aURI, &shouldLoad);
|
|
|
|
loadInDifferentProcess = NS_SUCCEEDED(rv) && !shouldLoad;
|
|
|
|
}
|
2017-06-05 20:31:19 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we're in a content process and we have noopener set, there's no reason
|
|
|
|
// to load in our process, so let's load it elsewhere!
|
|
|
|
if (loadInDifferentProcess) {
|
|
|
|
float fullZoom;
|
2017-07-05 22:57:47 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
|
2019-02-21 18:00:32 +03:00
|
|
|
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
2019-03-15 08:11:43 +03:00
|
|
|
nsCOMPtr<nsIReferrerInfo> referrerInfo;
|
2019-04-25 02:50:40 +03:00
|
|
|
rv = GetCreateWindowParams(aParent, aLoadState, aForceNoReferrer, &fullZoom,
|
|
|
|
getter_AddRefs(referrerInfo),
|
|
|
|
getter_AddRefs(triggeringPrincipal),
|
|
|
|
getter_AddRefs(csp));
|
2017-06-05 20:31:19 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
2016-11-24 18:08:31 +03:00
|
|
|
}
|
|
|
|
|
2019-03-06 17:05:50 +03:00
|
|
|
Maybe<URIParams> uriToLoad;
|
2017-06-05 20:31:19 +03:00
|
|
|
SerializeURI(aURI, uriToLoad);
|
2019-04-05 23:14:03 +03:00
|
|
|
|
|
|
|
if (name.LowerCaseEqualsLiteral("_blank")) {
|
|
|
|
name = EmptyString();
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(!nsContentUtils::IsSpecialName(name));
|
|
|
|
|
2017-06-05 20:31:19 +03:00
|
|
|
Unused << SendCreateWindowInDifferentProcess(
|
|
|
|
aTabOpener, aChromeFlags, aCalledFromJS, aPositionSpecified,
|
2019-03-15 08:11:43 +03:00
|
|
|
aSizeSpecified, uriToLoad, features, fullZoom, name,
|
2019-06-28 23:10:03 +03:00
|
|
|
triggeringPrincipal, csp, referrerInfo);
|
2017-06-05 20:31:19 +03:00
|
|
|
|
|
|
|
// We return NS_ERROR_ABORT, so that the caller knows that we've abandoned
|
|
|
|
// the window open as far as it is concerned.
|
|
|
|
return NS_ERROR_ABORT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aTabOpener) {
|
2016-01-05 12:59:30 +03:00
|
|
|
PopupIPCTabContext context;
|
|
|
|
openerTabId = aTabOpener->GetTabId();
|
|
|
|
context.opener() = openerTabId;
|
2016-02-18 07:35:45 +03:00
|
|
|
context.isMozBrowserElement() = aTabOpener->IsMozBrowserElement();
|
2016-01-05 12:59:30 +03:00
|
|
|
ipcContext = new IPCTabContext(context);
|
|
|
|
} else {
|
2019-04-10 01:39:01 +03:00
|
|
|
// It's possible to not have a BrowserChild opener in the case
|
2016-01-05 12:59:30 +03:00
|
|
|
// of ServiceWorker::OpenWindow.
|
|
|
|
UnsafeIPCTabContext unsafeTabContext;
|
|
|
|
ipcContext = new IPCTabContext(unsafeTabContext);
|
|
|
|
}
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(ipcContext);
|
2017-04-05 13:42:00 +03:00
|
|
|
TabId tabId(nsContentUtils::GenerateTabId());
|
2016-01-05 12:59:30 +03:00
|
|
|
|
2017-04-07 02:46:18 +03:00
|
|
|
// We need to assign a TabGroup to the PBrowser actor before we send it to the
|
|
|
|
// parent. Otherwise, the parent could send messages to us before we have a
|
|
|
|
// proper TabGroup for that actor.
|
|
|
|
RefPtr<TabGroup> tabGroup;
|
2019-08-28 21:07:28 +03:00
|
|
|
RefPtr<BrowsingContext> openerBC;
|
2017-04-07 02:46:18 +03:00
|
|
|
if (aTabOpener && !aForceNoOpener) {
|
|
|
|
// The new actor will use the same tab group as the opener.
|
|
|
|
tabGroup = aTabOpener->TabGroup();
|
2019-08-28 21:07:28 +03:00
|
|
|
if (aParent) {
|
|
|
|
openerBC = nsPIDOMWindowOuter::From(aParent)->GetBrowsingContext();
|
|
|
|
}
|
2017-04-07 02:46:18 +03:00
|
|
|
} else {
|
|
|
|
tabGroup = new TabGroup();
|
|
|
|
}
|
|
|
|
|
2019-03-14 21:50:45 +03:00
|
|
|
RefPtr<BrowsingContext> browsingContext = BrowsingContext::Create(
|
|
|
|
nullptr, openerBC, aName, BrowsingContext::Type::Content);
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
TabContext newTabContext = aTabOpener ? *aTabOpener : TabContext();
|
2019-08-08 19:07:05 +03:00
|
|
|
|
2019-08-08 19:07:07 +03:00
|
|
|
// The initial about:blank document we generate within the nsDocShell will
|
|
|
|
// almost certainly be replaced at some point. Unfortunately, getting the
|
|
|
|
// principal right here causes bugs due to frame scripts not getting events
|
|
|
|
// they expect, due to the real initial about:blank not being created yet.
|
|
|
|
//
|
|
|
|
// For this reason, we intentionally mispredict the initial principal here, so
|
|
|
|
// that we can act the same as we did before when not predicting a result
|
|
|
|
// principal. This `PWindowGlobal` will almost immediately be destroyed.
|
|
|
|
nsCOMPtr<nsIPrincipal> initialPrincipal =
|
|
|
|
NullPrincipal::Create(newTabContext.OriginAttributesRef());
|
|
|
|
WindowGlobalInit windowInit = WindowGlobalActor::AboutBlankInitializer(
|
|
|
|
browsingContext, initialPrincipal);
|
|
|
|
|
|
|
|
auto windowChild = MakeRefPtr<WindowGlobalChild>(windowInit, nullptr);
|
|
|
|
|
|
|
|
auto newChild = MakeRefPtr<BrowserChild>(this, tabId, tabGroup, newTabContext,
|
|
|
|
browsingContext, aChromeFlags,
|
|
|
|
/* aIsTopLevel */ true);
|
2016-01-05 12:59:30 +03:00
|
|
|
|
|
|
|
if (aTabOpener) {
|
|
|
|
MOZ_ASSERT(ipcContext->type() == IPCTabContext::TPopupIPCTabContext);
|
|
|
|
ipcContext->get_PopupIPCTabContext().opener() = aTabOpener;
|
|
|
|
}
|
|
|
|
|
2016-11-04 21:13:52 +03:00
|
|
|
nsCOMPtr<nsIEventTarget> target =
|
|
|
|
tabGroup->EventTargetFor(TaskCategory::Other);
|
|
|
|
SetEventTargetForActor(newChild, target);
|
|
|
|
|
2019-04-17 03:51:38 +03:00
|
|
|
if (IsShuttingDown()) {
|
|
|
|
return NS_ERROR_ABORT;
|
|
|
|
}
|
|
|
|
|
2019-08-08 19:46:24 +03:00
|
|
|
// Open a remote endpoint for our PBrowser actor.
|
|
|
|
ManagedEndpoint<PBrowserParent> parentEp = OpenPBrowserEndpoint(newChild);
|
2019-04-17 03:51:38 +03:00
|
|
|
if (NS_WARN_IF(!parentEp.IsValid())) {
|
|
|
|
return NS_ERROR_ABORT;
|
|
|
|
}
|
|
|
|
|
2019-08-08 19:07:07 +03:00
|
|
|
// Open a remote endpoint for our PWindowGlobal actor.
|
|
|
|
ManagedEndpoint<PWindowGlobalParent> windowParentEp =
|
2019-08-08 19:46:20 +03:00
|
|
|
newChild->OpenPWindowGlobalEndpoint(windowChild);
|
2019-08-08 19:07:07 +03:00
|
|
|
if (NS_WARN_IF(!windowParentEp.IsValid())) {
|
|
|
|
return NS_ERROR_ABORT;
|
|
|
|
}
|
|
|
|
|
2019-04-17 03:51:38 +03:00
|
|
|
// Tell the parent process to set up its PBrowserParent.
|
2019-08-08 19:07:07 +03:00
|
|
|
if (NS_WARN_IF(!SendConstructPopupBrowser(
|
|
|
|
std::move(parentEp), std::move(windowParentEp), tabId, *ipcContext,
|
|
|
|
windowInit, aChromeFlags))) {
|
2019-04-17 03:51:38 +03:00
|
|
|
return NS_ERROR_ABORT;
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
|
2019-08-08 19:07:07 +03:00
|
|
|
windowChild->Init();
|
|
|
|
|
2018-08-30 01:21:25 +03:00
|
|
|
// Now that |newChild| has had its IPC link established, call |Init| to set it
|
|
|
|
// up.
|
2019-08-08 19:07:07 +03:00
|
|
|
if (NS_FAILED(newChild->Init(aParent, windowChild))) {
|
2018-08-30 01:21:25 +03:00
|
|
|
return NS_ERROR_ABORT;
|
|
|
|
}
|
|
|
|
|
2017-06-15 20:28:11 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowInner> parentTopInnerWindow;
|
|
|
|
if (aParent) {
|
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> parentTopWindow =
|
2019-07-26 19:48:31 +03:00
|
|
|
nsPIDOMWindowOuter::From(aParent)->GetInProcessTop();
|
2017-06-15 20:28:11 +03:00
|
|
|
if (parentTopWindow) {
|
|
|
|
parentTopInnerWindow = parentTopWindow->GetCurrentInnerWindow();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Bug 1416728 - Process the CreateWindow reply message in order with other PContent IPC messages, r=bz
Previously we used the MozPromise interface for calling an async-message over
IPC with a reply. Unfortunately, MozPromise processes the reply asynchronously,
potentially allowing other IPC messages to be processed before the `->Then`
callback is processed.
In the original CreateWindow patch I tried to work around this by setting the
target of the `->Then` callback to be StableStateEventTarget. This worked,
however as it isn't safe to run scripts etc. in the stable state, we instead
tried to exit the nested event loop immediately after the runnable ran, and then
performed processing of the reply.
Unfortunately, this bug exposed a problem with that design. If we have multiple
nested event loops then we cannot guarantee that we'll exit the nested event
loop immediately after recieving the `->Then` callback, which meant that we
could still process other IPC messages before we processed the CreateWindow
reply.
The fix to this was to add a new API to allow passing callbacks directly into
IPC send methods, ensure that those callbacks are called in IPC order, and
fully process the CreateWindow reply in the callback, rather than waiting for
the nested event loop to exit.
MozReview-Commit-ID: D6zaMJRxhXd
2017-11-16 23:59:52 +03:00
|
|
|
// Set to true when we're ready to return from this function.
|
|
|
|
bool ready = false;
|
|
|
|
|
|
|
|
// NOTE: Capturing by reference here is safe, as this function won't return
|
|
|
|
// until one of these callbacks is called.
|
|
|
|
auto resolve = [&](const CreatedWindowInfo& info) {
|
|
|
|
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
|
|
|
rv = info.rv();
|
|
|
|
*aWindowIsNew = info.windowOpened();
|
|
|
|
nsTArray<FrameScriptInfo> frameScripts(info.frameScripts());
|
|
|
|
nsCString urlToLoad = info.urlToLoad();
|
|
|
|
uint32_t maxTouchPoints = info.maxTouchPoints();
|
|
|
|
DimensionInfo dimensionInfo = info.dimensions();
|
2018-07-19 21:05:35 +03:00
|
|
|
bool hasSiblings = info.hasSiblings();
|
Bug 1416728 - Process the CreateWindow reply message in order with other PContent IPC messages, r=bz
Previously we used the MozPromise interface for calling an async-message over
IPC with a reply. Unfortunately, MozPromise processes the reply asynchronously,
potentially allowing other IPC messages to be processed before the `->Then`
callback is processed.
In the original CreateWindow patch I tried to work around this by setting the
target of the `->Then` callback to be StableStateEventTarget. This worked,
however as it isn't safe to run scripts etc. in the stable state, we instead
tried to exit the nested event loop immediately after the runnable ran, and then
performed processing of the reply.
Unfortunately, this bug exposed a problem with that design. If we have multiple
nested event loops then we cannot guarantee that we'll exit the nested event
loop immediately after recieving the `->Then` callback, which meant that we
could still process other IPC messages before we processed the CreateWindow
reply.
The fix to this was to add a new API to allow passing callbacks directly into
IPC send methods, ensure that those callbacks are called in IPC order, and
fully process the CreateWindow reply in the callback, rather than waiting for
the nested event loop to exit.
MozReview-Commit-ID: D6zaMJRxhXd
2017-11-16 23:59:52 +03:00
|
|
|
|
|
|
|
// Once this function exits, we should try to exit the nested event loop.
|
|
|
|
ready = true;
|
|
|
|
|
|
|
|
// NOTE: We have to handle this immediately in the resolve callback in order
|
|
|
|
// to make sure that we don't process any more IPC messages before returning
|
|
|
|
// from ProvideWindowCommon.
|
|
|
|
|
|
|
|
// Handle the error which we got back from the parent process, if we got
|
|
|
|
// one.
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!*aWindowIsNew) {
|
|
|
|
rv = NS_ERROR_ABORT;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-10 01:39:01 +03:00
|
|
|
// If the BrowserChild has been torn down, we don't need to do this anymore.
|
Bug 1416728 - Process the CreateWindow reply message in order with other PContent IPC messages, r=bz
Previously we used the MozPromise interface for calling an async-message over
IPC with a reply. Unfortunately, MozPromise processes the reply asynchronously,
potentially allowing other IPC messages to be processed before the `->Then`
callback is processed.
In the original CreateWindow patch I tried to work around this by setting the
target of the `->Then` callback to be StableStateEventTarget. This worked,
however as it isn't safe to run scripts etc. in the stable state, we instead
tried to exit the nested event loop immediately after the runnable ran, and then
performed processing of the reply.
Unfortunately, this bug exposed a problem with that design. If we have multiple
nested event loops then we cannot guarantee that we'll exit the nested event
loop immediately after recieving the `->Then` callback, which meant that we
could still process other IPC messages before we processed the CreateWindow
reply.
The fix to this was to add a new API to allow passing callbacks directly into
IPC send methods, ensure that those callbacks are called in IPC order, and
fully process the CreateWindow reply in the callback, rather than waiting for
the nested event loop to exit.
MozReview-Commit-ID: D6zaMJRxhXd
2017-11-16 23:59:52 +03:00
|
|
|
if (NS_WARN_IF(!newChild->IPCOpen() || newChild->IsDestroyed())) {
|
|
|
|
rv = NS_ERROR_ABORT;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ShowInfo showInfo(EmptyString(), false, false, true, false, 0, 0, 0);
|
|
|
|
auto* opener = nsPIDOMWindowOuter::From(aParent);
|
|
|
|
nsIDocShell* openerShell;
|
|
|
|
if (opener && (openerShell = opener->GetDocShell())) {
|
|
|
|
nsCOMPtr<nsILoadContext> context = do_QueryInterface(openerShell);
|
|
|
|
showInfo = ShowInfo(EmptyString(), false, context->UsePrivateBrowsing(),
|
|
|
|
true, false, aTabOpener->WebWidget()->GetDPI(),
|
|
|
|
aTabOpener->WebWidget()->RoundsWidgetCoordinatesTo(),
|
|
|
|
aTabOpener->WebWidget()->GetDefaultScale().scale);
|
|
|
|
}
|
|
|
|
|
|
|
|
newChild->SetMaxTouchPoints(maxTouchPoints);
|
2018-07-19 21:05:35 +03:00
|
|
|
newChild->SetHasSiblings(hasSiblings);
|
Bug 1416728 - Process the CreateWindow reply message in order with other PContent IPC messages, r=bz
Previously we used the MozPromise interface for calling an async-message over
IPC with a reply. Unfortunately, MozPromise processes the reply asynchronously,
potentially allowing other IPC messages to be processed before the `->Then`
callback is processed.
In the original CreateWindow patch I tried to work around this by setting the
target of the `->Then` callback to be StableStateEventTarget. This worked,
however as it isn't safe to run scripts etc. in the stable state, we instead
tried to exit the nested event loop immediately after the runnable ran, and then
performed processing of the reply.
Unfortunately, this bug exposed a problem with that design. If we have multiple
nested event loops then we cannot guarantee that we'll exit the nested event
loop immediately after recieving the `->Then` callback, which meant that we
could still process other IPC messages before we processed the CreateWindow
reply.
The fix to this was to add a new API to allow passing callbacks directly into
IPC send methods, ensure that those callbacks are called in IPC order, and
fully process the CreateWindow reply in the callback, rather than waiting for
the nested event loop to exit.
MozReview-Commit-ID: D6zaMJRxhXd
2017-11-16 23:59:52 +03:00
|
|
|
|
2019-08-28 21:07:45 +03:00
|
|
|
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
|
|
|
if (nsCOMPtr<nsPIDOMWindowOuter> outer =
|
|
|
|
do_GetInterface(newChild->WebNavigation())) {
|
|
|
|
BrowsingContext* bc = outer->GetBrowsingContext();
|
|
|
|
auto parentBC =
|
|
|
|
aParent
|
|
|
|
? nsPIDOMWindowOuter::From(aParent)->GetBrowsingContext()->Id()
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
if (aForceNoOpener) {
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(!*aWindowIsNew || !bc->HadOriginalOpener());
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(bc->GetOpenerId() == 0);
|
|
|
|
} else {
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(!*aWindowIsNew ||
|
|
|
|
bc->HadOriginalOpener() == !!parentBC);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(bc->GetOpenerId() == parentBC);
|
|
|
|
}
|
Bug 1416728 - Process the CreateWindow reply message in order with other PContent IPC messages, r=bz
Previously we used the MozPromise interface for calling an async-message over
IPC with a reply. Unfortunately, MozPromise processes the reply asynchronously,
potentially allowing other IPC messages to be processed before the `->Then`
callback is processed.
In the original CreateWindow patch I tried to work around this by setting the
target of the `->Then` callback to be StableStateEventTarget. This worked,
however as it isn't safe to run scripts etc. in the stable state, we instead
tried to exit the nested event loop immediately after the runnable ran, and then
performed processing of the reply.
Unfortunately, this bug exposed a problem with that design. If we have multiple
nested event loops then we cannot guarantee that we'll exit the nested event
loop immediately after recieving the `->Then` callback, which meant that we
could still process other IPC messages before we processed the CreateWindow
reply.
The fix to this was to add a new API to allow passing callbacks directly into
IPC send methods, ensure that those callbacks are called in IPC order, and
fully process the CreateWindow reply in the callback, rather than waiting for
the nested event loop to exit.
MozReview-Commit-ID: D6zaMJRxhXd
2017-11-16 23:59:52 +03:00
|
|
|
}
|
2019-08-28 21:07:45 +03:00
|
|
|
#endif
|
Bug 1416728 - Process the CreateWindow reply message in order with other PContent IPC messages, r=bz
Previously we used the MozPromise interface for calling an async-message over
IPC with a reply. Unfortunately, MozPromise processes the reply asynchronously,
potentially allowing other IPC messages to be processed before the `->Then`
callback is processed.
In the original CreateWindow patch I tried to work around this by setting the
target of the `->Then` callback to be StableStateEventTarget. This worked,
however as it isn't safe to run scripts etc. in the stable state, we instead
tried to exit the nested event loop immediately after the runnable ran, and then
performed processing of the reply.
Unfortunately, this bug exposed a problem with that design. If we have multiple
nested event loops then we cannot guarantee that we'll exit the nested event
loop immediately after recieving the `->Then` callback, which meant that we
could still process other IPC messages before we processed the CreateWindow
reply.
The fix to this was to add a new API to allow passing callbacks directly into
IPC send methods, ensure that those callbacks are called in IPC order, and
fully process the CreateWindow reply in the callback, rather than waiting for
the nested event loop to exit.
MozReview-Commit-ID: D6zaMJRxhXd
2017-11-16 23:59:52 +03:00
|
|
|
|
|
|
|
// Unfortunately we don't get a window unless we've shown the frame. That's
|
|
|
|
// pretty bogus; see bug 763602.
|
2018-11-05 22:21:35 +03:00
|
|
|
newChild->DoFakeShow(showInfo);
|
Bug 1416728 - Process the CreateWindow reply message in order with other PContent IPC messages, r=bz
Previously we used the MozPromise interface for calling an async-message over
IPC with a reply. Unfortunately, MozPromise processes the reply asynchronously,
potentially allowing other IPC messages to be processed before the `->Then`
callback is processed.
In the original CreateWindow patch I tried to work around this by setting the
target of the `->Then` callback to be StableStateEventTarget. This worked,
however as it isn't safe to run scripts etc. in the stable state, we instead
tried to exit the nested event loop immediately after the runnable ran, and then
performed processing of the reply.
Unfortunately, this bug exposed a problem with that design. If we have multiple
nested event loops then we cannot guarantee that we'll exit the nested event
loop immediately after recieving the `->Then` callback, which meant that we
could still process other IPC messages before we processed the CreateWindow
reply.
The fix to this was to add a new API to allow passing callbacks directly into
IPC send methods, ensure that those callbacks are called in IPC order, and
fully process the CreateWindow reply in the callback, rather than waiting for
the nested event loop to exit.
MozReview-Commit-ID: D6zaMJRxhXd
2017-11-16 23:59:52 +03:00
|
|
|
|
|
|
|
newChild->RecvUpdateDimensions(dimensionInfo);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < frameScripts.Length(); i++) {
|
|
|
|
FrameScriptInfo& info = frameScripts[i];
|
|
|
|
if (!newChild->RecvLoadRemoteScript(info.url(),
|
|
|
|
info.runInGlobalScope())) {
|
|
|
|
MOZ_CRASH();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-18 01:19:50 +03:00
|
|
|
if (xpc::IsInAutomation()) {
|
|
|
|
if (nsCOMPtr<nsPIDOMWindowOuter> outer =
|
|
|
|
do_GetInterface(newChild->WebNavigation())) {
|
|
|
|
nsCOMPtr<nsIObserverService> obs(services::GetObserverService());
|
|
|
|
obs->NotifyObservers(
|
|
|
|
outer, "dangerous:test-only:new-browser-child-ready", nullptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Bug 1561015: Part 2 - Return BrowsingContext from openWindow2. r=bzbarsky
There are some unfortunate aspects of openWindow() and openWindow2() that make
this difficult. Namely, they sometimes return top-level chrome windows, and
sometimes a single content window from the top-level chrome window that they
open, depending on how they're called.
There really isn't any reason to return a BrowsingContext rather than a chrome
window in the former case, but there also really isn't a way to make the API
polymorphic in a way that would allow handling the two cases differently. So
at some point, the two cases should ideally be split into separate APIs rather
than separate special cases of a single API.
In the mean time, I've left openWindow() returning local mozIDOMWindowProxy
objects, since it isn't used by the DOM window.open() or openDialog() APIs,
and only updated openWindow2(). As a follow-up, we should remove both
openWindow() and openWindow2(), and replace them with openChromeWindow() and
openContentWindow() (or similar) methods which make it immediately clear what
type of window is being returned.
Differential Revision: https://phabricator.services.mozilla.com/D35689
--HG--
extra : moz-landing-system : lando
2019-08-02 23:48:40 +03:00
|
|
|
browsingContext.forget(aReturn);
|
Bug 1416728 - Process the CreateWindow reply message in order with other PContent IPC messages, r=bz
Previously we used the MozPromise interface for calling an async-message over
IPC with a reply. Unfortunately, MozPromise processes the reply asynchronously,
potentially allowing other IPC messages to be processed before the `->Then`
callback is processed.
In the original CreateWindow patch I tried to work around this by setting the
target of the `->Then` callback to be StableStateEventTarget. This worked,
however as it isn't safe to run scripts etc. in the stable state, we instead
tried to exit the nested event loop immediately after the runnable ran, and then
performed processing of the reply.
Unfortunately, this bug exposed a problem with that design. If we have multiple
nested event loops then we cannot guarantee that we'll exit the nested event
loop immediately after recieving the `->Then` callback, which meant that we
could still process other IPC messages before we processed the CreateWindow
reply.
The fix to this was to add a new API to allow passing callbacks directly into
IPC send methods, ensure that those callbacks are called in IPC order, and
fully process the CreateWindow reply in the callback, rather than waiting for
the nested event loop to exit.
MozReview-Commit-ID: D6zaMJRxhXd
2017-11-16 23:59:52 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
// NOTE: Capturing by reference here is safe, as this function won't return
|
|
|
|
// until one of these callbacks is called.
|
|
|
|
auto reject = [&](ResponseRejectReason) {
|
|
|
|
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
|
|
|
NS_WARNING("windowCreated promise rejected");
|
|
|
|
rv = NS_ERROR_NOT_AVAILABLE;
|
|
|
|
ready = true;
|
|
|
|
};
|
|
|
|
|
2017-06-15 20:28:11 +03:00
|
|
|
// Send down the request to open the window.
|
2016-01-05 12:59:30 +03:00
|
|
|
if (aIframeMoz) {
|
|
|
|
MOZ_ASSERT(aTabOpener);
|
2016-05-03 18:15:07 +03:00
|
|
|
nsAutoCString url;
|
|
|
|
if (aURI) {
|
|
|
|
aURI->GetSpec(url);
|
|
|
|
} else {
|
|
|
|
// We can't actually send a nullptr up as the URI, since IPDL doesn't let
|
|
|
|
// us send nullptr's for primitives. We indicate that the nsString for the
|
|
|
|
// URI should be converted to a nullptr by voiding the string.
|
|
|
|
url.SetIsVoid(true);
|
|
|
|
}
|
|
|
|
|
2017-06-15 20:28:11 +03:00
|
|
|
// NOTE: BrowserFrameOpenWindowPromise is the same type as
|
|
|
|
// CreateWindowPromise, and this code depends on that fact.
|
2019-04-25 02:50:40 +03:00
|
|
|
newChild->SendBrowserFrameOpenWindow(
|
|
|
|
aTabOpener, NS_ConvertUTF8toUTF16(url), name, aForceNoReferrer,
|
|
|
|
NS_ConvertUTF8toUTF16(features), std::move(resolve), std::move(reject));
|
2016-01-05 12:59:30 +03:00
|
|
|
} else {
|
2016-11-24 18:08:31 +03:00
|
|
|
float fullZoom;
|
2017-07-05 22:57:47 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
|
2019-02-21 18:00:32 +03:00
|
|
|
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
2019-03-15 08:11:43 +03:00
|
|
|
nsCOMPtr<nsIReferrerInfo> referrerInfo;
|
2019-04-25 02:50:40 +03:00
|
|
|
rv = GetCreateWindowParams(aParent, aLoadState, aForceNoReferrer, &fullZoom,
|
|
|
|
getter_AddRefs(referrerInfo),
|
|
|
|
getter_AddRefs(triggeringPrincipal),
|
|
|
|
getter_AddRefs(csp));
|
2016-11-24 18:08:31 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
2016-02-18 11:33:07 +03:00
|
|
|
}
|
|
|
|
|
2019-03-06 17:05:50 +03:00
|
|
|
Maybe<URIParams> uriToLoad;
|
2017-08-24 16:43:28 +03:00
|
|
|
if (aURI) {
|
|
|
|
SerializeURI(aURI, uriToLoad);
|
|
|
|
}
|
|
|
|
|
2018-11-05 21:45:06 +03:00
|
|
|
SendCreateWindow(aTabOpener, newChild, aChromeFlags, aCalledFromJS,
|
Bug 1416728 - Process the CreateWindow reply message in order with other PContent IPC messages, r=bz
Previously we used the MozPromise interface for calling an async-message over
IPC with a reply. Unfortunately, MozPromise processes the reply asynchronously,
potentially allowing other IPC messages to be processed before the `->Then`
callback is processed.
In the original CreateWindow patch I tried to work around this by setting the
target of the `->Then` callback to be StableStateEventTarget. This worked,
however as it isn't safe to run scripts etc. in the stable state, we instead
tried to exit the nested event loop immediately after the runnable ran, and then
performed processing of the reply.
Unfortunately, this bug exposed a problem with that design. If we have multiple
nested event loops then we cannot guarantee that we'll exit the nested event
loop immediately after recieving the `->Then` callback, which meant that we
could still process other IPC messages before we processed the CreateWindow
reply.
The fix to this was to add a new API to allow passing callbacks directly into
IPC send methods, ensure that those callbacks are called in IPC order, and
fully process the CreateWindow reply in the callback, rather than waiting for
the nested event loop to exit.
MozReview-Commit-ID: D6zaMJRxhXd
2017-11-16 23:59:52 +03:00
|
|
|
aPositionSpecified, aSizeSpecified, uriToLoad, features,
|
2019-03-15 08:11:43 +03:00
|
|
|
fullZoom, Principal(triggeringPrincipal), csp,
|
|
|
|
referrerInfo, std::move(resolve), std::move(reject));
|
2017-06-15 20:28:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// =======================
|
|
|
|
// Begin Nested Event Loop
|
|
|
|
// =======================
|
|
|
|
|
|
|
|
// We have to wait for a response from either SendCreateWindow or
|
|
|
|
// SendBrowserFrameOpenWindow with information we're going to need to return
|
|
|
|
// from this function, So we spin a nested event loop until they get back to
|
|
|
|
// us.
|
|
|
|
|
|
|
|
// Prevent the docshell from becoming active while the nested event loop is
|
|
|
|
// spinning.
|
|
|
|
newChild->AddPendingDocShellBlocker();
|
|
|
|
auto removePendingDocShellBlocker = MakeScopeExit([&] {
|
|
|
|
if (newChild) {
|
|
|
|
newChild->RemovePendingDocShellBlocker();
|
2015-10-30 02:30:57 +03:00
|
|
|
}
|
2017-06-15 20:28:11 +03:00
|
|
|
});
|
2017-06-15 20:28:11 +03:00
|
|
|
|
2017-06-15 20:28:11 +03:00
|
|
|
// Suspend our window if we have one to make sure we don't re-enter it.
|
|
|
|
if (parentTopInnerWindow) {
|
|
|
|
parentTopInnerWindow->Suspend();
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
AutoNoJSAPI nojsapi;
|
|
|
|
|
|
|
|
// Spin the event loop until we get a response. Callers of this function
|
|
|
|
// already have to guard against an inner event loop spinning in the
|
|
|
|
// non-e10s case because of the need to spin one to create a new chrome
|
|
|
|
// window.
|
|
|
|
SpinEventLoopUntil([&]() { return ready; });
|
|
|
|
MOZ_RELEASE_ASSERT(ready,
|
|
|
|
"We are on the main thread, so we should not exit this "
|
|
|
|
"loop without ready being true.");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parentTopInnerWindow) {
|
|
|
|
parentTopInnerWindow->Resume();
|
|
|
|
}
|
|
|
|
|
|
|
|
// =====================
|
|
|
|
// End Nested Event Loop
|
|
|
|
// =====================
|
|
|
|
|
2019-09-18 01:19:50 +03:00
|
|
|
// It's possible for our new BrowsingContext to become discarded during the
|
|
|
|
// nested event loop, in which case we shouldn't return it, since our callers
|
|
|
|
// will generally not be prepared to deal with that.
|
|
|
|
if (*aReturn && (*aReturn)->IsDiscarded()) {
|
|
|
|
NS_RELEASE(*aReturn);
|
|
|
|
return NS_ERROR_ABORT;
|
|
|
|
}
|
|
|
|
|
Bug 1416728 - Process the CreateWindow reply message in order with other PContent IPC messages, r=bz
Previously we used the MozPromise interface for calling an async-message over
IPC with a reply. Unfortunately, MozPromise processes the reply asynchronously,
potentially allowing other IPC messages to be processed before the `->Then`
callback is processed.
In the original CreateWindow patch I tried to work around this by setting the
target of the `->Then` callback to be StableStateEventTarget. This worked,
however as it isn't safe to run scripts etc. in the stable state, we instead
tried to exit the nested event loop immediately after the runnable ran, and then
performed processing of the reply.
Unfortunately, this bug exposed a problem with that design. If we have multiple
nested event loops then we cannot guarantee that we'll exit the nested event
loop immediately after recieving the `->Then` callback, which meant that we
could still process other IPC messages before we processed the CreateWindow
reply.
The fix to this was to add a new API to allow passing callbacks directly into
IPC send methods, ensure that those callbacks are called in IPC order, and
fully process the CreateWindow reply in the callback, rather than waiting for
the nested event loop to exit.
MozReview-Commit-ID: D6zaMJRxhXd
2017-11-16 23:59:52 +03:00
|
|
|
// We should have the results already set by the callbacks.
|
|
|
|
MOZ_ASSERT_IF(NS_SUCCEEDED(rv), *aReturn);
|
|
|
|
return rv;
|
2015-10-30 02:30:57 +03:00
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
void ContentChild::GetProcessName(nsAString& aName) const {
|
|
|
|
aName.Assign(mProcessName);
|
2012-10-06 01:54:54 +04:00
|
|
|
}
|
|
|
|
|
2019-01-12 07:51:20 +03:00
|
|
|
void ContentChild::LaunchRDDProcess() {
|
|
|
|
SynchronousTask task("LaunchRDDProcess");
|
|
|
|
SystemGroup::Dispatch(
|
|
|
|
TaskCategory::Other,
|
|
|
|
NS_NewRunnableFunction("LaunchRDDProcess", [&task, this] {
|
|
|
|
AutoCompleteTask complete(&task);
|
|
|
|
nsresult rv;
|
|
|
|
Endpoint<PRemoteDecoderManagerChild> endpoint;
|
|
|
|
Unused << SendLaunchRDDProcess(&rv, &endpoint);
|
2019-04-03 06:12:35 +03:00
|
|
|
if (rv == NS_OK) {
|
2019-06-11 05:01:34 +03:00
|
|
|
RemoteDecoderManagerChild::InitForRDDProcess(std::move(endpoint));
|
2019-01-12 07:51:20 +03:00
|
|
|
}
|
|
|
|
}));
|
|
|
|
task.Wait();
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
bool ContentChild::IsAlive() const { return mIsAlive; }
|
2014-10-14 01:28:00 +04:00
|
|
|
|
2016-09-03 02:23:00 +03:00
|
|
|
bool ContentChild::IsShuttingDown() const { return mShuttingDown; }
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
void ContentChild::GetProcessName(nsACString& aName) const {
|
|
|
|
aName.Assign(NS_ConvertUTF16toUTF8(mProcessName));
|
2013-10-25 07:47:48 +04:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:05:29 +03:00
|
|
|
/* static */
|
|
|
|
void ContentChild::AppendProcessId(nsACString& aName) {
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!aName.IsEmpty()) {
|
|
|
|
aName.Append(' ');
|
|
|
|
}
|
|
|
|
unsigned pid = getpid();
|
|
|
|
aName.Append(nsPrintfCString("(pid %u)", pid));
|
2013-10-25 07:47:48 +04:00
|
|
|
}
|
|
|
|
|
2017-06-22 20:45:48 +03:00
|
|
|
void ContentChild::InitGraphicsDeviceData(const ContentDeviceData& aData) {
|
|
|
|
gfxPlatform::InitChild(aData);
|
2015-08-02 23:59:33 +03:00
|
|
|
}
|
|
|
|
|
2019-03-30 03:23:49 +03:00
|
|
|
void ContentChild::InitSharedUASheets(const Maybe<SharedMemoryHandle>& aHandle,
|
|
|
|
uintptr_t aAddress) {
|
|
|
|
MOZ_ASSERT_IF(!aHandle, !aAddress);
|
|
|
|
|
|
|
|
if (!aAddress) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Map the shared memory storing the user agent style sheets. Do this as
|
|
|
|
// early as possible to maximize the chance of being able to map at the
|
|
|
|
// address we want.
|
|
|
|
nsLayoutStylesheetCache::SetSharedMemory(*aHandle, aAddress);
|
|
|
|
}
|
|
|
|
|
2017-02-05 08:52:38 +03:00
|
|
|
void ContentChild::InitXPCOM(
|
|
|
|
const XPCOMInitData& aXPCOMInit,
|
|
|
|
const mozilla::dom::ipc::StructuredCloneData& aInitialData) {
|
2016-01-05 12:59:30 +03:00
|
|
|
// Do this as early as possible to get the parent process to initialize the
|
|
|
|
// background thread since we'll likely need database information very soon.
|
|
|
|
BackgroundChild::Startup();
|
2013-11-27 11:59:41 +04:00
|
|
|
|
2017-10-24 13:02:41 +03:00
|
|
|
PBackgroundChild* actorChild = BackgroundChild::GetOrCreateForCurrentThread();
|
|
|
|
if (NS_WARN_IF(!actorChild)) {
|
2017-10-25 09:45:53 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("PBackground init can't fail at this point");
|
|
|
|
return;
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2013-11-27 11:59:41 +04:00
|
|
|
|
2019-03-11 17:35:04 +03:00
|
|
|
LSObject::Initialize();
|
|
|
|
|
2017-11-09 08:19:59 +03:00
|
|
|
ClientManager::Startup();
|
|
|
|
|
2018-11-20 02:18:32 +03:00
|
|
|
RemoteWorkerService::Initialize();
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
|
|
|
if (!svc) {
|
|
|
|
NS_WARNING("Couldn't acquire console service");
|
|
|
|
return;
|
|
|
|
}
|
2010-09-24 05:39:32 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
mConsoleListener = new ConsoleListener(this);
|
|
|
|
if (NS_FAILED(svc->RegisterListener(mConsoleListener)))
|
|
|
|
NS_WARNING("Couldn't register console listener for child process");
|
|
|
|
|
2017-02-05 08:52:38 +03:00
|
|
|
mAvailableDictionaries = aXPCOMInit.dictionaries();
|
|
|
|
|
|
|
|
RecvSetOffline(aXPCOMInit.isOffline());
|
|
|
|
RecvSetConnectivity(aXPCOMInit.isConnected());
|
Bug 1348042 - Refactor LocaleService to operate in server-client mode. r=Ehsan,qdot
LocaleService serves two main functions. It is a central place for all code in the
engine to learn about locales, but it also does the language negotiation and selection.
The former is relevant in all processes, but the latter should only be performed
by the "main" process. In case of current Desktop Firefox, the parent process
is the one performing all the language negotiation, and content processes should
operate in the "client" mode.
In Fennec, there's a Java app on top of Gecko which should work as a "server"
and then all processes, including parent process of Gecko is merely a "client" for that.
This refactor finalizes this duality making it easily configurable to define in
which mode a given LocaleService operates.
The server-client model allows all clients to stay in sync with the server,
but operate transparently for all callers just returning the right values.
In order to initialize LocaleService in the client mode in child process with the
right locales I'm adding the list of app locales to the XPCOMInitData,
and then fire LocaleService::SetAppLocales in the child process initialization.
In order to keep the list up to date, I'm adding intl:app-locales-changed to
the list of observed topics, and when triggered, I send the updated list
to the child process, which updates LocaleService::SetAppLocales with the new
list.
MozReview-Commit-ID: K9X6berF3IO
--HG--
extra : rebase_source : ca5e502d064023fddfd63fe6fe5eccefce8dee52
2017-03-26 08:09:45 +03:00
|
|
|
LocaleService::GetInstance()->AssignAppLocales(aXPCOMInit.appLocales());
|
|
|
|
LocaleService::GetInstance()->AssignRequestedLocales(
|
|
|
|
aXPCOMInit.requestedLocales());
|
|
|
|
|
2017-02-05 08:52:38 +03:00
|
|
|
RecvSetCaptivePortalState(aXPCOMInit.captivePortalState());
|
|
|
|
RecvBidiKeyboardNotify(aXPCOMInit.isLangRTL(),
|
|
|
|
aXPCOMInit.haveBidiKeyboards());
|
2016-01-05 12:59:30 +03:00
|
|
|
|
2018-07-23 17:51:09 +03:00
|
|
|
// Create the CPOW manager as soon as possible. Middleman processes don't use
|
|
|
|
// CPOWs, because their recording child will also have a CPOW manager that
|
|
|
|
// communicates with the UI process.
|
|
|
|
if (!recordreplay::IsMiddleman()) {
|
|
|
|
SendPJavaScriptConstructor();
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
|
2017-02-05 08:52:38 +03:00
|
|
|
if (aXPCOMInit.domainPolicy().active()) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
|
|
|
MOZ_ASSERT(ssm);
|
|
|
|
ssm->ActivateDomainPolicyInternal(getter_AddRefs(mPolicy));
|
|
|
|
if (!mPolicy) {
|
|
|
|
MOZ_CRASH("Failed to activate domain policy.");
|
|
|
|
}
|
2017-02-05 08:52:38 +03:00
|
|
|
mPolicy->ApplyClone(&aXPCOMInit.domainPolicy());
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-03-24 17:29:16 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIClipboard> clipboard(
|
|
|
|
do_GetService("@mozilla.org/widget/clipboard;1"));
|
|
|
|
if (nsCOMPtr<nsIClipboardProxy> clipboardProxy =
|
|
|
|
do_QueryInterface(clipboard)) {
|
2017-02-05 08:52:38 +03:00
|
|
|
clipboardProxy->SetCapabilities(aXPCOMInit.clipboardCaps());
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-10-22 13:50:00 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
{
|
|
|
|
AutoJSAPI jsapi;
|
|
|
|
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
|
|
|
|
MOZ_CRASH();
|
2015-05-01 04:20:51 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
ErrorResult rv;
|
|
|
|
JS::RootedValue data(jsapi.cx());
|
2017-02-05 08:52:38 +03:00
|
|
|
mozilla::dom::ipc::StructuredCloneData id;
|
|
|
|
id.Copy(aInitialData);
|
|
|
|
id.Read(jsapi.cx(), &data, rv);
|
2016-01-05 12:59:30 +03:00
|
|
|
if (NS_WARN_IF(rv.Failed())) {
|
|
|
|
MOZ_CRASH();
|
|
|
|
}
|
2018-08-03 01:03:50 +03:00
|
|
|
auto* global = ContentProcessMessageManager::Get();
|
2016-01-05 12:59:30 +03:00
|
|
|
global->SetInitialProcessData(data);
|
|
|
|
}
|
2015-05-01 04:20:51 +03:00
|
|
|
|
2016-07-21 13:57:35 +03:00
|
|
|
// The stylesheet cache is not ready yet. Store this URL for future use.
|
2017-02-05 08:52:38 +03:00
|
|
|
nsCOMPtr<nsIURI> ucsURL = DeserializeURI(aXPCOMInit.userContentSheetURL());
|
2016-07-21 13:57:35 +03:00
|
|
|
nsLayoutStylesheetCache::SetUserContentCSSURL(ucsURL);
|
|
|
|
|
2017-02-11 02:46:59 +03:00
|
|
|
GfxInfoBase::SetFeatureStatus(aXPCOMInit.gfxFeatureStatus());
|
2017-02-25 19:14:04 +03:00
|
|
|
|
|
|
|
DataStorage::SetCachedStorageEntries(aXPCOMInit.dataStorage());
|
2017-08-29 14:05:40 +03:00
|
|
|
|
|
|
|
// Set the dynamic scalar definitions for this process.
|
|
|
|
TelemetryIPC::AddDynamicScalarDefinitions(aXPCOMInit.dynamicScalarDefs());
|
2010-09-24 05:39:32 +04:00
|
|
|
}
|
|
|
|
|
2017-01-27 03:35:54 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRequestMemoryReport(
|
|
|
|
const uint32_t& aGeneration, const bool& aAnonymize,
|
2019-03-01 00:20:40 +03:00
|
|
|
const bool& aMinimizeMemoryUsage,
|
|
|
|
const Maybe<mozilla::ipc::FileDescriptor>& aDMDFile) {
|
2017-01-27 03:35:53 +03:00
|
|
|
nsCString process;
|
|
|
|
GetProcessName(process);
|
|
|
|
AppendProcessId(process);
|
|
|
|
|
2019-01-02 16:05:23 +03:00
|
|
|
MemoryReportRequestClient::Start(
|
|
|
|
aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile, process,
|
|
|
|
[&](const MemoryReport& aReport) {
|
|
|
|
Unused << GetSingleton()->SendAddMemoryReport(aReport);
|
|
|
|
},
|
|
|
|
[&](const uint32_t& aGeneration) {
|
|
|
|
return GetSingleton()->SendFinishMemoryReport(aGeneration);
|
|
|
|
});
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-03-05 06:27:13 +04:00
|
|
|
}
|
|
|
|
|
2014-05-13 21:13:00 +04:00
|
|
|
PCycleCollectWithLogsChild* ContentChild::AllocPCycleCollectWithLogsChild(
|
|
|
|
const bool& aDumpAllTraces, const FileDescriptor& aGCLog,
|
|
|
|
const FileDescriptor& aCCLog) {
|
2018-11-24 01:07:41 +03:00
|
|
|
return do_AddRef(new CycleCollectWithLogsChild()).take();
|
2014-05-13 21:13:00 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvPCycleCollectWithLogsConstructor(
|
|
|
|
PCycleCollectWithLogsChild* aActor, const bool& aDumpAllTraces,
|
|
|
|
const FileDescriptor& aGCLog, const FileDescriptor& aCCLog) {
|
2018-11-24 01:07:41 +03:00
|
|
|
// The sink's destructor is called when the last reference goes away, which
|
|
|
|
// will cause the actor to be closed down.
|
|
|
|
auto* actor = static_cast<CycleCollectWithLogsChild*>(aActor);
|
|
|
|
RefPtr<CycleCollectWithLogsChild::Sink> sink =
|
|
|
|
new CycleCollectWithLogsChild::Sink(actor, aGCLog, aCCLog);
|
2018-11-28 03:57:32 +03:00
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
// Invoke the dumper, which will take a reference to the sink.
|
|
|
|
nsCOMPtr<nsIMemoryInfoDumper> dumper =
|
|
|
|
do_GetService("@mozilla.org/memory-info-dumper;1");
|
2016-01-05 12:59:30 +03:00
|
|
|
dumper->DumpGCAndCCLogsToSink(aDumpAllTraces, sink);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-05-13 21:13:00 +04:00
|
|
|
}
|
|
|
|
|
2018-11-24 01:07:41 +03:00
|
|
|
bool ContentChild::DeallocPCycleCollectWithLogsChild(
|
|
|
|
PCycleCollectWithLogsChild* aActor) {
|
|
|
|
RefPtr<CycleCollectWithLogsChild> actor =
|
|
|
|
dont_AddRef(static_cast<CycleCollectWithLogsChild*>(aActor));
|
2016-01-05 12:59:30 +03:00
|
|
|
return true;
|
2012-10-16 06:12:14 +04:00
|
|
|
}
|
|
|
|
|
2017-01-05 23:55:57 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvInitGMPService(
|
|
|
|
Endpoint<PGMPServiceChild>&& aGMPService) {
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!GMPServiceChild::Create(std::move(aGMPService))) {
|
2017-01-05 23:55:57 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
2015-02-10 13:49:03 +03:00
|
|
|
}
|
|
|
|
|
2017-05-30 22:06:14 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvInitProfiler(
|
|
|
|
Endpoint<PProfilerChild>&& aEndpoint) {
|
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
2018-05-30 22:15:35 +03:00
|
|
|
mProfilerController = ChildProfilerController::Create(std::move(aEndpoint));
|
2017-05-30 22:06:14 +03:00
|
|
|
#endif
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-11-01 06:25:19 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvGMPsChanged(
|
|
|
|
nsTArray<GMPCapabilityData>&& capabilities) {
|
2018-05-30 22:15:35 +03:00
|
|
|
GeckoMediaPluginServiceChild::UpdateGMPCapabilities(std::move(capabilities));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-11-01 06:25:19 +03:00
|
|
|
}
|
|
|
|
|
2017-01-05 23:54:52 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvInitProcessHangMonitor(
|
|
|
|
Endpoint<PProcessHangMonitorChild>&& aHangMonitor) {
|
2018-05-30 22:15:35 +03:00
|
|
|
CreateHangMonitorChild(std::move(aHangMonitor));
|
2017-01-05 23:54:52 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-02-15 02:07:53 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::GetResultForRenderingInitFailure(
|
|
|
|
base::ProcessId aOtherPid) {
|
|
|
|
if (aOtherPid == base::GetCurrentProcId() || aOtherPid == OtherPid()) {
|
|
|
|
// If we are talking to ourselves, or the UI process, then that is a fatal
|
|
|
|
// protocol error.
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we are talking to the GPU process, then we should recover from this on
|
|
|
|
// the next ContentChild::RecvReinitRendering call.
|
|
|
|
gfxCriticalNote << "Could not initialize rendering with GPU process";
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-07-05 17:32:03 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRequestPerformanceMetrics(
|
|
|
|
const nsID& aID) {
|
2018-11-20 01:51:12 +03:00
|
|
|
RefPtr<ContentChild> self = this;
|
|
|
|
RefPtr<AbstractThread> mainThread =
|
|
|
|
SystemGroup::AbstractMainThreadFor(TaskCategory::Performance);
|
|
|
|
nsTArray<RefPtr<PerformanceInfoPromise>> promises = CollectPerformanceInfo();
|
|
|
|
|
|
|
|
PerformanceInfoPromise::All(mainThread, promises)
|
|
|
|
->Then(
|
|
|
|
mainThread, __func__,
|
|
|
|
[self, aID](const nsTArray<mozilla::dom::PerformanceInfo>& aResult) {
|
|
|
|
self->SendAddPerformanceMetrics(aID, aResult);
|
|
|
|
},
|
|
|
|
[]() { /* silently fails -- the parent times out
|
|
|
|
and proceeds when the data is not coming back */
|
|
|
|
});
|
|
|
|
|
2018-03-20 22:07:41 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-03-29 16:47:44 +03:00
|
|
|
#if defined(XP_MACOSX)
|
|
|
|
extern "C" {
|
|
|
|
void CGSShutdownServerConnections();
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2017-06-14 18:39:59 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvInitRendering(
|
|
|
|
Endpoint<PCompositorManagerChild>&& aCompositor,
|
2016-09-20 11:15:49 +03:00
|
|
|
Endpoint<PImageBridgeChild>&& aImageBridge,
|
2016-11-08 05:21:35 +03:00
|
|
|
Endpoint<PVRManagerChild>&& aVRBridge,
|
2019-06-11 05:01:34 +03:00
|
|
|
Endpoint<PRemoteDecoderManagerChild>&& aVideoManager,
|
2017-04-14 11:06:09 +03:00
|
|
|
nsTArray<uint32_t>&& namespaces) {
|
2017-06-14 18:39:59 +03:00
|
|
|
MOZ_ASSERT(namespaces.Length() == 3);
|
2017-04-14 11:06:09 +03:00
|
|
|
|
2018-02-15 02:07:53 +03:00
|
|
|
// Note that for all of the methods below, if it can fail, it should only
|
|
|
|
// return false if the failure is an IPDL error. In such situations,
|
|
|
|
// ContentChild can reason about whether or not to wait for
|
|
|
|
// RecvReinitRendering (because we surmised the GPU process crashed), or if it
|
|
|
|
// should crash itself (because we are actually talking to the UI process). If
|
|
|
|
// there are localized failures (e.g. failed to spawn a thread), then it
|
|
|
|
// should MOZ_RELEASE_ASSERT or MOZ_CRASH as necessary instead.
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!CompositorManagerChild::Init(std::move(aCompositor), namespaces[0])) {
|
2018-02-15 02:07:53 +03:00
|
|
|
return GetResultForRenderingInitFailure(aCompositor.OtherPid());
|
2016-09-20 11:15:49 +03:00
|
|
|
}
|
2017-06-14 18:39:59 +03:00
|
|
|
if (!CompositorManagerChild::CreateContentCompositorBridge(namespaces[1])) {
|
2018-02-15 02:07:53 +03:00
|
|
|
return GetResultForRenderingInitFailure(aCompositor.OtherPid());
|
2017-06-14 18:39:59 +03:00
|
|
|
}
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!ImageBridgeChild::InitForContent(std::move(aImageBridge),
|
|
|
|
namespaces[2])) {
|
2018-02-15 02:07:53 +03:00
|
|
|
return GetResultForRenderingInitFailure(aImageBridge.OtherPid());
|
2016-09-20 11:15:49 +03:00
|
|
|
}
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!gfx::VRManagerChild::InitForContent(std::move(aVRBridge))) {
|
2018-02-15 02:07:53 +03:00
|
|
|
return GetResultForRenderingInitFailure(aVRBridge.OtherPid());
|
2016-09-20 11:15:49 +03:00
|
|
|
}
|
2019-06-11 05:01:34 +03:00
|
|
|
RemoteDecoderManagerChild::InitForGPUProcess(std::move(aVideoManager));
|
2019-03-29 16:47:44 +03:00
|
|
|
|
|
|
|
#if defined(XP_MACOSX) && !defined(MOZ_SANDBOX)
|
|
|
|
// Close all current connections to the WindowServer. This ensures that the
|
|
|
|
// Activity Monitor will not label the content process as "Not responding"
|
|
|
|
// because it's not running a native event loop. See bug 1384336. When the
|
|
|
|
// build is configured with sandbox support, this is called during sandbox
|
|
|
|
// setup.
|
|
|
|
CGSShutdownServerConnections();
|
|
|
|
#endif
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-21 10:14:59 +03:00
|
|
|
}
|
|
|
|
|
2017-06-14 18:39:59 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvReinitRendering(
|
|
|
|
Endpoint<PCompositorManagerChild>&& aCompositor,
|
2016-09-20 11:18:50 +03:00
|
|
|
Endpoint<PImageBridgeChild>&& aImageBridge,
|
2016-11-08 05:21:35 +03:00
|
|
|
Endpoint<PVRManagerChild>&& aVRBridge,
|
2019-06-11 05:01:34 +03:00
|
|
|
Endpoint<PRemoteDecoderManagerChild>&& aVideoManager,
|
2017-04-14 11:06:09 +03:00
|
|
|
nsTArray<uint32_t>&& namespaces) {
|
2017-06-14 18:39:59 +03:00
|
|
|
MOZ_ASSERT(namespaces.Length() == 3);
|
2019-04-10 01:39:01 +03:00
|
|
|
nsTArray<RefPtr<BrowserChild>> tabs = BrowserChild::GetAll();
|
2016-09-20 11:19:32 +03:00
|
|
|
|
|
|
|
// Zap all the old layer managers we have lying around.
|
2019-04-10 01:39:01 +03:00
|
|
|
for (const auto& browserChild : tabs) {
|
|
|
|
if (browserChild->GetLayersId().IsValid()) {
|
|
|
|
browserChild->InvalidateLayers();
|
2016-09-20 11:19:32 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Re-establish singleton bridges to the compositor.
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!CompositorManagerChild::Init(std::move(aCompositor), namespaces[0])) {
|
2018-02-15 02:07:53 +03:00
|
|
|
return GetResultForRenderingInitFailure(aCompositor.OtherPid());
|
2017-06-14 18:39:59 +03:00
|
|
|
}
|
|
|
|
if (!CompositorManagerChild::CreateContentCompositorBridge(namespaces[1])) {
|
2018-02-15 02:07:53 +03:00
|
|
|
return GetResultForRenderingInitFailure(aCompositor.OtherPid());
|
2016-09-20 11:18:50 +03:00
|
|
|
}
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!ImageBridgeChild::ReinitForContent(std::move(aImageBridge),
|
|
|
|
namespaces[2])) {
|
2018-02-15 02:07:53 +03:00
|
|
|
return GetResultForRenderingInitFailure(aImageBridge.OtherPid());
|
2016-09-20 11:18:50 +03:00
|
|
|
}
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!gfx::VRManagerChild::ReinitForContent(std::move(aVRBridge))) {
|
2018-02-15 02:07:53 +03:00
|
|
|
return GetResultForRenderingInitFailure(aVRBridge.OtherPid());
|
2016-09-20 11:18:50 +03:00
|
|
|
}
|
2017-06-28 19:27:03 +03:00
|
|
|
gfxPlatform::GetPlatform()->CompositorUpdated();
|
2016-09-20 11:19:32 +03:00
|
|
|
|
|
|
|
// Establish new PLayerTransactions.
|
2019-04-10 01:39:01 +03:00
|
|
|
for (const auto& browserChild : tabs) {
|
|
|
|
if (browserChild->GetLayersId().IsValid()) {
|
|
|
|
browserChild->ReinitRendering();
|
2016-09-20 11:19:32 +03:00
|
|
|
}
|
|
|
|
}
|
2016-11-08 05:21:35 +03:00
|
|
|
|
2019-06-11 05:01:34 +03:00
|
|
|
RemoteDecoderManagerChild::InitForGPUProcess(std::move(aVideoManager));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-09-20 11:18:50 +03:00
|
|
|
}
|
|
|
|
|
2017-07-18 05:42:59 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvAudioDefaultDeviceChange() {
|
2017-07-25 07:34:14 +03:00
|
|
|
#ifdef XP_WIN
|
|
|
|
audio::AudioNotificationReceiver::NotifyDefaultDeviceChanged();
|
|
|
|
#endif
|
2017-07-18 05:42:59 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-05-12 08:44:27 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvReinitRenderingForDeviceReset() {
|
|
|
|
gfxPlatform::GetPlatform()->CompositorUpdated();
|
|
|
|
|
2019-04-10 01:39:01 +03:00
|
|
|
nsTArray<RefPtr<BrowserChild>> tabs = BrowserChild::GetAll();
|
|
|
|
for (const auto& browserChild : tabs) {
|
|
|
|
if (browserChild->GetLayersId().IsValid()) {
|
|
|
|
browserChild->ReinitRenderingForDeviceReset();
|
2017-05-12 08:44:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-03-19 01:31:59 +03:00
|
|
|
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
|
2017-07-22 02:16:59 +03:00
|
|
|
extern "C" {
|
2018-08-02 18:18:51 +03:00
|
|
|
CGError CGSSetDenyWindowServerConnections(bool);
|
2017-07-22 02:16:59 +03:00
|
|
|
};
|
|
|
|
|
2014-11-10 19:59:43 +03:00
|
|
|
static bool StartMacOSContentSandbox() {
|
2018-08-13 17:43:45 +03:00
|
|
|
// Close all current connections to the WindowServer. This ensures that the
|
|
|
|
// Activity Monitor will not label the content process as "Not responding"
|
|
|
|
// because it's not running a native event loop. See bug 1384336.
|
2019-03-29 16:47:44 +03:00
|
|
|
// This is required with or without the sandbox enabled. Until the
|
|
|
|
// window server is blocked as the policy level, this should be called
|
|
|
|
// just before CGSSetDenyWindowServerConnections() so there are no
|
|
|
|
// windowserver connections active when CGSSetDenyWindowServerConnections()
|
|
|
|
// is called.
|
2018-08-27 20:41:41 +03:00
|
|
|
CGSShutdownServerConnections();
|
|
|
|
|
2019-03-29 16:47:44 +03:00
|
|
|
int sandboxLevel = GetEffectiveContentSandboxLevel();
|
|
|
|
if (sandboxLevel < 1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-13 17:43:45 +03:00
|
|
|
// Actual security benefits are only acheived when we additionally deny
|
|
|
|
// future connections, however this currently breaks WebGL so it's not done
|
|
|
|
// by default.
|
2018-08-02 18:18:51 +03:00
|
|
|
if (Preferences::GetBool(
|
|
|
|
"security.sandbox.content.mac.disconnect-windowserver")) {
|
|
|
|
CGError result = CGSSetDenyWindowServerConnections(true);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(result == kCGErrorSuccess);
|
2018-08-09 21:58:11 +03:00
|
|
|
# if !MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
|
|
|
Unused << result;
|
|
|
|
# endif
|
2017-07-22 02:16:59 +03:00
|
|
|
}
|
|
|
|
|
2018-10-26 16:03:55 +03:00
|
|
|
// If the sandbox is already enabled, there's nothing more to do here.
|
|
|
|
if (Preferences::GetBool("security.sandbox.content.mac.earlyinit") &&
|
|
|
|
!recordreplay::IsRecordingOrReplaying()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-10-19 21:23:06 +03:00
|
|
|
nsAutoCString appPath;
|
|
|
|
if (!nsMacUtilsImpl::GetAppPath(appPath)) {
|
|
|
|
MOZ_CRASH("Error resolving child process app path");
|
2014-11-10 19:59:43 +03:00
|
|
|
}
|
|
|
|
|
2017-01-25 02:20:08 +03:00
|
|
|
ContentChild* cc = ContentChild::GetSingleton();
|
|
|
|
|
2017-10-02 17:48:01 +03:00
|
|
|
nsresult rv;
|
2016-08-30 23:32:21 +03:00
|
|
|
nsCOMPtr<nsIFile> profileDir;
|
2017-01-25 02:20:08 +03:00
|
|
|
cc->GetProfileDir(getter_AddRefs(profileDir));
|
2016-08-30 23:32:21 +03:00
|
|
|
nsCString profileDirPath;
|
|
|
|
if (profileDir) {
|
2017-01-25 07:06:35 +03:00
|
|
|
profileDir->Normalize();
|
2016-08-30 23:32:21 +03:00
|
|
|
rv = profileDir->GetNativePath(profileDirPath);
|
|
|
|
if (NS_FAILED(rv) || profileDirPath.IsEmpty()) {
|
|
|
|
MOZ_CRASH("Failed to get profile path");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-25 02:20:08 +03:00
|
|
|
bool isFileProcess = cc->GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE);
|
|
|
|
|
2014-11-10 19:59:43 +03:00
|
|
|
MacSandboxInfo info;
|
|
|
|
info.type = MacSandboxType_Content;
|
2017-01-25 02:20:08 +03:00
|
|
|
info.level = sandboxLevel;
|
|
|
|
info.hasFilePrivileges = isFileProcess;
|
2017-01-23 23:46:49 +03:00
|
|
|
info.shouldLog = Preferences::GetBool("security.sandbox.logging.enabled") ||
|
|
|
|
PR_GetEnv("MOZ_SANDBOX_LOGGING");
|
2015-04-03 19:51:41 +03:00
|
|
|
info.appPath.assign(appPath.get());
|
2019-10-30 02:33:45 +03:00
|
|
|
info.hasAudio = !StaticPrefs::media_cubeb_sandbox();
|
2018-10-18 23:49:51 +03:00
|
|
|
info.hasWindowServer = !Preferences::GetBool(
|
|
|
|
"security.sandbox.content.mac.disconnect-windowserver");
|
2014-11-10 19:59:43 +03:00
|
|
|
|
2018-10-31 20:56:43 +03:00
|
|
|
// These paths are used to allowlist certain directories used by the testing
|
2017-06-21 17:19:28 +03:00
|
|
|
// system. They should not be considered a public API, and are only intended
|
|
|
|
// for use in automation.
|
2017-07-31 07:28:48 +03:00
|
|
|
nsAutoCString testingReadPath1;
|
|
|
|
Preferences::GetCString("security.sandbox.content.mac.testing_read_path1",
|
|
|
|
testingReadPath1);
|
2017-06-21 17:19:28 +03:00
|
|
|
if (!testingReadPath1.IsEmpty()) {
|
|
|
|
info.testingReadPath1.assign(testingReadPath1.get());
|
|
|
|
}
|
2017-07-31 07:28:48 +03:00
|
|
|
nsAutoCString testingReadPath2;
|
|
|
|
Preferences::GetCString("security.sandbox.content.mac.testing_read_path2",
|
|
|
|
testingReadPath2);
|
2017-06-21 17:19:28 +03:00
|
|
|
if (!testingReadPath2.IsEmpty()) {
|
|
|
|
info.testingReadPath2.assign(testingReadPath2.get());
|
|
|
|
}
|
2017-07-15 02:32:53 +03:00
|
|
|
|
2017-07-19 19:16:09 +03:00
|
|
|
if (mozilla::IsDevelopmentBuild()) {
|
|
|
|
nsCOMPtr<nsIFile> repoDir;
|
2019-06-15 01:19:01 +03:00
|
|
|
rv = nsMacUtilsImpl::GetRepoDir(getter_AddRefs(repoDir));
|
2017-07-15 02:32:53 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
2017-07-19 19:16:09 +03:00
|
|
|
MOZ_CRASH("Failed to get path to repo dir");
|
2017-07-15 02:32:53 +03:00
|
|
|
}
|
2017-07-19 19:16:09 +03:00
|
|
|
nsCString repoDirPath;
|
|
|
|
Unused << repoDir->GetNativePath(repoDirPath);
|
2017-07-15 02:32:53 +03:00
|
|
|
info.testingReadPath3.assign(repoDirPath.get());
|
|
|
|
|
2017-07-19 19:16:09 +03:00
|
|
|
nsCOMPtr<nsIFile> objDir;
|
2019-06-15 01:19:01 +03:00
|
|
|
rv = nsMacUtilsImpl::GetObjDir(getter_AddRefs(objDir));
|
2017-07-15 02:32:53 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
2017-07-19 19:16:09 +03:00
|
|
|
MOZ_CRASH("Failed to get path to build object dir");
|
2017-07-15 02:32:53 +03:00
|
|
|
}
|
2017-07-19 19:16:09 +03:00
|
|
|
|
|
|
|
nsCString objDirPath;
|
|
|
|
Unused << objDir->GetNativePath(objDirPath);
|
2017-07-15 02:32:53 +03:00
|
|
|
info.testingReadPath4.assign(objDirPath.get());
|
2017-06-21 17:19:28 +03:00
|
|
|
}
|
|
|
|
|
2016-08-30 23:32:21 +03:00
|
|
|
if (profileDir) {
|
|
|
|
info.hasSandboxedProfile = true;
|
|
|
|
info.profileDir.assign(profileDirPath.get());
|
|
|
|
} else {
|
|
|
|
info.hasSandboxedProfile = false;
|
|
|
|
}
|
|
|
|
|
2017-05-02 18:07:10 +03:00
|
|
|
# ifdef DEBUG
|
2019-04-18 18:17:08 +03:00
|
|
|
// For bloat/leak logging or when a content process dies intentionally
|
|
|
|
// (|NoteIntentionalCrash|) for tests, it wants to log that it did this.
|
|
|
|
// Allow writing to this location.
|
|
|
|
nsAutoCString bloatLogDirPath;
|
|
|
|
if (NS_SUCCEEDED(nsMacUtilsImpl::GetBloatLogDir(bloatLogDirPath))) {
|
|
|
|
info.debugWriteDir = bloatLogDirPath.get();
|
2017-05-02 18:07:10 +03:00
|
|
|
}
|
|
|
|
# endif // DEBUG
|
|
|
|
|
2015-04-03 19:51:41 +03:00
|
|
|
std::string err;
|
2014-11-10 19:59:43 +03:00
|
|
|
if (!mozilla::StartMacSandbox(info, err)) {
|
2015-04-03 19:51:41 +03:00
|
|
|
NS_WARNING(err.c_str());
|
2014-11-10 19:59:43 +03:00
|
|
|
MOZ_CRASH("sandbox_init() failed");
|
|
|
|
}
|
2016-07-25 14:21:00 +03:00
|
|
|
|
|
|
|
return true;
|
2014-11-10 19:59:43 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-08 08:13:09 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSetProcessSandbox(
|
2019-03-01 00:20:40 +03:00
|
|
|
const Maybe<mozilla::ipc::FileDescriptor>& aBroker) {
|
2016-01-05 12:59:30 +03:00
|
|
|
// We may want to move the sandbox initialization somewhere else
|
|
|
|
// at some point; see bug 880808.
|
2019-03-19 01:31:59 +03:00
|
|
|
#if defined(MOZ_SANDBOX)
|
2016-07-25 14:21:00 +03:00
|
|
|
bool sandboxEnabled = true;
|
2014-03-13 02:48:15 +04:00
|
|
|
# if defined(XP_LINUX)
|
2018-01-24 08:35:44 +03:00
|
|
|
// On Linux, we have to support systems that can't use any sandboxing.
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!SandboxInfo::Get().CanSandboxContent()) {
|
2017-12-20 04:51:11 +03:00
|
|
|
sandboxEnabled = false;
|
2018-03-06 23:01:35 +03:00
|
|
|
} else {
|
|
|
|
// Pre-start audio before sandboxing; see bug 1443612.
|
2019-10-30 02:33:45 +03:00
|
|
|
if (StaticPrefs::media_cubeb_sandbox()) {
|
2019-10-11 19:04:32 +03:00
|
|
|
if (atp_set_real_time_limit(0, 48000)) {
|
|
|
|
NS_WARNING("could not set real-time limit at process startup");
|
|
|
|
}
|
2019-10-11 19:04:32 +03:00
|
|
|
InstallSoftRealTimeLimitHandler();
|
|
|
|
} else {
|
|
|
|
Unused << CubebUtils::GetCubebContext();
|
2018-03-06 23:01:35 +03:00
|
|
|
}
|
2016-07-25 14:21:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sandboxEnabled) {
|
2018-01-24 08:35:44 +03:00
|
|
|
sandboxEnabled = SetContentProcessSandbox(
|
|
|
|
ContentProcessSandboxParams::ForThisProcess(aBroker));
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-03-13 02:48:15 +04:00
|
|
|
# elif defined(XP_WIN)
|
2016-01-05 12:59:30 +03:00
|
|
|
mozilla::SandboxTarget::Instance()->StartSandbox();
|
2014-11-10 19:59:43 +03:00
|
|
|
# elif defined(XP_MACOSX)
|
2016-07-25 14:21:00 +03:00
|
|
|
sandboxEnabled = StartMacOSContentSandbox();
|
2013-08-12 23:58:35 +04:00
|
|
|
# endif
|
2016-07-25 14:21:00 +03:00
|
|
|
|
|
|
|
CrashReporter::AnnotateCrashReport(
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
CrashReporter::Annotation::ContentSandboxEnabled, sandboxEnabled);
|
2016-07-25 14:21:00 +03:00
|
|
|
# if defined(XP_LINUX) && !defined(OS_ANDROID)
|
2016-10-27 01:57:10 +03:00
|
|
|
CrashReporter::AnnotateCrashReport(
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
CrashReporter::Annotation::ContentSandboxCapabilities,
|
|
|
|
static_cast<int>(SandboxInfo::Get().AsInteger()));
|
2016-07-25 14:21:00 +03:00
|
|
|
# endif /* XP_LINUX && !OS_ANDROID */
|
2019-06-28 17:30:18 +03:00
|
|
|
// Use the prefix to avoid URIs from Fission isolated processes.
|
|
|
|
auto remoteTypePrefix = RemoteTypePrefix(GetRemoteType());
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RemoteType,
|
2019-06-28 17:30:18 +03:00
|
|
|
NS_ConvertUTF16toUTF8(remoteTypePrefix));
|
2019-03-19 01:31:59 +03:00
|
|
|
#endif /* MOZ_SANDBOX */
|
2016-07-25 14:21:00 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-01-18 00:06:36 +04:00
|
|
|
}
|
|
|
|
|
2016-06-03 12:56:04 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvBidiKeyboardNotify(
|
|
|
|
const bool& aIsLangRTL, const bool& aHaveBidiKeyboards) {
|
2016-01-05 12:59:30 +03:00
|
|
|
// bidi is always of type PuppetBidiKeyboard* (because in the child, the only
|
|
|
|
// possible implementation of nsIBidiKeyboard is PuppetBidiKeyboard).
|
|
|
|
PuppetBidiKeyboard* bidi =
|
|
|
|
static_cast<PuppetBidiKeyboard*>(nsContentUtils::GetBidiKeyboard());
|
|
|
|
if (bidi) {
|
2016-06-03 12:56:04 +03:00
|
|
|
bidi->SetBidiKeyboardInfo(aIsLangRTL, aHaveBidiKeyboards);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-04-11 01:18:05 +03:00
|
|
|
}
|
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
static StaticRefPtr<CancelableRunnable> gFirstIdleTask;
|
|
|
|
|
|
|
|
static void FirstIdle(void) {
|
|
|
|
MOZ_ASSERT(gFirstIdleTask);
|
|
|
|
gFirstIdleTask = nullptr;
|
2018-07-23 17:51:34 +03:00
|
|
|
|
|
|
|
// When recording or replaying, the middleman process will send this message
|
|
|
|
// instead.
|
|
|
|
if (!recordreplay::IsRecordingOrReplaying()) {
|
|
|
|
ContentChild::GetSingleton()->SendFirstIdle();
|
|
|
|
}
|
2017-02-01 15:34:24 +03:00
|
|
|
}
|
2012-10-09 08:46:19 +04:00
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
mozilla::jsipc::PJavaScriptChild* ContentChild::AllocPJavaScriptChild() {
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(ManagedPJavaScriptChild().IsEmpty());
|
2014-05-09 02:43:53 +04:00
|
|
|
|
2019-02-25 23:04:53 +03:00
|
|
|
return NewJavaScriptChild();
|
2013-07-03 11:24:32 +04:00
|
|
|
}
|
|
|
|
|
2014-06-11 09:44:06 +04:00
|
|
|
bool ContentChild::DeallocPJavaScriptChild(PJavaScriptChild* aChild) {
|
2019-02-25 23:04:53 +03:00
|
|
|
ReleaseJavaScriptChild(aChild);
|
|
|
|
return true;
|
2013-07-03 11:24:32 +04:00
|
|
|
}
|
|
|
|
|
2019-04-17 03:51:38 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvConstructBrowser(
|
2019-08-08 19:07:05 +03:00
|
|
|
ManagedEndpoint<PBrowserChild>&& aBrowserEp,
|
|
|
|
ManagedEndpoint<PWindowGlobalChild>&& aWindowEp, const TabId& aTabId,
|
2019-04-17 03:51:38 +03:00
|
|
|
const TabId& aSameTabGroupAs, const IPCTabContext& aContext,
|
2019-08-08 19:07:05 +03:00
|
|
|
const WindowGlobalInit& aWindowInit, const uint32_t& aChromeFlags,
|
2019-05-29 19:35:37 +03:00
|
|
|
const ContentParentId& aCpID, const bool& aIsForBrowser,
|
|
|
|
const bool& aIsTopLevel) {
|
2017-01-17 05:33:48 +03:00
|
|
|
MOZ_ASSERT(!IsShuttingDown());
|
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
static bool hasRunOnce = false;
|
|
|
|
if (!hasRunOnce) {
|
|
|
|
hasRunOnce = true;
|
|
|
|
MOZ_ASSERT(!gFirstIdleTask);
|
2017-10-27 23:39:28 +03:00
|
|
|
RefPtr<CancelableRunnable> firstIdleTask =
|
|
|
|
NewCancelableRunnableFunction("FirstIdleRunnable", FirstIdle);
|
2017-02-01 15:34:24 +03:00
|
|
|
gFirstIdleTask = firstIdleTask;
|
2019-01-26 20:18:05 +03:00
|
|
|
if (NS_FAILED(NS_DispatchToCurrentThreadQueue(firstIdleTask.forget(),
|
|
|
|
EventQueuePriority::Idle))) {
|
2018-01-05 01:59:14 +03:00
|
|
|
gFirstIdleTask = nullptr;
|
|
|
|
hasRunOnce = false;
|
|
|
|
}
|
2017-02-01 15:34:24 +03:00
|
|
|
}
|
|
|
|
|
2019-04-17 03:51:38 +03:00
|
|
|
// We'll happily accept any kind of IPCTabContext here; we don't need to
|
|
|
|
// check that it's of a certain type for security purposes, because we
|
|
|
|
// believe whatever the parent process tells us.
|
|
|
|
MaybeInvalidTabContext tc(aContext);
|
|
|
|
if (!tc.IsValid()) {
|
|
|
|
NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
|
|
|
|
"the parent process. (%s) Crashing...",
|
|
|
|
tc.GetInvalidReason())
|
|
|
|
.get());
|
|
|
|
MOZ_CRASH("Invalid TabContext received from the parent process.");
|
|
|
|
}
|
|
|
|
|
2019-08-08 19:07:05 +03:00
|
|
|
auto windowChild = MakeRefPtr<WindowGlobalChild>(aWindowInit, nullptr);
|
|
|
|
|
|
|
|
RefPtr<BrowserChild> browserChild = BrowserChild::Create(
|
|
|
|
this, aTabId, aSameTabGroupAs, tc.GetTabContext(),
|
|
|
|
aWindowInit.browsingContext(), aChromeFlags, aIsTopLevel);
|
2019-04-17 03:51:38 +03:00
|
|
|
|
2019-08-08 19:46:24 +03:00
|
|
|
// Bind the created BrowserChild to IPC to actually link the actor.
|
|
|
|
if (NS_WARN_IF(!BindPBrowserEndpoint(std::move(aBrowserEp), browserChild))) {
|
2019-04-17 03:51:38 +03:00
|
|
|
return IPC_FAIL(this, "BindPBrowserEndpoint failed");
|
|
|
|
}
|
|
|
|
|
2019-08-08 19:46:20 +03:00
|
|
|
if (NS_WARN_IF(!browserChild->BindPWindowGlobalEndpoint(std::move(aWindowEp),
|
|
|
|
windowChild))) {
|
2019-08-08 19:07:05 +03:00
|
|
|
return IPC_FAIL(this, "BindPWindowGlobalEndpoint failed");
|
|
|
|
}
|
|
|
|
windowChild->Init();
|
|
|
|
|
|
|
|
// Ensure that a TabGroup is set for our BrowserChild before running `Init`.
|
2019-04-10 01:39:01 +03:00
|
|
|
if (!browserChild->mTabGroup) {
|
|
|
|
browserChild->mTabGroup = TabGroup::GetFromActor(browserChild);
|
2019-04-05 22:38:27 +03:00
|
|
|
|
2019-04-10 01:39:01 +03:00
|
|
|
if (!browserChild->mTabGroup) {
|
|
|
|
browserChild->mTabGroup = new TabGroup();
|
2019-04-05 22:38:27 +03:00
|
|
|
MOZ_DIAGNOSTIC_ASSERT(aSameTabGroupAs != 0);
|
|
|
|
}
|
|
|
|
}
|
2019-02-25 23:04:53 +03:00
|
|
|
|
2019-08-08 19:07:05 +03:00
|
|
|
if (NS_WARN_IF(
|
|
|
|
NS_FAILED(browserChild->Init(/* aOpener */ nullptr, windowChild)))) {
|
2019-04-10 01:39:01 +03:00
|
|
|
return IPC_FAIL(browserChild, "BrowserChild::Init failed");
|
2019-02-25 23:04:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
|
|
|
if (os) {
|
2019-04-10 01:39:01 +03:00
|
|
|
os->NotifyObservers(static_cast<nsIBrowserChild*>(browserChild),
|
2019-02-25 23:04:53 +03:00
|
|
|
"tab-child-created", nullptr);
|
|
|
|
}
|
|
|
|
// Notify parent that we are ready to handle input events.
|
2019-04-10 01:39:01 +03:00
|
|
|
browserChild->SendRemoteIsReadyToHandleInputEvents();
|
2019-02-25 23:04:53 +03:00
|
|
|
return IPC_OK();
|
2009-08-12 20:18:08 +04:00
|
|
|
}
|
|
|
|
|
2019-07-10 06:27:27 +03:00
|
|
|
void ContentChild::GetAvailableDictionaries(nsTArray<nsString>& aDictionaries) {
|
2016-01-05 12:59:30 +03:00
|
|
|
aDictionaries = mAvailableDictionaries;
|
2014-10-03 18:52:37 +04:00
|
|
|
}
|
|
|
|
|
2016-09-21 13:27:26 +03:00
|
|
|
PFileDescriptorSetChild* ContentChild::SendPFileDescriptorSetConstructor(
|
|
|
|
const FileDescriptor& aFD) {
|
2017-01-17 05:33:48 +03:00
|
|
|
if (IsShuttingDown()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2016-09-21 13:27:26 +03:00
|
|
|
return PContentChild::SendPFileDescriptorSetConstructor(aFD);
|
|
|
|
}
|
|
|
|
|
2014-03-25 22:37:13 +04:00
|
|
|
PFileDescriptorSetChild* ContentChild::AllocPFileDescriptorSetChild(
|
|
|
|
const FileDescriptor& aFD) {
|
2019-02-25 23:04:49 +03:00
|
|
|
return new FileDescriptorSetChild(aFD);
|
2014-03-25 22:37:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPFileDescriptorSetChild(
|
|
|
|
PFileDescriptorSetChild* aActor) {
|
2019-02-25 23:04:49 +03:00
|
|
|
delete static_cast<FileDescriptorSetChild*>(aActor);
|
|
|
|
return true;
|
2014-03-25 22:37:13 +04:00
|
|
|
}
|
2013-02-23 08:24:28 +04:00
|
|
|
|
2019-08-08 19:46:46 +03:00
|
|
|
already_AddRefed<PIPCBlobInputStreamChild>
|
|
|
|
ContentChild::AllocPIPCBlobInputStreamChild(const nsID& aID,
|
|
|
|
const uint64_t& aSize) {
|
2019-02-25 23:04:53 +03:00
|
|
|
RefPtr<IPCBlobInputStreamChild> actor =
|
|
|
|
new IPCBlobInputStreamChild(aID, aSize);
|
2019-08-08 19:46:46 +03:00
|
|
|
return actor.forget();
|
Bug 1353629 - PBlob refactoring - part 4 - IPCBlobInputStream, r=smaug
IPCBlobInputStream is a new type of nsIInputStream that is used only in content
process when a Blob is sent from parent to child. This inputStream is for now,
just cloneable.
When the parent process sends a Blob to a content process, it has the Blob and
its inputStream. With its inputStream it creates a IPCBlobInputStreamParent
actor. This actor keeps the inputStream alive for following uses (not part of
this patch).
On the child side we will have, of course, a IPCBlobInputStreamChild actor.
This actor is able to create a IPCBlobInputStream when CreateStream() is
called. This means that 1 IPCBlobInputStreamChild can manage multiple
IPCBlobInputStreams each time one of them is cloned. When the last one of this
stream is released, the child actor sends a __delete__ request to the parent
side; the parent will be deleted, and the original inputStream, on the parent
side, will be released as well.
IPCBlobInputStream is a special inputStream because each method, except for
Available() fails. Basically, this inputStream cannot be used on the content
process for nothing else than knowing the size of the original stream.
In the following patches, I'll introduce an async way to use it.
2017-04-24 13:09:40 +03:00
|
|
|
}
|
|
|
|
|
2014-07-02 02:24:27 +04:00
|
|
|
mozilla::PRemoteSpellcheckEngineChild*
|
|
|
|
ContentChild::AllocPRemoteSpellcheckEngineChild() {
|
2016-01-08 23:40:26 +03:00
|
|
|
MOZ_CRASH(
|
|
|
|
"Default Constructor for PRemoteSpellcheckEngineChild should never be "
|
|
|
|
"called");
|
2016-01-05 12:59:30 +03:00
|
|
|
return nullptr;
|
2014-07-02 02:24:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPRemoteSpellcheckEngineChild(
|
|
|
|
PRemoteSpellcheckEngineChild* child) {
|
2016-01-05 12:59:30 +03:00
|
|
|
delete child;
|
|
|
|
return true;
|
2014-07-02 02:24:27 +04:00
|
|
|
}
|
|
|
|
|
2015-03-26 06:16:21 +03:00
|
|
|
PPresentationChild* ContentChild::AllocPPresentationChild() {
|
2016-01-08 23:40:26 +03:00
|
|
|
MOZ_CRASH("We should never be manually allocating PPresentationChild actors");
|
2016-01-05 12:59:30 +03:00
|
|
|
return nullptr;
|
2015-03-26 06:16:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPPresentationChild(PPresentationChild* aActor) {
|
2016-01-05 12:59:30 +03:00
|
|
|
delete aActor;
|
|
|
|
return true;
|
2015-03-26 06:16:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvNotifyPresentationReceiverLaunched(
|
|
|
|
PBrowserChild* aIframe, const nsString& aSessionId) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIDocShell> docShell =
|
2019-04-10 01:39:01 +03:00
|
|
|
do_GetInterface(static_cast<BrowserChild*>(aIframe)->WebNavigation());
|
2016-09-02 10:12:24 +03:00
|
|
|
NS_WARNING_ASSERTION(docShell, "WebNavigation failed");
|
2015-03-30 10:46:11 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
2016-09-02 10:12:24 +03:00
|
|
|
NS_WARNING_ASSERTION(service, "presentation service is missing");
|
2015-03-30 10:46:11 +03:00
|
|
|
|
2016-09-02 10:12:24 +03:00
|
|
|
Unused << NS_WARN_IF(
|
|
|
|
NS_FAILED(static_cast<PresentationIPCService*>(service.get())
|
|
|
|
->MonitorResponderLoading(aSessionId, docShell)));
|
2015-03-26 06:16:21 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-03-26 06:16:21 +03:00
|
|
|
}
|
|
|
|
|
2015-08-31 08:24:35 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvNotifyPresentationReceiverCleanUp(
|
|
|
|
const nsString& aSessionId) {
|
|
|
|
nsCOMPtr<nsIPresentationService> service =
|
2016-01-05 12:59:30 +03:00
|
|
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
2016-09-02 10:12:24 +03:00
|
|
|
NS_WARNING_ASSERTION(service, "presentation service is missing");
|
2015-08-31 08:24:35 +03:00
|
|
|
|
2016-09-02 10:12:24 +03:00
|
|
|
Unused << NS_WARN_IF(NS_FAILED(service->UntrackSessionInfo(
|
|
|
|
aSessionId, nsIPresentationService::ROLE_RECEIVER)));
|
2015-08-31 08:24:35 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-08-31 08:24:35 +03:00
|
|
|
}
|
|
|
|
|
2016-08-08 06:04:55 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvNotifyEmptyHTTPCache() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
obs->NotifyObservers(nullptr, "cacheservice:empty-cache", nullptr);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-08-08 06:04:55 +03:00
|
|
|
}
|
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
PHalChild* ContentChild::AllocPHalChild() { return CreateHalChild(); }
|
2011-10-06 02:15:45 +04:00
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
bool ContentChild::DeallocPHalChild(PHalChild* aHal) {
|
2016-01-05 12:59:30 +03:00
|
|
|
delete aHal;
|
|
|
|
return true;
|
2011-10-06 02:15:45 +04:00
|
|
|
}
|
|
|
|
|
2015-09-22 22:09:42 +03:00
|
|
|
devtools::PHeapSnapshotTempFileHelperChild*
|
|
|
|
ContentChild::AllocPHeapSnapshotTempFileHelperChild() {
|
2016-01-05 12:59:30 +03:00
|
|
|
return devtools::HeapSnapshotTempFileHelperChild::Create();
|
2015-09-22 22:09:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPHeapSnapshotTempFileHelperChild(
|
2016-01-05 12:59:30 +03:00
|
|
|
devtools::PHeapSnapshotTempFileHelperChild* aHeapSnapshotHelper) {
|
|
|
|
delete aHeapSnapshotHelper;
|
|
|
|
return true;
|
2015-09-22 22:09:42 +03:00
|
|
|
}
|
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
PTestShellChild* ContentChild::AllocPTestShellChild() {
|
2016-01-05 12:59:30 +03:00
|
|
|
return new TestShellChild();
|
2009-08-12 22:31:48 +04:00
|
|
|
}
|
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
bool ContentChild::DeallocPTestShellChild(PTestShellChild* shell) {
|
2016-01-05 12:59:30 +03:00
|
|
|
delete shell;
|
|
|
|
return true;
|
2009-08-26 03:07:22 +04:00
|
|
|
}
|
|
|
|
|
2013-07-03 11:24:32 +04:00
|
|
|
jsipc::CPOWManager* ContentChild::GetCPOWManager() {
|
2016-01-05 12:59:30 +03:00
|
|
|
if (PJavaScriptChild* c =
|
|
|
|
LoneManagedOrNullAsserts(ManagedPJavaScriptChild())) {
|
|
|
|
return CPOWManagerFor(c);
|
|
|
|
}
|
2018-07-23 17:51:09 +03:00
|
|
|
if (recordreplay::IsMiddleman()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
return CPOWManagerFor(SendPJavaScriptConstructor());
|
2013-07-03 11:24:32 +04:00
|
|
|
}
|
|
|
|
|
2010-07-19 22:33:33 +04:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvPTestShellConstructor(
|
|
|
|
PTestShellChild* actor) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2009-11-06 23:43:39 +03:00
|
|
|
}
|
|
|
|
|
2017-08-03 14:00:41 +03:00
|
|
|
void ContentChild::UpdateCookieStatus(nsIChannel* aChannel) {
|
|
|
|
RefPtr<CookieServiceChild> csChild = CookieServiceChild::GetSingleton();
|
|
|
|
NS_ASSERTION(csChild, "Couldn't get CookieServiceChild");
|
|
|
|
|
|
|
|
csChild->TrackCookieLoad(aChannel);
|
|
|
|
}
|
|
|
|
|
2019-05-07 05:29:48 +03:00
|
|
|
already_AddRefed<RemoteBrowser> ContentChild::CreateBrowser(
|
2019-04-25 07:52:47 +03:00
|
|
|
nsFrameLoader* aFrameLoader, const TabContext& aContext,
|
|
|
|
const nsString& aRemoteType, BrowsingContext* aBrowsingContext) {
|
|
|
|
MOZ_ASSERT(XRE_IsContentProcess());
|
|
|
|
|
|
|
|
// Determine our embedder's BrowserChild actor.
|
|
|
|
RefPtr<Element> owner = aFrameLoader->GetOwnerContent();
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(owner);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(owner->GetOwnerGlobal());
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(docShell);
|
|
|
|
|
|
|
|
RefPtr<BrowserChild> browserChild = BrowserChild::GetFrom(docShell);
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(browserChild);
|
|
|
|
|
|
|
|
uint32_t chromeFlags = 0;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
|
|
|
if (docShell) {
|
|
|
|
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
|
|
|
}
|
|
|
|
if (treeOwner) {
|
|
|
|
nsCOMPtr<nsIWebBrowserChrome> wbc = do_GetInterface(treeOwner);
|
|
|
|
if (wbc) {
|
|
|
|
wbc->GetChromeFlags(&chromeFlags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Checking that this actually does something useful is
|
|
|
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1542710
|
|
|
|
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
|
|
|
|
if (loadContext && loadContext->UsePrivateBrowsing()) {
|
|
|
|
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
|
|
|
|
}
|
2019-08-23 19:06:09 +03:00
|
|
|
if (loadContext && loadContext->UseRemoteTabs()) {
|
|
|
|
chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
|
|
|
|
}
|
|
|
|
if (loadContext && loadContext->UseRemoteSubframes()) {
|
|
|
|
chromeFlags |= nsIWebBrowserChrome::CHROME_FISSION_WINDOW;
|
|
|
|
}
|
2019-04-25 07:52:47 +03:00
|
|
|
if (docShell->GetAffectPrivateSessionLifetime()) {
|
|
|
|
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
|
|
|
|
}
|
|
|
|
|
2019-06-02 20:42:03 +03:00
|
|
|
TabId tabId(nsContentUtils::GenerateTabId());
|
2019-04-25 07:52:47 +03:00
|
|
|
RefPtr<BrowserBridgeChild> browserBridge =
|
2019-10-22 16:57:00 +03:00
|
|
|
new BrowserBridgeChild(aBrowsingContext, tabId);
|
2019-09-19 21:45:36 +03:00
|
|
|
|
2019-04-25 07:52:47 +03:00
|
|
|
browserChild->SendPBrowserBridgeConstructor(
|
2019-07-29 22:54:18 +03:00
|
|
|
browserBridge, PromiseFlatString(aContext.PresentationURL()), aRemoteType,
|
2019-08-08 20:41:10 +03:00
|
|
|
aBrowsingContext, chromeFlags, tabId);
|
2019-06-13 05:19:42 +03:00
|
|
|
|
2019-10-22 16:57:00 +03:00
|
|
|
return browserBridge->FinishInit(aFrameLoader);
|
2019-04-25 07:52:47 +03:00
|
|
|
}
|
|
|
|
|
2017-05-03 03:17:52 +03:00
|
|
|
PScriptCacheChild* ContentChild::AllocPScriptCacheChild(
|
|
|
|
const FileDescOrError& cacheFile, const bool& wantCacheData) {
|
|
|
|
return new loader::ScriptCacheChild();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPScriptCacheChild(PScriptCacheChild* cache) {
|
|
|
|
delete static_cast<loader::ScriptCacheChild*>(cache);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvPScriptCacheConstructor(
|
|
|
|
PScriptCacheChild* actor, const FileDescOrError& cacheFile,
|
|
|
|
const bool& wantCacheData) {
|
|
|
|
Maybe<FileDescriptor> fd;
|
|
|
|
if (cacheFile.type() == cacheFile.TFileDescriptor) {
|
|
|
|
fd.emplace(cacheFile.get_FileDescriptor());
|
|
|
|
}
|
|
|
|
|
|
|
|
static_cast<loader::ScriptCacheChild*>(actor)->Init(fd, wantCacheData);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
PNeckoChild* ContentChild::AllocPNeckoChild() { return new NeckoChild(); }
|
2009-08-18 23:05:15 +04:00
|
|
|
|
2019-05-07 01:41:25 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvNetworkLinkTypeChange(
|
|
|
|
const uint32_t& aType) {
|
|
|
|
mNetworkLinkType = aType;
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
if (obs) {
|
|
|
|
obs->NotifyObservers(nullptr, "contentchild:network-link-type-changed",
|
|
|
|
nullptr);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
bool ContentChild::DeallocPNeckoChild(PNeckoChild* necko) {
|
2016-01-05 12:59:30 +03:00
|
|
|
delete necko;
|
|
|
|
return true;
|
2009-08-18 23:05:15 +04:00
|
|
|
}
|
|
|
|
|
2014-10-28 18:59:08 +03:00
|
|
|
PPrintingChild* ContentChild::AllocPPrintingChild() {
|
2016-01-05 12:59:30 +03:00
|
|
|
// The ContentParent should never attempt to allocate the nsPrintingProxy,
|
|
|
|
// which implements PPrintingChild. Instead, the nsPrintingProxy service is
|
|
|
|
// requested and instantiated via XPCOM, and the constructor of
|
|
|
|
// nsPrintingProxy sets up the IPC connection.
|
2016-01-08 23:40:26 +03:00
|
|
|
MOZ_CRASH("Should never get here!");
|
2016-01-05 12:59:30 +03:00
|
|
|
return nullptr;
|
2014-10-28 18:59:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPPrintingChild(PPrintingChild* printing) {
|
2016-01-05 12:59:30 +03:00
|
|
|
return true;
|
2014-10-28 18:59:08 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:28:58 +03:00
|
|
|
PChildToParentStreamChild* ContentChild::SendPChildToParentStreamConstructor(
|
|
|
|
PChildToParentStreamChild* aActor) {
|
2017-01-17 05:33:48 +03:00
|
|
|
if (IsShuttingDown()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2017-03-14 14:28:58 +03:00
|
|
|
return PContentChild::SendPChildToParentStreamConstructor(aActor);
|
2016-09-21 13:27:26 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:28:58 +03:00
|
|
|
PChildToParentStreamChild* ContentChild::AllocPChildToParentStreamChild() {
|
2019-02-25 23:04:53 +03:00
|
|
|
MOZ_CRASH("PChildToParentStreamChild actors should be manually constructed!");
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:28:58 +03:00
|
|
|
bool ContentChild::DeallocPChildToParentStreamChild(
|
|
|
|
PChildToParentStreamChild* aActor) {
|
2019-02-25 23:04:53 +03:00
|
|
|
delete aActor;
|
|
|
|
return true;
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
PParentToChildStreamChild* ContentChild::AllocPParentToChildStreamChild() {
|
2019-02-25 23:04:53 +03:00
|
|
|
return mozilla::ipc::AllocPParentToChildStreamChild();
|
2017-03-14 14:29:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPParentToChildStreamChild(
|
|
|
|
PParentToChildStreamChild* aActor) {
|
2019-02-25 23:04:53 +03:00
|
|
|
delete aActor;
|
|
|
|
return true;
|
2017-03-14 14:29:43 +03:00
|
|
|
}
|
|
|
|
|
2015-04-22 22:55:23 +03:00
|
|
|
PPSMContentDownloaderChild* ContentChild::AllocPPSMContentDownloaderChild(
|
|
|
|
const uint32_t& aCertType) {
|
2016-01-05 12:59:30 +03:00
|
|
|
// NB: We don't need aCertType in the child actor.
|
|
|
|
RefPtr<PSMContentDownloaderChild> child = new PSMContentDownloaderChild();
|
|
|
|
return child.forget().take();
|
2015-04-22 22:55:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPPSMContentDownloaderChild(
|
|
|
|
PPSMContentDownloaderChild* aListener) {
|
2016-01-05 12:59:30 +03:00
|
|
|
auto* listener = static_cast<PSMContentDownloaderChild*>(aListener);
|
|
|
|
RefPtr<PSMContentDownloaderChild> child = dont_AddRef(listener);
|
|
|
|
return true;
|
2015-04-22 22:55:23 +03:00
|
|
|
}
|
|
|
|
|
2015-06-18 18:46:36 +03:00
|
|
|
media::PMediaChild* ContentChild::AllocPMediaChild() {
|
|
|
|
return media::AllocPMediaChild();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPMediaChild(media::PMediaChild* aActor) {
|
|
|
|
return media::DeallocPMediaChild(aActor);
|
|
|
|
}
|
|
|
|
|
2019-08-06 12:24:34 +03:00
|
|
|
PBenchmarkStorageChild* ContentChild::AllocPBenchmarkStorageChild() {
|
|
|
|
return BenchmarkStorageChild::Instance();
|
|
|
|
}
|
|
|
|
|
2019-08-08 20:41:10 +03:00
|
|
|
bool ContentChild::DeallocPBenchmarkStorageChild(
|
|
|
|
PBenchmarkStorageChild* aActor) {
|
2019-08-06 12:24:34 +03:00
|
|
|
delete aActor;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
PSpeechSynthesisChild* ContentChild::AllocPSpeechSynthesisChild() {
|
2013-04-04 02:13:17 +04:00
|
|
|
#ifdef MOZ_WEBSPEECH
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_CRASH("No one should be allocating PSpeechSynthesisChild actors");
|
2013-04-04 02:13:17 +04:00
|
|
|
#else
|
2016-01-05 12:59:30 +03:00
|
|
|
return nullptr;
|
2013-04-04 02:13:17 +04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
bool ContentChild::DeallocPSpeechSynthesisChild(PSpeechSynthesisChild* aActor) {
|
2013-04-04 02:13:17 +04:00
|
|
|
#ifdef MOZ_WEBSPEECH
|
2016-01-05 12:59:30 +03:00
|
|
|
delete aActor;
|
|
|
|
return true;
|
2013-04-04 02:13:17 +04:00
|
|
|
#else
|
2016-01-05 12:59:30 +03:00
|
|
|
return false;
|
2013-04-04 02:13:17 +04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-04-22 01:29:18 +03:00
|
|
|
PWebrtcGlobalChild* ContentChild::AllocPWebrtcGlobalChild() {
|
2015-05-06 19:29:33 +03:00
|
|
|
#ifdef MOZ_WEBRTC
|
2016-11-14 12:35:58 +03:00
|
|
|
auto* child = new WebrtcGlobalChild();
|
2016-01-05 12:59:30 +03:00
|
|
|
return child;
|
2015-05-06 19:29:33 +03:00
|
|
|
#else
|
2016-01-05 12:59:30 +03:00
|
|
|
return nullptr;
|
2015-05-06 19:29:33 +03:00
|
|
|
#endif
|
2015-04-22 01:29:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPWebrtcGlobalChild(PWebrtcGlobalChild* aActor) {
|
2015-05-06 19:29:33 +03:00
|
|
|
#ifdef MOZ_WEBRTC
|
2016-01-05 12:59:30 +03:00
|
|
|
delete static_cast<WebrtcGlobalChild*>(aActor);
|
|
|
|
return true;
|
2015-05-06 19:29:33 +03:00
|
|
|
#else
|
2016-01-05 12:59:30 +03:00
|
|
|
return false;
|
2015-05-06 19:29:33 +03:00
|
|
|
#endif
|
2015-04-22 01:29:18 +03:00
|
|
|
}
|
|
|
|
|
2015-01-16 22:58:52 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRegisterChrome(
|
2019-07-10 06:27:27 +03:00
|
|
|
nsTArray<ChromePackage>&& packages,
|
|
|
|
nsTArray<SubstitutionMapping>&& resources,
|
|
|
|
nsTArray<OverrideMapping>&& overrides, const nsCString& locale,
|
2014-07-26 00:17:36 +04:00
|
|
|
const bool& reset) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
|
|
|
|
nsChromeRegistryContent* chromeRegistry =
|
|
|
|
static_cast<nsChromeRegistryContent*>(registrySvc.get());
|
2018-07-04 18:37:02 +03:00
|
|
|
if (!chromeRegistry) {
|
2018-07-04 17:20:59 +03:00
|
|
|
return IPC_FAIL(this, "ChromeRegistryContent is null!");
|
2018-07-04 18:37:02 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
chromeRegistry->RegisterRemoteChrome(packages, resources, overrides, locale,
|
|
|
|
reset);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-07-26 00:17:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRegisterChromeItem(
|
|
|
|
const ChromeRegistryItem& item) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
|
|
|
|
nsChromeRegistryContent* chromeRegistry =
|
|
|
|
static_cast<nsChromeRegistryContent*>(registrySvc.get());
|
2018-07-04 18:37:02 +03:00
|
|
|
if (!chromeRegistry) {
|
2018-07-04 17:20:59 +03:00
|
|
|
return IPC_FAIL(this, "ChromeRegistryContent is null!");
|
2018-07-04 18:37:02 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
switch (item.type()) {
|
|
|
|
case ChromeRegistryItem::TChromePackage:
|
|
|
|
chromeRegistry->RegisterPackage(item.get_ChromePackage());
|
|
|
|
break;
|
2014-07-26 00:17:36 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
case ChromeRegistryItem::TOverrideMapping:
|
|
|
|
chromeRegistry->RegisterOverride(item.get_OverrideMapping());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ChromeRegistryItem::TSubstitutionMapping:
|
|
|
|
chromeRegistry->RegisterSubstitution(item.get_SubstitutionMapping());
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
MOZ_ASSERT(false, "bad chrome item");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-03-11 08:33:00 +03:00
|
|
|
}
|
|
|
|
|
2016-06-07 01:23:43 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvClearImageCache(
|
|
|
|
const bool& privateLoader, const bool& chrome) {
|
|
|
|
imgLoader* loader = privateLoader ? imgLoader::PrivateBrowsingLoader()
|
|
|
|
: imgLoader::NormalLoader();
|
|
|
|
|
|
|
|
loader->ClearCache(chrome);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-07 01:23:43 +03:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSetOffline(const bool& offline) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIIOService> io(do_GetIOService());
|
|
|
|
NS_ASSERTION(io, "IO Service can not be null");
|
2010-05-11 16:44:12 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
io->SetOffline(offline);
|
2011-02-15 01:34:46 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-05-11 16:44:12 +04:00
|
|
|
}
|
|
|
|
|
2015-05-02 00:14:39 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSetConnectivity(
|
|
|
|
const bool& connectivity) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIIOService> io(do_GetIOService());
|
|
|
|
nsCOMPtr<nsIIOServiceInternal> ioInternal(do_QueryInterface(io));
|
|
|
|
NS_ASSERTION(ioInternal, "IO Service can not be null");
|
2015-05-02 00:14:39 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
ioInternal->SetConnectivity(connectivity);
|
2015-05-02 00:14:39 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-05-02 00:14:39 +03:00
|
|
|
}
|
|
|
|
|
2016-11-17 19:35:24 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSetCaptivePortalState(
|
|
|
|
const int32_t& aState) {
|
|
|
|
nsCOMPtr<nsICaptivePortalService> cps = do_GetService(NS_CAPTIVEPORTAL_CID);
|
|
|
|
if (!cps) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::net::CaptivePortalService* portal =
|
|
|
|
static_cast<mozilla::net::CaptivePortalService*>(cps.get());
|
|
|
|
portal->SetStateInChild(aState);
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2010-07-19 22:33:33 +04:00
|
|
|
void ContentChild::ActorDestroy(ActorDestroyReason why) {
|
2016-06-02 15:52:17 +03:00
|
|
|
if (mForceKillTimer) {
|
|
|
|
mForceKillTimer->Cancel();
|
|
|
|
mForceKillTimer = nullptr;
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (AbnormalShutdown == why) {
|
|
|
|
NS_WARNING("shutting down early because of crash!");
|
2016-04-11 11:12:33 +03:00
|
|
|
ProcessChild::QuickExit();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2010-08-21 03:24:40 +04:00
|
|
|
|
2015-07-31 22:11:48 +03:00
|
|
|
#ifndef NS_FREE_PERMANENT_DATA
|
2016-01-05 12:59:30 +03:00
|
|
|
// In release builds, there's no point in the content process
|
|
|
|
// going through the full XPCOM shutdown path, because it doesn't
|
|
|
|
// keep persistent state.
|
2016-04-11 11:12:33 +03:00
|
|
|
ProcessChild::QuickExit();
|
2015-11-09 08:41:40 +03:00
|
|
|
#else
|
2017-02-01 15:34:24 +03:00
|
|
|
if (gFirstIdleTask) {
|
|
|
|
gFirstIdleTask->Cancel();
|
2018-01-05 01:59:14 +03:00
|
|
|
gFirstIdleTask = nullptr;
|
2017-02-01 15:34:24 +03:00
|
|
|
}
|
2012-11-28 00:43:52 +04:00
|
|
|
|
2018-06-02 16:51:42 +03:00
|
|
|
BlobURLProtocolHandler::RemoveDataEntries();
|
2016-07-18 12:13:31 +03:00
|
|
|
|
2018-06-23 06:35:49 +03:00
|
|
|
mSharedData = nullptr;
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
mAlertObservers.Clear();
|
2011-02-15 01:34:46 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
mIdleObservers.Clear();
|
2014-04-21 21:18:53 +04:00
|
|
|
|
2019-05-03 02:56:41 +03:00
|
|
|
mBrowsingContextGroupHolder.Clear();
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
|
|
|
if (svc) {
|
|
|
|
svc->UnregisterListener(mConsoleListener);
|
|
|
|
mConsoleListener->mChild = nullptr;
|
|
|
|
}
|
|
|
|
mIsAlive = false;
|
2010-09-24 05:39:32 +04:00
|
|
|
|
2017-02-17 05:44:16 +03:00
|
|
|
CrashReporterClient::DestroySingleton();
|
2017-10-10 13:43:09 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
XRE_ShutdownChildProcess();
|
2015-11-09 08:41:40 +03:00
|
|
|
#endif // NS_FREE_PERMANENT_DATA
|
2009-09-03 04:18:27 +04:00
|
|
|
}
|
|
|
|
|
2015-02-03 20:09:27 +03:00
|
|
|
void ContentChild::ProcessingError(Result aCode, const char* aReason) {
|
2016-01-05 12:59:30 +03:00
|
|
|
switch (aCode) {
|
|
|
|
case MsgDropped:
|
|
|
|
NS_WARNING("MsgDropped in ContentChild");
|
|
|
|
return;
|
|
|
|
|
|
|
|
case MsgNotKnown:
|
|
|
|
case MsgNotAllowed:
|
|
|
|
case MsgPayloadError:
|
|
|
|
case MsgProcessingError:
|
|
|
|
case MsgRouteError:
|
|
|
|
case MsgValueError:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2016-12-03 00:46:53 +03:00
|
|
|
MOZ_CRASH("not reached");
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-02-08 21:37:21 +03:00
|
|
|
|
2017-02-17 05:44:16 +03:00
|
|
|
nsDependentCString reason(aReason);
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
CrashReporter::AnnotateCrashReport(
|
|
|
|
CrashReporter::Annotation::ipc_channel_error, reason);
|
2017-10-10 13:43:09 +03:00
|
|
|
|
2016-12-03 00:46:53 +03:00
|
|
|
MOZ_CRASH("Content child abort due to IPC error");
|
2010-08-21 03:24:40 +04:00
|
|
|
}
|
|
|
|
|
2010-09-15 20:44:57 +04:00
|
|
|
nsresult ContentChild::AddRemoteAlertObserver(const nsString& aData,
|
|
|
|
nsIObserver* aObserver) {
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_ASSERTION(aObserver, "Adding a null observer?");
|
|
|
|
mAlertObservers.AppendElement(new AlertObserver(aObserver, aData));
|
|
|
|
return NS_OK;
|
2010-09-15 20:44:57 +04:00
|
|
|
}
|
|
|
|
|
2017-11-22 13:21:19 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvPreferenceUpdate(const Pref& aPref) {
|
2016-01-05 12:59:30 +03:00
|
|
|
Preferences::SetPreference(aPref);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-05-26 04:13:47 +04:00
|
|
|
}
|
|
|
|
|
2016-08-04 21:33:42 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvVarUpdate(const GfxVarUpdate& aVar) {
|
|
|
|
gfx::gfxVars::ApplyUpdate(aVar);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-08-04 21:33:42 +03:00
|
|
|
}
|
|
|
|
|
2019-05-21 22:01:31 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUpdatePerfStatsCollectionMask(
|
|
|
|
const uint64_t& aMask) {
|
|
|
|
PerfStats::SetCollectionMask(static_cast<PerfStats::MetricMask>(aMask));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvCollectPerfStatsJSON(
|
|
|
|
CollectPerfStatsJSONResolver&& aResolver) {
|
|
|
|
aResolver(PerfStats::CollectLocalPerfStatsJSON());
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvDataStoragePut(
|
2015-10-30 22:30:00 +03:00
|
|
|
const nsString& aFilename, const DataStorageItem& aItem) {
|
2017-03-16 05:19:14 +03:00
|
|
|
RefPtr<DataStorage> storage = DataStorage::GetFromRawFileName(aFilename);
|
2016-01-05 12:59:30 +03:00
|
|
|
if (storage) {
|
|
|
|
storage->Put(aItem.key(), aItem.value(), aItem.type());
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-10-30 22:30:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvDataStorageRemove(
|
|
|
|
const nsString& aFilename, const nsCString& aKey,
|
|
|
|
const DataStorageType& aType) {
|
2017-03-16 05:19:14 +03:00
|
|
|
RefPtr<DataStorage> storage = DataStorage::GetFromRawFileName(aFilename);
|
2016-01-05 12:59:30 +03:00
|
|
|
if (storage) {
|
|
|
|
storage->Remove(aKey, aType);
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-10-30 22:30:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvDataStorageClear(
|
|
|
|
const nsString& aFilename) {
|
2017-03-16 05:19:14 +03:00
|
|
|
RefPtr<DataStorage> storage = DataStorage::GetFromRawFileName(aFilename);
|
2016-01-05 12:59:30 +03:00
|
|
|
if (storage) {
|
|
|
|
storage->Clear();
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-10-30 22:30:00 +03:00
|
|
|
}
|
|
|
|
|
2010-09-15 20:44:57 +04:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvNotifyAlertsObserver(
|
|
|
|
const nsCString& aType, const nsString& aData) {
|
2016-01-05 12:59:30 +03:00
|
|
|
for (uint32_t i = 0; i < mAlertObservers.Length();
|
|
|
|
/*we mutate the array during the loop; ++i iff no mutation*/) {
|
|
|
|
AlertObserver* observer = mAlertObservers[i];
|
|
|
|
if (observer->Observes(aData) && observer->Notify(aType)) {
|
|
|
|
// if aType == alertfinished, this alert is done. we can
|
|
|
|
// remove the observer.
|
|
|
|
if (aType.Equals(nsDependentCString("alertfinished"))) {
|
|
|
|
mAlertObservers.RemoveElementAt(i);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-09-15 20:44:57 +04:00
|
|
|
}
|
|
|
|
|
2017-06-19 23:22:15 +03:00
|
|
|
// NOTE: This method is being run in the SystemGroup, and thus cannot directly
|
|
|
|
// touch pages. See GetSpecificMessageEventTarget.
|
2017-12-04 20:45:29 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvNotifyVisited(
|
2019-11-04 16:28:58 +03:00
|
|
|
nsTArray<VisitedQueryResult>&& aURIs) {
|
|
|
|
nsCOMPtr<IHistory> history = services::GetHistoryService();
|
|
|
|
if (!history) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
for (const VisitedQueryResult& result : aURIs) {
|
|
|
|
nsCOMPtr<nsIURI> newURI = DeserializeURI(result.uri());
|
2017-12-04 20:45:29 +03:00
|
|
|
if (!newURI) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
2019-11-04 16:28:58 +03:00
|
|
|
auto status = result.visited() ? IHistory::VisitedStatus::Visited
|
|
|
|
: IHistory::VisitedStatus::Unvisited;
|
|
|
|
history->NotifyVisited(newURI, status);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-07-02 19:50:41 +04:00
|
|
|
}
|
|
|
|
|
2015-02-20 04:13:02 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvLoadProcessScript(
|
|
|
|
const nsString& aURL) {
|
2018-08-03 01:03:50 +03:00
|
|
|
auto* global = ContentProcessMessageManager::Get();
|
2016-01-05 12:59:30 +03:00
|
|
|
global->LoadScript(aURL);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-02-20 04:13:02 +03:00
|
|
|
}
|
|
|
|
|
2012-08-02 10:02:29 +04:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvAsyncMessage(
|
2019-07-10 06:27:27 +03:00
|
|
|
const nsString& aMsg, nsTArray<CpowEntry>&& aCpows,
|
2016-04-09 16:50:59 +03:00
|
|
|
const IPC::Principal& aPrincipal, const ClonedMessageData& aData) {
|
2017-10-13 08:12:57 +03:00
|
|
|
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING("ContentChild::RecvAsyncMessage",
|
2018-05-19 00:36:30 +03:00
|
|
|
OTHER, aMsg);
|
2018-12-11 20:31:24 +03:00
|
|
|
MMPrinter::Print("ContentChild::RecvAsyncMessage", aMsg, aData);
|
2017-03-30 00:43:21 +03:00
|
|
|
|
2017-01-17 22:00:38 +03:00
|
|
|
CrossProcessCpowHolder cpows(this, aCpows);
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<nsFrameMessageManager> cpm =
|
|
|
|
nsFrameMessageManager::GetChildProcessManager();
|
|
|
|
if (cpm) {
|
|
|
|
StructuredCloneData data;
|
|
|
|
ipc::UnpackClonedMessageDataForChild(aData, data);
|
2018-02-16 17:28:31 +03:00
|
|
|
cpm->ReceiveMessage(cpm, nullptr, aMsg, false, &data, &cpows, aPrincipal,
|
|
|
|
nullptr, IgnoreErrors());
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-08-31 22:58:35 +04:00
|
|
|
}
|
|
|
|
|
2018-06-30 08:53:12 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRegisterStringBundles(
|
|
|
|
nsTArray<mozilla::dom::StringBundleDescriptor>&& aDescriptors) {
|
|
|
|
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
|
|
|
services::GetStringBundleService();
|
|
|
|
|
|
|
|
for (auto& descriptor : aDescriptors) {
|
|
|
|
stringBundleService->RegisterContentBundle(
|
|
|
|
descriptor.bundleURL(), descriptor.mapFile(), descriptor.mapSize());
|
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-06-23 06:35:49 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUpdateSharedData(
|
|
|
|
const FileDescriptor& aMapFile, const uint32_t& aMapSize,
|
|
|
|
nsTArray<IPCBlob>&& aBlobs, nsTArray<nsCString>&& aChangedKeys) {
|
2018-07-21 00:44:00 +03:00
|
|
|
nsTArray<RefPtr<BlobImpl>> blobImpls(aBlobs.Length());
|
|
|
|
for (auto& ipcBlob : aBlobs) {
|
|
|
|
blobImpls.AppendElement(IPCBlobUtils::Deserialize(ipcBlob));
|
|
|
|
}
|
2018-06-28 02:35:53 +03:00
|
|
|
|
2018-07-21 00:44:00 +03:00
|
|
|
if (mSharedData) {
|
2018-06-28 02:35:53 +03:00
|
|
|
mSharedData->Update(aMapFile, aMapSize, std::move(blobImpls),
|
|
|
|
std::move(aChangedKeys));
|
2018-07-21 00:44:00 +03:00
|
|
|
} else {
|
2018-08-11 00:03:18 +03:00
|
|
|
mSharedData =
|
|
|
|
new SharedMap(ContentProcessMessageManager::Get()->GetParentObject(),
|
|
|
|
aMapFile, aMapSize, std::move(blobImpls));
|
2018-06-23 06:35:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-04-27 18:37:58 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvFontListChanged() {
|
|
|
|
gfxPlatformFontList::PlatformFontList()->FontListChanged();
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
Bug 1443954 - Part 3: Add support for RefCounted types to IPDL, r=bz,froydnj,baku
This patch was reviewed in parts, however the intermediate states would not build:
Bug 1443954 - Part 3A: Strip pointers from the argument to WriteParam and WriteIPDLParam before selecting the ParamTraits impl, r=froydnj
Bug 1443954 - Part 3B: Move nsIAlertNotification serialization to the refcounted system, r=bz
Bug 1443954 - Part 3C: Move geolocation serialization to the refcounted system, r=bz
Bug 1443954 - Part 3D: Move nsIInputStream serialization to the refcounted system, r=baku
Bug 1443954 - Part 3E: Move BlobImpl serialization to the refcounted system, r=baku
Bug 1443954 - Part 3F: Correctly implement ParamTraits for actors after the ParamTraits changes, r=froydnj
2018-03-07 04:14:59 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvGeolocationUpdate(
|
|
|
|
nsIDOMGeoPosition* aPosition) {
|
2018-08-22 07:22:01 +03:00
|
|
|
RefPtr<nsGeolocationService> gs =
|
|
|
|
nsGeolocationService::GetGeolocationService();
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!gs) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
Bug 1443954 - Part 3: Add support for RefCounted types to IPDL, r=bz,froydnj,baku
This patch was reviewed in parts, however the intermediate states would not build:
Bug 1443954 - Part 3A: Strip pointers from the argument to WriteParam and WriteIPDLParam before selecting the ParamTraits impl, r=froydnj
Bug 1443954 - Part 3B: Move nsIAlertNotification serialization to the refcounted system, r=bz
Bug 1443954 - Part 3C: Move geolocation serialization to the refcounted system, r=bz
Bug 1443954 - Part 3D: Move nsIInputStream serialization to the refcounted system, r=baku
Bug 1443954 - Part 3E: Move BlobImpl serialization to the refcounted system, r=baku
Bug 1443954 - Part 3F: Correctly implement ParamTraits for actors after the ParamTraits changes, r=froydnj
2018-03-07 04:14:59 +03:00
|
|
|
gs->Update(aPosition);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-09-21 08:16:37 +04:00
|
|
|
}
|
|
|
|
|
2014-10-23 22:31:00 +04:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvGeolocationError(
|
|
|
|
const uint16_t& errorCode) {
|
2018-08-22 07:22:01 +03:00
|
|
|
RefPtr<nsGeolocationService> gs =
|
|
|
|
nsGeolocationService::GetGeolocationService();
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!gs) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
gs->NotifyError(errorCode);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-10-23 22:31:00 +04:00
|
|
|
}
|
|
|
|
|
2015-01-16 22:58:52 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUpdateDictionaryList(
|
2019-07-10 06:27:27 +03:00
|
|
|
nsTArray<nsString>&& aDictionaries) {
|
2016-01-05 12:59:30 +03:00
|
|
|
mAvailableDictionaries = aDictionaries;
|
|
|
|
mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking();
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-10-03 18:52:37 +04:00
|
|
|
}
|
|
|
|
|
2017-11-02 23:29:33 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUpdateFontList(
|
2019-07-10 06:27:27 +03:00
|
|
|
nsTArray<SystemFontListEntry>&& aFontList) {
|
2018-05-30 22:15:35 +03:00
|
|
|
mFontList = std::move(aFontList);
|
2017-11-02 23:29:33 +03:00
|
|
|
gfxPlatform::GetPlatform()->UpdateFontList();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-04-27 18:37:58 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRebuildFontList() {
|
|
|
|
gfxPlatform::GetPlatform()->UpdateFontList();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
Bug 1348042 - Refactor LocaleService to operate in server-client mode. r=Ehsan,qdot
LocaleService serves two main functions. It is a central place for all code in the
engine to learn about locales, but it also does the language negotiation and selection.
The former is relevant in all processes, but the latter should only be performed
by the "main" process. In case of current Desktop Firefox, the parent process
is the one performing all the language negotiation, and content processes should
operate in the "client" mode.
In Fennec, there's a Java app on top of Gecko which should work as a "server"
and then all processes, including parent process of Gecko is merely a "client" for that.
This refactor finalizes this duality making it easily configurable to define in
which mode a given LocaleService operates.
The server-client model allows all clients to stay in sync with the server,
but operate transparently for all callers just returning the right values.
In order to initialize LocaleService in the client mode in child process with the
right locales I'm adding the list of app locales to the XPCOMInitData,
and then fire LocaleService::SetAppLocales in the child process initialization.
In order to keep the list up to date, I'm adding intl:app-locales-changed to
the list of observed topics, and when triggered, I send the updated list
to the child process, which updates LocaleService::SetAppLocales with the new
list.
MozReview-Commit-ID: K9X6berF3IO
--HG--
extra : rebase_source : ca5e502d064023fddfd63fe6fe5eccefce8dee52
2017-03-26 08:09:45 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUpdateAppLocales(
|
|
|
|
nsTArray<nsCString>&& aAppLocales) {
|
|
|
|
LocaleService::GetInstance()->AssignAppLocales(aAppLocales);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUpdateRequestedLocales(
|
|
|
|
nsTArray<nsCString>&& aRequestedLocales) {
|
|
|
|
LocaleService::GetInstance()->AssignRequestedLocales(aRequestedLocales);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2010-10-09 22:07:38 +04:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvAddPermission(
|
|
|
|
const IPC::Permission& permission) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIPermissionManager> permissionManagerIface =
|
|
|
|
services::GetPermissionManager();
|
|
|
|
nsPermissionManager* permissionManager =
|
|
|
|
static_cast<nsPermissionManager*>(permissionManagerIface.get());
|
|
|
|
MOZ_ASSERT(permissionManager,
|
|
|
|
"We have no permissionManager in the Content process !");
|
|
|
|
|
2016-06-17 09:18:00 +03:00
|
|
|
// note we do not need to force mUserContextId to the default here because
|
|
|
|
// the permission manager does that internally.
|
2016-01-05 12:59:30 +03:00
|
|
|
nsAutoCString originNoSuffix;
|
2017-01-12 19:38:48 +03:00
|
|
|
OriginAttributes attrs;
|
2016-08-15 13:21:53 +03:00
|
|
|
bool success = attrs.PopulateFromOrigin(permission.origin, originNoSuffix);
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_TRUE(success, IPC_FAIL_NO_REASON(this));
|
2016-01-05 12:59:30 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2016-01-05 12:59:30 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIPrincipal> principal =
|
2019-07-08 19:37:45 +03:00
|
|
|
mozilla::BasePrincipal::CreateContentPrincipal(uri, attrs);
|
2016-01-05 12:59:30 +03:00
|
|
|
|
|
|
|
// child processes don't care about modification time.
|
|
|
|
int64_t modificationTime = 0;
|
|
|
|
|
|
|
|
permissionManager->AddInternal(
|
|
|
|
principal, nsCString(permission.type), permission.capability, 0,
|
|
|
|
permission.expireType, permission.expireTime, modificationTime,
|
|
|
|
nsPermissionManager::eNotify, nsPermissionManager::eNoDBOperation);
|
2010-10-09 22:07:38 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-10-09 22:07:38 +04:00
|
|
|
}
|
2011-06-20 09:36:17 +04:00
|
|
|
|
2018-07-10 11:09:59 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRemoveAllPermissions() {
|
|
|
|
nsCOMPtr<nsIPermissionManager> permissionManagerIface =
|
|
|
|
services::GetPermissionManager();
|
|
|
|
nsPermissionManager* permissionManager =
|
|
|
|
static_cast<nsPermissionManager*>(permissionManagerIface.get());
|
|
|
|
MOZ_ASSERT(permissionManager,
|
|
|
|
"We have no permissionManager in the Content process !");
|
|
|
|
|
|
|
|
permissionManager->RemoveAllFromIPC();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2010-12-12 01:36:08 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvFlushMemory(const nsString& reason) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
|
|
|
if (os) {
|
|
|
|
os->NotifyObservers(nullptr, "memory-pressure", reason.get());
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-12-12 01:36:08 +03:00
|
|
|
}
|
|
|
|
|
2017-06-07 02:35:51 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvActivateA11y(
|
|
|
|
const uint32_t& aMainChromeTid, const uint32_t& aMsaaID) {
|
2011-07-21 08:37:32 +04:00
|
|
|
#ifdef ACCESSIBILITY
|
2016-10-20 21:34:16 +03:00
|
|
|
# ifdef XP_WIN
|
2017-06-07 02:35:51 +03:00
|
|
|
MOZ_ASSERT(aMainChromeTid != 0);
|
|
|
|
mMainChromeTid = aMainChromeTid;
|
|
|
|
|
2016-10-20 21:34:16 +03:00
|
|
|
MOZ_ASSERT(aMsaaID != 0);
|
|
|
|
mMsaaID = aMsaaID;
|
|
|
|
# endif // XP_WIN
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Start accessibility in content process if it's running in chrome
|
|
|
|
// process.
|
2016-08-29 18:06:48 +03:00
|
|
|
GetOrCreateAccService(nsAccessibilityService::eMainProcess);
|
2016-10-20 21:34:16 +03:00
|
|
|
#endif // ACCESSIBILITY
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-08-29 18:06:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvShutdownA11y() {
|
|
|
|
#ifdef ACCESSIBILITY
|
|
|
|
// Try to shutdown accessibility in content process if it's shutting down in
|
|
|
|
// chrome process.
|
|
|
|
MaybeShutdownAccService(nsAccessibilityService::eMainProcess);
|
2011-07-21 08:37:32 +04:00
|
|
|
#endif
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-07-21 08:37:32 +04:00
|
|
|
}
|
|
|
|
|
2011-09-13 21:53:51 +04:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvGarbageCollect() {
|
2016-01-05 12:59:30 +03:00
|
|
|
// Rebroadcast the "child-gc-request" so that workers will GC.
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
if (obs) {
|
|
|
|
obs->NotifyObservers(nullptr, "child-gc-request", nullptr);
|
|
|
|
}
|
2019-01-21 16:09:12 +03:00
|
|
|
nsJSContext::GarbageCollectNow(JS::GCReason::DOM_IPC);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-09-13 21:53:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvCycleCollect() {
|
2016-01-05 12:59:30 +03:00
|
|
|
// Rebroadcast the "child-cc-request" so that workers will CC.
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
if (obs) {
|
|
|
|
obs->NotifyObservers(nullptr, "child-cc-request", nullptr);
|
|
|
|
}
|
|
|
|
nsJSContext::CycleCollectNow();
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-09-13 21:53:51 +04:00
|
|
|
}
|
|
|
|
|
2018-01-12 01:14:09 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUnlinkGhosts() {
|
|
|
|
#ifdef DEBUG
|
|
|
|
nsWindowMemoryReporter::UnlinkGhostWindows();
|
|
|
|
#endif
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvAppInfo(
|
2013-04-22 20:41:59 +04:00
|
|
|
const nsCString& version, const nsCString& buildID, const nsCString& name,
|
2018-05-16 02:44:44 +03:00
|
|
|
const nsCString& UAName, const nsCString& ID, const nsCString& vendor,
|
|
|
|
const nsCString& sourceURL) {
|
2016-01-05 12:59:30 +03:00
|
|
|
mAppInfo.version.Assign(version);
|
|
|
|
mAppInfo.buildID.Assign(buildID);
|
|
|
|
mAppInfo.name.Assign(name);
|
|
|
|
mAppInfo.UAName.Assign(UAName);
|
|
|
|
mAppInfo.ID.Assign(ID);
|
|
|
|
mAppInfo.vendor.Assign(vendor);
|
2018-05-16 02:44:44 +03:00
|
|
|
mAppInfo.sourceURL.Assign(sourceURL);
|
2013-11-29 13:28:54 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-05-14 17:49:38 +03:00
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRemoteType(
|
|
|
|
const nsString& aRemoteType) {
|
|
|
|
MOZ_ASSERT(DOMStringIsNull(mRemoteType));
|
|
|
|
|
|
|
|
mRemoteType.Assign(aRemoteType);
|
2017-07-25 06:27:40 +03:00
|
|
|
|
|
|
|
// For non-default ("web") types, update the process name so about:memory's
|
|
|
|
// process names are more obvious.
|
|
|
|
if (aRemoteType.EqualsLiteral(FILE_REMOTE_TYPE)) {
|
|
|
|
SetProcessName(NS_LITERAL_STRING("file:// Content"));
|
|
|
|
} else if (aRemoteType.EqualsLiteral(EXTENSION_REMOTE_TYPE)) {
|
|
|
|
SetProcessName(NS_LITERAL_STRING("WebExtensions"));
|
2019-05-29 14:31:31 +03:00
|
|
|
} else if (aRemoteType.EqualsLiteral(PRIVILEGEDABOUT_REMOTE_TYPE)) {
|
2018-06-20 21:04:51 +03:00
|
|
|
SetProcessName(NS_LITERAL_STRING("Privileged Content"));
|
2017-07-25 06:27:40 +03:00
|
|
|
} else if (aRemoteType.EqualsLiteral(LARGE_ALLOCATION_REMOTE_TYPE)) {
|
|
|
|
SetProcessName(NS_LITERAL_STRING("Large Allocation Web Content"));
|
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-06-28 17:30:18 +03:00
|
|
|
// Call RemoteTypePrefix() on the result to remove URIs if you want to use this
|
|
|
|
// for telemetry.
|
2016-11-24 18:08:31 +03:00
|
|
|
const nsAString& ContentChild::GetRemoteType() const { return mRemoteType; }
|
|
|
|
|
2016-07-13 11:34:24 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvInitServiceWorkers(
|
|
|
|
const ServiceWorkerConfiguration& aConfig) {
|
|
|
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
2017-01-13 01:00:36 +03:00
|
|
|
if (!swm) {
|
|
|
|
// browser shutdown began
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2016-07-13 11:34:24 +03:00
|
|
|
swm->LoadRegistrations(aConfig.serviceWorkerRegistrations());
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-13 11:34:24 +03:00
|
|
|
}
|
|
|
|
|
2016-07-17 17:50:50 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvInitBlobURLs(
|
|
|
|
nsTArray<BlobURLRegistrationData>&& aRegistrations) {
|
|
|
|
for (uint32_t i = 0; i < aRegistrations.Length(); ++i) {
|
|
|
|
BlobURLRegistrationData& registration = aRegistrations[i];
|
2017-04-24 13:16:49 +03:00
|
|
|
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(registration.blob());
|
2016-07-17 17:50:50 +03:00
|
|
|
MOZ_ASSERT(blobImpl);
|
|
|
|
|
2018-06-02 16:51:42 +03:00
|
|
|
BlobURLProtocolHandler::AddDataEntry(registration.url(),
|
|
|
|
registration.principal(), blobImpl);
|
2017-11-29 11:40:16 +03:00
|
|
|
// If we have received an already-revoked blobURL, we have to keep it alive
|
2018-06-02 16:51:42 +03:00
|
|
|
// for a while (see BlobURLProtocolHandler) in order to support pending
|
2017-11-29 11:40:16 +03:00
|
|
|
// operations such as navigation, download and so on.
|
|
|
|
if (registration.revoked()) {
|
2018-06-02 16:51:42 +03:00
|
|
|
BlobURLProtocolHandler::RemoveDataEntry(registration.url(), false);
|
2017-11-29 11:40:16 +03:00
|
|
|
}
|
2016-07-17 17:50:50 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-17 17:50:50 +03:00
|
|
|
}
|
|
|
|
|
2019-01-28 22:02:02 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvInitJSWindowActorInfos(
|
|
|
|
nsTArray<JSWindowActorInfo>&& aInfos) {
|
|
|
|
RefPtr<JSWindowActorService> actSvc = JSWindowActorService::GetSingleton();
|
|
|
|
actSvc->LoadJSWindowActorInfos(aInfos);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-02-22 18:17:01 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUnregisterJSWindowActor(
|
|
|
|
const nsString& aName) {
|
|
|
|
RefPtr<JSWindowActorService> actSvc = JSWindowActorService::GetSingleton();
|
|
|
|
actSvc->UnregisterWindowActor(aName);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2012-04-20 04:13:20 +04:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvLastPrivateDocShellDestroyed() {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
obs->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2012-04-20 04:13:20 +04:00
|
|
|
}
|
|
|
|
|
2013-04-26 04:53:26 +04:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvNotifyProcessPriorityChanged(
|
2016-01-05 12:59:30 +03:00
|
|
|
const hal::ProcessPriority& aPriority) {
|
|
|
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_TRUE(os, IPC_OK());
|
2013-04-26 04:53:26 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
|
|
|
|
props->SetPropertyAsInt32(NS_LITERAL_STRING("priority"),
|
|
|
|
static_cast<int32_t>(aPriority));
|
2013-04-26 04:53:26 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
os->NotifyObservers(static_cast<nsIPropertyBag2*>(props),
|
|
|
|
"ipc:process-priority-changed", nullptr);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-04-26 04:53:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvMinimizeMemoryUsage() {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIMemoryReporterManager> mgr =
|
|
|
|
do_GetService("@mozilla.org/memory-reporter-manager;1");
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_TRUE(mgr, IPC_OK());
|
2013-04-26 04:53:26 +04:00
|
|
|
|
2016-08-24 08:23:45 +03:00
|
|
|
Unused << mgr->MinimizeMemoryUsage(/* callback = */ nullptr);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-04-26 04:53:26 +04:00
|
|
|
}
|
|
|
|
|
2013-12-13 20:28:46 +04:00
|
|
|
void ContentChild::AddIdleObserver(nsIObserver* aObserver,
|
|
|
|
uint32_t aIdleTimeInS) {
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(aObserver, "null idle observer");
|
|
|
|
// Make sure aObserver isn't released while we wait for the parent
|
|
|
|
aObserver->AddRef();
|
|
|
|
SendAddIdleObserver(reinterpret_cast<uint64_t>(aObserver), aIdleTimeInS);
|
|
|
|
mIdleObservers.PutEntry(aObserver);
|
2013-12-13 20:28:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void ContentChild::RemoveIdleObserver(nsIObserver* aObserver,
|
|
|
|
uint32_t aIdleTimeInS) {
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(aObserver, "null idle observer");
|
|
|
|
SendRemoveIdleObserver(reinterpret_cast<uint64_t>(aObserver), aIdleTimeInS);
|
|
|
|
aObserver->Release();
|
|
|
|
mIdleObservers.RemoveEntry(aObserver);
|
2013-12-13 20:28:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvNotifyIdleObserver(
|
|
|
|
const uint64_t& aObserver, const nsCString& aTopic,
|
|
|
|
const nsString& aTimeStr) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsIObserver* observer = reinterpret_cast<nsIObserver*>(aObserver);
|
|
|
|
if (mIdleObservers.Contains(observer)) {
|
|
|
|
observer->Observe(nullptr, aTopic.get(), aTimeStr.get());
|
|
|
|
} else {
|
|
|
|
NS_WARNING("Received notification for an idle observer that was removed.");
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-12-13 20:28:46 +04:00
|
|
|
}
|
|
|
|
|
2013-08-27 21:10:39 +04:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvLoadAndRegisterSheet(
|
|
|
|
const URIParams& aURI, const uint32_t& aType) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
|
|
|
if (!uri) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2013-08-27 21:10:39 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
|
|
|
|
if (sheetService) {
|
|
|
|
sheetService->LoadAndRegisterSheet(uri, aType);
|
|
|
|
}
|
2013-08-27 21:10:39 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-08-27 21:10:39 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUnregisterSheet(
|
|
|
|
const URIParams& aURI, const uint32_t& aType) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
|
|
|
if (!uri) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2013-08-27 21:10:39 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
|
|
|
|
if (sheetService) {
|
|
|
|
sheetService->UnregisterSheet(uri, aType);
|
|
|
|
}
|
2013-08-27 21:10:39 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-08-27 21:10:39 +04:00
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvDomainSetChanged(
|
|
|
|
const uint32_t& aSetType, const uint32_t& aChangeType,
|
2019-03-06 17:05:50 +03:00
|
|
|
const Maybe<URIParams>& aDomain) {
|
2016-01-05 12:59:30 +03:00
|
|
|
if (aChangeType == ACTIVATE_POLICY) {
|
|
|
|
if (mPolicy) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
|
|
|
MOZ_ASSERT(ssm);
|
|
|
|
ssm->ActivateDomainPolicyInternal(getter_AddRefs(mPolicy));
|
2016-11-15 06:26:00 +03:00
|
|
|
if (!mPolicy) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
2017-02-09 12:31:03 +03:00
|
|
|
}
|
|
|
|
if (!mPolicy) {
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE(
|
|
|
|
"If the domain policy is not active yet,"
|
|
|
|
" the first message should be ACTIVATE_POLICY");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-03-24 17:29:16 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_TRUE(mPolicy, IPC_FAIL_NO_REASON(this));
|
2015-03-24 17:29:16 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (aChangeType == DEACTIVATE_POLICY) {
|
|
|
|
mPolicy->Deactivate();
|
|
|
|
mPolicy = nullptr;
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-03-24 17:29:16 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIDomainSet> set;
|
|
|
|
switch (aSetType) {
|
2018-10-31 20:56:43 +03:00
|
|
|
case BLOCKLIST:
|
|
|
|
mPolicy->GetBlocklist(getter_AddRefs(set));
|
2016-01-05 12:59:30 +03:00
|
|
|
break;
|
2018-10-31 20:56:43 +03:00
|
|
|
case SUPER_BLOCKLIST:
|
|
|
|
mPolicy->GetSuperBlocklist(getter_AddRefs(set));
|
2016-01-05 12:59:30 +03:00
|
|
|
break;
|
2018-10-31 20:56:43 +03:00
|
|
|
case ALLOWLIST:
|
|
|
|
mPolicy->GetAllowlist(getter_AddRefs(set));
|
2016-01-05 12:59:30 +03:00
|
|
|
break;
|
2018-10-31 20:56:43 +03:00
|
|
|
case SUPER_ALLOWLIST:
|
|
|
|
mPolicy->GetSuperAllowlist(getter_AddRefs(set));
|
2016-01-05 12:59:30 +03:00
|
|
|
break;
|
|
|
|
default:
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("Unexpected setType");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-03-24 17:29:16 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(set);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri = DeserializeURI(aDomain);
|
|
|
|
|
|
|
|
switch (aChangeType) {
|
|
|
|
case ADD_DOMAIN:
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_TRUE(uri, IPC_FAIL_NO_REASON(this));
|
2016-01-05 12:59:30 +03:00
|
|
|
set->Add(uri);
|
|
|
|
break;
|
|
|
|
case REMOVE_DOMAIN:
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_TRUE(uri, IPC_FAIL_NO_REASON(this));
|
2016-01-05 12:59:30 +03:00
|
|
|
set->Remove(uri);
|
|
|
|
break;
|
|
|
|
case CLEAR_DOMAINS:
|
|
|
|
set->Clear();
|
|
|
|
break;
|
|
|
|
default:
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("Unexpected changeType");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-03-24 17:29:16 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-03-24 17:29:16 +03:00
|
|
|
}
|
|
|
|
|
2016-06-02 15:52:17 +03:00
|
|
|
void ContentChild::StartForceKillTimer() {
|
|
|
|
if (mForceKillTimer) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-11-06 16:51:21 +03:00
|
|
|
int32_t timeoutSecs = StaticPrefs::dom_ipc_tabs_shutdownTimeoutSecs();
|
2016-06-02 15:52:17 +03:00
|
|
|
if (timeoutSecs > 0) {
|
2017-10-16 09:15:40 +03:00
|
|
|
NS_NewTimerWithFuncCallback(getter_AddRefs(mForceKillTimer),
|
|
|
|
ContentChild::ForceKillTimerCallback, this,
|
|
|
|
timeoutSecs * 1000, nsITimer::TYPE_ONE_SHOT,
|
|
|
|
"dom::ContentChild::StartForceKillTimer");
|
2016-06-02 15:52:17 +03:00
|
|
|
MOZ_ASSERT(mForceKillTimer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:05:29 +03:00
|
|
|
/* static */
|
|
|
|
void ContentChild::ForceKillTimerCallback(nsITimer* aTimer, void* aClosure) {
|
2016-06-02 15:52:17 +03:00
|
|
|
ProcessChild::QuickExit();
|
|
|
|
}
|
|
|
|
|
2015-01-10 21:18:59 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvShutdown() {
|
2018-01-28 10:41:36 +03:00
|
|
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
|
|
|
if (os) {
|
2019-02-25 23:04:55 +03:00
|
|
|
os->NotifyObservers(this, "content-child-will-shutdown", nullptr);
|
2018-01-28 10:41:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
ShutdownInternal();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentChild::ShutdownInternal() {
|
2018-03-22 02:22:57 +03:00
|
|
|
// If we receive the shutdown message from within a nested event loop, we want
|
|
|
|
// to wait for that event loop to finish. Otherwise we could prematurely
|
|
|
|
// terminate an "unload" or "pagehide" event handler (which might be doing a
|
2018-04-09 21:50:22 +03:00
|
|
|
// sync XHR, for example).
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
CrashReporter::AnnotateCrashReport(
|
|
|
|
CrashReporter::Annotation::IPCShutdownState,
|
|
|
|
NS_LITERAL_CSTRING("RecvShutdown"));
|
2018-04-09 21:50:22 +03:00
|
|
|
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
RefPtr<nsThread> mainThread = nsThreadManager::get().GetCurrentThread();
|
2017-07-20 02:08:46 +03:00
|
|
|
// Note that we only have to check the recursion count for the current
|
|
|
|
// cooperative thread. Since the Shutdown message is not labeled with a
|
|
|
|
// SchedulerGroup, there can be no other cooperative threads doing work while
|
|
|
|
// we're running.
|
2018-04-09 21:50:22 +03:00
|
|
|
if (mainThread && mainThread->RecursionDepth() > 1) {
|
2017-07-20 02:08:46 +03:00
|
|
|
// We're in a nested event loop. Let's delay for an arbitrary period of
|
|
|
|
// time (100ms) in the hopes that the event loop will have finished by
|
|
|
|
// then.
|
|
|
|
MessageLoop::current()->PostDelayedTask(
|
2018-01-28 10:41:36 +03:00
|
|
|
NewRunnableMethod("dom::ContentChild::RecvShutdown", this,
|
|
|
|
&ContentChild::ShutdownInternal),
|
2018-04-09 21:50:22 +03:00
|
|
|
100);
|
2018-01-28 10:41:36 +03:00
|
|
|
return;
|
2016-06-04 03:22:08 +03:00
|
|
|
}
|
|
|
|
|
2016-09-03 02:23:00 +03:00
|
|
|
mShuttingDown = true;
|
|
|
|
|
2017-08-09 23:59:27 +03:00
|
|
|
#ifdef NIGHTLY_BUILD
|
2018-04-30 04:21:20 +03:00
|
|
|
BackgroundHangMonitor::UnregisterAnnotator(
|
|
|
|
PendingInputEventHangAnnotator::sSingleton);
|
2017-08-09 23:59:27 +03:00
|
|
|
#endif
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (mPolicy) {
|
|
|
|
mPolicy->Deactivate();
|
|
|
|
mPolicy = nullptr;
|
|
|
|
}
|
2015-03-24 17:29:16 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
|
|
|
if (os) {
|
2019-02-25 23:04:55 +03:00
|
|
|
os->NotifyObservers(this, "content-child-shutdown", nullptr);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-01-10 21:39:33 +03:00
|
|
|
|
2016-03-13 16:25:23 +03:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
mozilla::widget::StopAudioSession();
|
|
|
|
#endif
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
GetIPCChannel()->SetAbortOnError(false);
|
2015-02-13 22:10:56 +03:00
|
|
|
|
2017-01-24 06:15:12 +03:00
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
2017-05-30 22:06:14 +03:00
|
|
|
if (mProfilerController) {
|
|
|
|
nsCString shutdownProfile =
|
|
|
|
mProfilerController->GrabShutdownProfileAndShutdown();
|
|
|
|
mProfilerController = nullptr;
|
|
|
|
// Send the shutdown profile to the parent process through our own
|
|
|
|
// message channel, which we know will survive for long enough.
|
|
|
|
Unused << SendShutdownProfile(shutdownProfile);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-08-18 21:57:35 +03:00
|
|
|
#endif
|
|
|
|
|
2016-06-02 15:52:17 +03:00
|
|
|
// Start a timer that will insure we quickly exit after a reasonable
|
|
|
|
// period of time. Prevents shutdown hangs after our connection to the
|
|
|
|
// parent closes.
|
|
|
|
StartForceKillTimer();
|
|
|
|
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
CrashReporter::AnnotateCrashReport(
|
|
|
|
CrashReporter::Annotation::IPCShutdownState,
|
|
|
|
NS_LITERAL_CSTRING("SendFinishShutdown (sending)"));
|
2017-10-06 21:50:58 +03:00
|
|
|
bool sent = SendFinishShutdown();
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
CrashReporter::AnnotateCrashReport(
|
|
|
|
CrashReporter::Annotation::IPCShutdownState,
|
2017-10-06 21:50:58 +03:00
|
|
|
sent ? NS_LITERAL_CSTRING("SendFinishShutdown (sent)")
|
|
|
|
: NS_LITERAL_CSTRING("SendFinishShutdown (failed)"));
|
2015-01-10 21:18:59 +03:00
|
|
|
}
|
|
|
|
|
2019-04-10 01:39:01 +03:00
|
|
|
PBrowserOrId ContentChild::GetBrowserOrId(BrowserChild* aBrowserChild) {
|
|
|
|
if (!aBrowserChild || this == aBrowserChild->Manager()) {
|
|
|
|
return PBrowserOrId(aBrowserChild);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2019-04-10 01:39:01 +03:00
|
|
|
return PBrowserOrId(aBrowserChild->GetTabId());
|
2014-11-04 04:58:00 +03:00
|
|
|
}
|
|
|
|
|
2015-04-07 16:17:27 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUpdateWindow(
|
|
|
|
const uintptr_t& aChildId) {
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
NS_ASSERTION(aChildId,
|
|
|
|
"Expected child hwnd value for remote plugin instance.");
|
|
|
|
mozilla::plugins::PluginInstanceParent* parentInstance =
|
2016-01-05 12:59:30 +03:00
|
|
|
mozilla::plugins::PluginInstanceParent::LookupPluginInstanceByID(
|
|
|
|
aChildId);
|
2015-04-07 16:17:27 +03:00
|
|
|
if (parentInstance) {
|
2017-09-28 20:46:37 +03:00
|
|
|
// sync! update call to the plugin instance that forces the
|
|
|
|
// plugin to paint its child window.
|
|
|
|
if (!parentInstance->CallUpdateWindow()) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
2015-04-07 16:17:27 +03:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-04-07 16:17:27 +03:00
|
|
|
#else
|
2016-01-08 23:40:26 +03:00
|
|
|
MOZ_ASSERT(
|
|
|
|
false,
|
|
|
|
"ContentChild::RecvUpdateWindow calls unexpected on this platform.");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2015-04-07 16:17:27 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-04-14 04:08:00 +03:00
|
|
|
PContentPermissionRequestChild*
|
|
|
|
ContentChild::AllocPContentPermissionRequestChild(
|
2019-07-10 06:27:27 +03:00
|
|
|
const nsTArray<PermissionRequest>& aRequests,
|
2018-11-20 04:52:47 +03:00
|
|
|
const IPC::Principal& aPrincipal, const IPC::Principal& aTopLevelPrincipal,
|
2019-04-18 16:43:05 +03:00
|
|
|
const bool& aIsHandlingUserInput, const bool& aDocumentHasUserInput,
|
|
|
|
const DOMTimeStamp aPageLoadTimestamp, const TabId& aTabId) {
|
2016-12-03 00:46:53 +03:00
|
|
|
MOZ_CRASH("unused");
|
2016-01-05 12:59:30 +03:00
|
|
|
return nullptr;
|
2015-04-14 04:08:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPContentPermissionRequestChild(
|
|
|
|
PContentPermissionRequestChild* actor) {
|
2016-01-05 12:59:30 +03:00
|
|
|
nsContentPermissionUtils::NotifyRemoveContentPermissionRequestChild(actor);
|
|
|
|
auto child = static_cast<RemotePermissionRequest*>(actor);
|
|
|
|
child->IPDLRelease();
|
|
|
|
return true;
|
2015-04-14 04:08:00 +03:00
|
|
|
}
|
|
|
|
|
2015-09-21 15:54:00 +03:00
|
|
|
PWebBrowserPersistDocumentChild*
|
|
|
|
ContentChild::AllocPWebBrowserPersistDocumentChild(
|
|
|
|
PBrowserChild* aBrowser, const uint64_t& aOuterWindowID) {
|
|
|
|
return new WebBrowserPersistDocumentChild();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvPWebBrowserPersistDocumentConstructor(
|
|
|
|
PWebBrowserPersistDocumentChild* aActor, PBrowserChild* aBrowser,
|
|
|
|
const uint64_t& aOuterWindowID) {
|
|
|
|
if (NS_WARN_IF(!aBrowser)) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2015-09-21 15:54:00 +03:00
|
|
|
}
|
2019-04-13 04:53:10 +03:00
|
|
|
nsCOMPtr<Document> rootDoc =
|
2019-04-10 01:39:01 +03:00
|
|
|
static_cast<BrowserChild*>(aBrowser)->GetTopLevelDocument();
|
2019-01-02 16:05:23 +03:00
|
|
|
nsCOMPtr<Document> foundDoc;
|
2015-09-21 15:54:00 +03:00
|
|
|
if (aOuterWindowID) {
|
|
|
|
foundDoc = nsContentUtils::GetSubdocumentWithOuterWindowId(rootDoc,
|
|
|
|
aOuterWindowID);
|
|
|
|
} else {
|
|
|
|
foundDoc = rootDoc;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!foundDoc) {
|
|
|
|
aActor->SendInitFailure(NS_ERROR_NO_CONTENT);
|
|
|
|
} else {
|
|
|
|
static_cast<WebBrowserPersistDocumentChild*>(aActor)->Start(foundDoc);
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-09-21 15:54:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPWebBrowserPersistDocumentChild(
|
|
|
|
PWebBrowserPersistDocumentChild* aActor) {
|
|
|
|
delete aActor;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-03-13 16:25:23 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSetAudioSessionData(
|
|
|
|
const nsID& aId, const nsString& aDisplayName, const nsString& aIconPath) {
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
if (NS_FAILED(mozilla::widget::RecvAudioSessionData(aId, aDisplayName,
|
|
|
|
aIconPath))) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2016-03-13 16:25:23 +03:00
|
|
|
// Ignore failures here; we can't really do anything about them
|
|
|
|
mozilla::widget::StartAudioSession();
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-03-13 16:25:23 +03:00
|
|
|
#else
|
2017-10-25 09:30:31 +03:00
|
|
|
MOZ_CRASH("Not Reached!");
|
2016-03-13 16:25:23 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-04-08 21:48:11 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvInvokeDragSession(
|
|
|
|
nsTArray<IPCDataTransfer>&& aTransfers, const uint32_t& aAction) {
|
|
|
|
nsCOMPtr<nsIDragService> dragService =
|
|
|
|
do_GetService("@mozilla.org/widget/dragservice;1");
|
|
|
|
if (dragService) {
|
|
|
|
dragService->StartDragSession();
|
|
|
|
nsCOMPtr<nsIDragSession> session;
|
|
|
|
dragService->GetCurrentSession(getter_AddRefs(session));
|
|
|
|
if (session) {
|
|
|
|
session->SetDragAction(aAction);
|
2016-06-21 20:07:17 +03:00
|
|
|
// Check if we are receiving any file objects. If we are we will want
|
|
|
|
// to hide any of the other objects coming in from content.
|
|
|
|
bool hasFiles = false;
|
|
|
|
for (uint32_t i = 0; i < aTransfers.Length() && !hasFiles; ++i) {
|
|
|
|
auto& items = aTransfers[i].items();
|
|
|
|
for (uint32_t j = 0; j < items.Length() && !hasFiles; ++j) {
|
2017-04-24 13:16:50 +03:00
|
|
|
if (items[j].data().type() == IPCDataTransferData::TIPCBlob) {
|
2016-06-21 20:07:17 +03:00
|
|
|
hasFiles = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the entries from the IPC to the new DataTransfer
|
2015-04-08 21:48:11 +03:00
|
|
|
nsCOMPtr<DataTransfer> dataTransfer =
|
2015-09-02 09:08:01 +03:00
|
|
|
new DataTransfer(nullptr, eDragStart, false, -1);
|
2015-04-08 21:48:11 +03:00
|
|
|
for (uint32_t i = 0; i < aTransfers.Length(); ++i) {
|
|
|
|
auto& items = aTransfers[i].items();
|
|
|
|
for (uint32_t j = 0; j < items.Length(); ++j) {
|
|
|
|
const IPCDataTransferItem& item = items[j];
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsVariantCC> variant = new nsVariantCC();
|
2015-04-08 21:48:11 +03:00
|
|
|
if (item.data().type() == IPCDataTransferData::TnsString) {
|
|
|
|
const nsString& data = item.data().get_nsString();
|
|
|
|
variant->SetAsAString(data);
|
2016-06-15 19:57:46 +03:00
|
|
|
} else if (item.data().type() == IPCDataTransferData::TShmem) {
|
|
|
|
Shmem data = item.data().get_Shmem();
|
2018-07-19 23:14:50 +03:00
|
|
|
variant->SetAsACString(
|
|
|
|
nsDependentCSubstring(data.get<char>(), data.Size<char>()));
|
2016-06-15 19:57:46 +03:00
|
|
|
Unused << DeallocShmem(data);
|
2017-04-24 13:16:50 +03:00
|
|
|
} else if (item.data().type() == IPCDataTransferData::TIPCBlob) {
|
|
|
|
RefPtr<BlobImpl> blobImpl =
|
|
|
|
IPCBlobUtils::Deserialize(item.data().get_IPCBlob());
|
2015-05-27 02:07:54 +03:00
|
|
|
variant->SetAsISupports(blobImpl);
|
2015-05-12 18:51:08 +03:00
|
|
|
} else {
|
|
|
|
continue;
|
|
|
|
}
|
2016-06-21 20:07:17 +03:00
|
|
|
// We should hide this data from content if we have a file, and we
|
|
|
|
// aren't a file.
|
2017-04-24 13:16:50 +03:00
|
|
|
bool hidden =
|
|
|
|
hasFiles && item.data().type() != IPCDataTransferData::TIPCBlob;
|
2016-04-21 21:11:14 +03:00
|
|
|
dataTransfer->SetDataWithPrincipalFromOtherProcess(
|
|
|
|
NS_ConvertUTF8toUTF16(item.flavor()), variant, i,
|
2016-06-21 20:07:17 +03:00
|
|
|
nsContentUtils::GetSystemPrincipal(), hidden);
|
2015-05-12 18:51:08 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
session->SetDataTransfer(dataTransfer);
|
|
|
|
}
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-05-12 18:51:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvEndDragSession(
|
2016-05-19 00:17:34 +03:00
|
|
|
const bool& aDoneDrag, const bool& aUserCancelled,
|
2017-02-17 06:29:42 +03:00
|
|
|
const LayoutDeviceIntPoint& aDragEndPoint, const uint32_t& aKeyModifiers) {
|
2015-05-12 18:51:08 +03:00
|
|
|
nsCOMPtr<nsIDragService> dragService =
|
|
|
|
do_GetService("@mozilla.org/widget/dragservice;1");
|
|
|
|
if (dragService) {
|
|
|
|
if (aUserCancelled) {
|
|
|
|
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
|
|
|
|
if (dragSession) {
|
|
|
|
dragSession->UserCancelled();
|
|
|
|
}
|
|
|
|
}
|
2016-05-19 00:17:34 +03:00
|
|
|
static_cast<nsBaseDragService*>(dragService.get())
|
|
|
|
->SetDragEndPoint(aDragEndPoint);
|
2017-02-17 06:29:42 +03:00
|
|
|
dragService->EndDragSession(aDoneDrag, aKeyModifiers);
|
2015-05-12 18:51:08 +03:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-05-12 18:51:08 +03:00
|
|
|
}
|
|
|
|
|
2016-01-14 08:19:51 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvPush(const nsCString& aScope,
|
2016-03-28 21:50:39 +03:00
|
|
|
const IPC::Principal& aPrincipal,
|
|
|
|
const nsString& aMessageId) {
|
2016-05-20 05:01:34 +03:00
|
|
|
PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Nothing());
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-14 08:19:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvPushWithData(
|
|
|
|
const nsCString& aScope, const IPC::Principal& aPrincipal,
|
2019-07-10 06:27:27 +03:00
|
|
|
const nsString& aMessageId, nsTArray<uint8_t>&& aData) {
|
2016-05-20 05:01:34 +03:00
|
|
|
PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Some(aData));
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-14 08:19:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvPushSubscriptionChange(
|
|
|
|
const nsCString& aScope, const IPC::Principal& aPrincipal) {
|
2016-05-20 05:01:34 +03:00
|
|
|
PushSubscriptionChangeDispatcher dispatcher(aScope, aPrincipal);
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-14 08:19:51 +03:00
|
|
|
}
|
|
|
|
|
2016-05-20 05:01:34 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvPushError(
|
|
|
|
const nsCString& aScope, const IPC::Principal& aPrincipal,
|
|
|
|
const nsString& aMessage, const uint32_t& aFlags) {
|
|
|
|
PushErrorDispatcher dispatcher(aScope, aPrincipal, aMessage, aFlags);
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObserversAndWorkers()));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-03-28 23:33:20 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-05-15 02:54:51 +03:00
|
|
|
ContentChild::RecvNotifyPushSubscriptionModifiedObservers(
|
|
|
|
const nsCString& aScope, const IPC::Principal& aPrincipal) {
|
|
|
|
PushSubscriptionModifiedDispatcher dispatcher(aScope, aPrincipal);
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-05-15 02:54:51 +03:00
|
|
|
}
|
|
|
|
|
2017-04-24 13:16:49 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvBlobURLRegistration(
|
|
|
|
const nsCString& aURI, const IPCBlob& aBlob,
|
2016-07-17 17:50:50 +03:00
|
|
|
const IPC::Principal& aPrincipal) {
|
2017-04-24 13:16:49 +03:00
|
|
|
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(aBlob);
|
2016-07-17 17:50:50 +03:00
|
|
|
MOZ_ASSERT(blobImpl);
|
|
|
|
|
2018-06-02 16:51:42 +03:00
|
|
|
BlobURLProtocolHandler::AddDataEntry(aURI, aPrincipal, blobImpl);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-17 17:50:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvBlobURLUnregistration(
|
|
|
|
const nsCString& aURI) {
|
2018-06-02 16:51:42 +03:00
|
|
|
BlobURLProtocolHandler::RemoveDataEntry(
|
|
|
|
aURI,
|
|
|
|
/* aBroadcastToOtherProcesses = */ false);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-17 17:50:50 +03:00
|
|
|
}
|
|
|
|
|
2016-10-27 21:40:50 +03:00
|
|
|
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
|
|
|
bool ContentChild::SendGetA11yContentId() {
|
|
|
|
return PContentChild::SendGetA11yContentId(&mMsaaID);
|
|
|
|
}
|
|
|
|
#endif // defined(XP_WIN) && defined(ACCESSIBILITY)
|
2016-07-17 17:50:50 +03:00
|
|
|
|
2016-07-14 10:04:21 +03:00
|
|
|
void ContentChild::CreateGetFilesRequest(const nsAString& aDirectoryPath,
|
|
|
|
bool aRecursiveFlag, nsID& aUUID,
|
|
|
|
GetFilesHelperChild* aChild) {
|
|
|
|
MOZ_ASSERT(aChild);
|
|
|
|
MOZ_ASSERT(!mGetFilesPendingRequests.GetWeak(aUUID));
|
|
|
|
|
|
|
|
Unused << SendGetFilesRequest(aUUID, nsString(aDirectoryPath),
|
|
|
|
aRecursiveFlag);
|
|
|
|
mGetFilesPendingRequests.Put(aUUID, aChild);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentChild::DeleteGetFilesRequest(nsID& aUUID,
|
|
|
|
GetFilesHelperChild* aChild) {
|
|
|
|
MOZ_ASSERT(aChild);
|
|
|
|
MOZ_ASSERT(mGetFilesPendingRequests.GetWeak(aUUID));
|
|
|
|
|
|
|
|
Unused << SendDeleteGetFilesRequest(aUUID);
|
|
|
|
mGetFilesPendingRequests.Remove(aUUID);
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvGetFilesResponse(
|
|
|
|
const nsID& aUUID, const GetFilesResponseResult& aResult) {
|
|
|
|
GetFilesHelperChild* child = mGetFilesPendingRequests.GetWeak(aUUID);
|
|
|
|
// This object can already been deleted in case DeleteGetFilesRequest has
|
|
|
|
// been called when the response was sending by the parent.
|
|
|
|
if (!child) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-14 10:04:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (aResult.type() == GetFilesResponseResult::TGetFilesResponseFailure) {
|
|
|
|
child->Finished(aResult.get_GetFilesResponseFailure().errorCode());
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(aResult.type() ==
|
|
|
|
GetFilesResponseResult::TGetFilesResponseSuccess);
|
|
|
|
|
2017-04-24 13:16:49 +03:00
|
|
|
const nsTArray<IPCBlob>& ipcBlobs =
|
|
|
|
aResult.get_GetFilesResponseSuccess().blobs();
|
2016-07-14 10:04:21 +03:00
|
|
|
|
|
|
|
bool succeeded = true;
|
2017-04-24 13:16:49 +03:00
|
|
|
for (uint32_t i = 0; succeeded && i < ipcBlobs.Length(); ++i) {
|
|
|
|
RefPtr<BlobImpl> impl = IPCBlobUtils::Deserialize(ipcBlobs[i]);
|
2016-07-14 10:04:21 +03:00
|
|
|
succeeded = child->AppendBlobImpl(impl);
|
|
|
|
}
|
|
|
|
|
|
|
|
child->Finished(succeeded ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
}
|
|
|
|
|
|
|
|
mGetFilesPendingRequests.Remove(aUUID);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-14 10:04:21 +03:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:05:29 +03:00
|
|
|
/* static */
|
|
|
|
void ContentChild::FatalErrorIfNotUsingGPUProcess(const char* const aErrorMsg,
|
|
|
|
base::ProcessId aOtherPid) {
|
2016-10-04 11:31:27 +03:00
|
|
|
// If we're communicating with the same process or the UI process then we
|
|
|
|
// want to crash normally. Otherwise we want to just warn as the other end
|
|
|
|
// must be the GPU process and it crashing shouldn't be fatal for us.
|
|
|
|
if (aOtherPid == base::GetCurrentProcId() ||
|
|
|
|
(GetSingleton() && GetSingleton()->OtherPid() == aOtherPid)) {
|
2018-04-23 21:13:36 +03:00
|
|
|
mozilla::ipc::FatalError(aErrorMsg, false);
|
2016-10-04 11:31:27 +03:00
|
|
|
} else {
|
2018-04-23 21:13:36 +03:00
|
|
|
nsAutoCString formattedMessage("IPDL error: \"");
|
2016-10-04 11:31:27 +03:00
|
|
|
formattedMessage.AppendASCII(aErrorMsg);
|
2016-11-14 12:45:55 +03:00
|
|
|
formattedMessage.AppendLiteral(R"(".)");
|
2016-10-04 11:31:27 +03:00
|
|
|
NS_WARNING(formattedMessage.get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-19 00:54:57 +03:00
|
|
|
PURLClassifierChild* ContentChild::AllocPURLClassifierChild(
|
2019-01-18 00:24:43 +03:00
|
|
|
const Principal& aPrincipal, bool* aSuccess) {
|
2016-11-19 00:54:57 +03:00
|
|
|
*aSuccess = true;
|
|
|
|
return new URLClassifierChild();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPURLClassifierChild(PURLClassifierChild* aActor) {
|
|
|
|
MOZ_ASSERT(aActor);
|
|
|
|
delete aActor;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-04-07 09:15:16 +03:00
|
|
|
PURLClassifierLocalChild* ContentChild::AllocPURLClassifierLocalChild(
|
2018-12-14 14:40:17 +03:00
|
|
|
const URIParams& aUri, const nsTArray<IPCURLClassifierFeature>& aFeatures) {
|
2017-04-07 09:15:16 +03:00
|
|
|
return new URLClassifierLocalChild();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPURLClassifierLocalChild(
|
|
|
|
PURLClassifierLocalChild* aActor) {
|
|
|
|
MOZ_ASSERT(aActor);
|
|
|
|
delete aActor;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-12-07 11:32:52 +03:00
|
|
|
PLoginReputationChild* ContentChild::AllocPLoginReputationChild(
|
|
|
|
const URIParams& aUri) {
|
|
|
|
return new PLoginReputationChild();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPLoginReputationChild(PLoginReputationChild* aActor) {
|
|
|
|
MOZ_ASSERT(aActor);
|
|
|
|
delete aActor;
|
2019-02-06 08:09:57 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
PSessionStorageObserverChild*
|
|
|
|
ContentChild::AllocPSessionStorageObserverChild() {
|
|
|
|
MOZ_CRASH(
|
|
|
|
"PSessionStorageObserverChild actors should be manually constructed!");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPSessionStorageObserverChild(
|
|
|
|
PSessionStorageObserverChild* aActor) {
|
|
|
|
MOZ_ASSERT(aActor);
|
|
|
|
|
|
|
|
delete aActor;
|
2017-12-07 11:32:52 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-03-05 17:46:10 +03:00
|
|
|
PSHEntryChild* ContentChild::AllocPSHEntryChild(
|
2019-10-17 21:03:49 +03:00
|
|
|
PSHistoryChild* aSHistory, const PSHEntryOrSharedID& aEntryOrSharedID) {
|
2019-03-05 17:46:10 +03:00
|
|
|
// We take a strong reference for the IPC layer. The Release implementation
|
|
|
|
// for SHEntryChild will ask the IPC layer to release it (through
|
|
|
|
// DeallocPSHEntryChild) if that is the only remaining reference.
|
|
|
|
RefPtr<SHEntryChild> child;
|
|
|
|
if (aEntryOrSharedID.type() == PSHEntryOrSharedID::Tuint64_t) {
|
2019-10-24 10:17:19 +03:00
|
|
|
child = new SHEntryChild(static_cast<SHistoryChild*>(aSHistory),
|
|
|
|
aEntryOrSharedID.get_uint64_t());
|
2019-03-05 17:46:10 +03:00
|
|
|
} else {
|
|
|
|
child = new SHEntryChild(
|
|
|
|
static_cast<const SHEntryChild*>(aEntryOrSharedID.get_PSHEntryChild()));
|
|
|
|
}
|
|
|
|
return child.forget().take();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentChild::DeallocPSHEntryChild(PSHEntryChild* aActor) {
|
|
|
|
// Release the strong reference we took in AllocPSHEntryChild for the IPC
|
|
|
|
// layer.
|
|
|
|
RefPtr<SHEntryChild> child(dont_AddRef(static_cast<SHEntryChild*>(aActor)));
|
|
|
|
}
|
|
|
|
|
|
|
|
PSHistoryChild* ContentChild::AllocPSHistoryChild(BrowsingContext* aContext) {
|
|
|
|
// We take a strong reference for the IPC layer. The Release implementation
|
|
|
|
// for SHistoryChild will ask the IPC layer to release it (through
|
|
|
|
// DeallocPSHistoryChild) if that is the only remaining reference.
|
|
|
|
return do_AddRef(new SHistoryChild(aContext)).take();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ContentChild::DeallocPSHistoryChild(PSHistoryChild* aActor) {
|
|
|
|
// Release the strong reference we took in AllocPSHistoryChild for the IPC
|
|
|
|
// layer.
|
|
|
|
RefPtr<SHistoryChild> child(dont_AddRef(static_cast<SHistoryChild*>(aActor)));
|
|
|
|
}
|
|
|
|
|
2017-01-21 07:11:35 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvActivate(PBrowserChild* aTab) {
|
2019-04-10 01:39:01 +03:00
|
|
|
BrowserChild* tab = static_cast<BrowserChild*>(aTab);
|
2017-01-21 07:11:35 +03:00
|
|
|
return tab->RecvActivate();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvDeactivate(PBrowserChild* aTab) {
|
2019-04-10 01:39:01 +03:00
|
|
|
BrowserChild* tab = static_cast<BrowserChild*>(aTab);
|
2017-01-21 07:11:35 +03:00
|
|
|
return tab->RecvDeactivate();
|
|
|
|
}
|
|
|
|
|
2017-03-14 02:06:04 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvProvideAnonymousTemporaryFile(
|
|
|
|
const uint64_t& aID, const FileDescOrError& aFDOrError) {
|
|
|
|
nsAutoPtr<AnonymousTemporaryFileCallback> callback;
|
2017-07-05 03:01:45 +03:00
|
|
|
mPendingAnonymousTemporaryFiles.Remove(aID, &callback);
|
2017-03-14 02:06:04 +03:00
|
|
|
MOZ_ASSERT(callback);
|
|
|
|
|
|
|
|
PRFileDesc* prfile = nullptr;
|
|
|
|
if (aFDOrError.type() == FileDescOrError::Tnsresult) {
|
|
|
|
DebugOnly<nsresult> rv = aFDOrError.get_nsresult();
|
|
|
|
MOZ_ASSERT(NS_FAILED(rv));
|
|
|
|
} else {
|
|
|
|
auto rawFD = aFDOrError.get_FileDescriptor().ClonePlatformHandle();
|
|
|
|
prfile = PR_ImportFile(PROsfd(rawFD.release()));
|
|
|
|
}
|
|
|
|
(*callback)(prfile);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-04-27 19:44:57 +03:00
|
|
|
nsresult ContentChild::AsyncOpenAnonymousTemporaryFile(
|
|
|
|
const AnonymousTemporaryFileCallback& aCallback) {
|
2017-03-14 02:06:04 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
static uint64_t id = 0;
|
|
|
|
auto newID = id++;
|
|
|
|
if (!SendRequestAnonymousTemporaryFile(newID)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remember the association with the callback.
|
|
|
|
MOZ_ASSERT(!mPendingAnonymousTemporaryFiles.Get(newID));
|
|
|
|
mPendingAnonymousTemporaryFiles.LookupOrAdd(newID, aCallback);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-03-03 00:53:33 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSetPermissionsWithKey(
|
|
|
|
const nsCString& aPermissionKey, nsTArray<IPC::Permission>&& aPerms) {
|
|
|
|
nsCOMPtr<nsIPermissionManager> permissionManager =
|
|
|
|
services::GetPermissionManager();
|
|
|
|
permissionManager->SetPermissionsWithKey(aPermissionKey, aPerms);
|
2017-03-09 14:30:26 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-03-03 00:53:33 +03:00
|
|
|
|
2017-03-09 14:30:26 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRefreshScreens(
|
|
|
|
nsTArray<ScreenDetails>&& aScreens) {
|
|
|
|
ScreenManager& screenManager = ScreenManager::GetSingleton();
|
2018-05-30 22:15:35 +03:00
|
|
|
screenManager.Refresh(std::move(aScreens));
|
2017-03-03 00:53:33 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-03-14 02:06:04 +03:00
|
|
|
|
2017-05-02 12:57:51 +03:00
|
|
|
already_AddRefed<nsIEventTarget> ContentChild::GetEventTargetFor(
|
2019-04-10 01:39:01 +03:00
|
|
|
BrowserChild* aBrowserChild) {
|
|
|
|
return IToplevelProtocol::GetActorEventTarget(aBrowserChild);
|
2017-05-02 12:57:51 +03:00
|
|
|
}
|
|
|
|
|
2017-06-06 20:39:46 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSetPluginList(
|
|
|
|
const uint32_t& aPluginEpoch, nsTArray<plugins::PluginTag>&& aPluginTags,
|
|
|
|
nsTArray<plugins::FakePluginTag>&& aFakePluginTags) {
|
|
|
|
RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
|
|
|
host->SetPluginsInContent(aPluginEpoch, aPluginTags, aFakePluginTags);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-11-01 20:19:38 +03:00
|
|
|
PClientOpenWindowOpChild* ContentChild::AllocPClientOpenWindowOpChild(
|
|
|
|
const ClientOpenWindowArgs& aArgs) {
|
|
|
|
return AllocClientOpenWindowOpChild();
|
|
|
|
}
|
|
|
|
|
|
|
|
IPCResult ContentChild::RecvPClientOpenWindowOpConstructor(
|
|
|
|
PClientOpenWindowOpChild* aActor, const ClientOpenWindowArgs& aArgs) {
|
|
|
|
InitClientOpenWindowOpChild(aActor, aArgs);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ContentChild::DeallocPClientOpenWindowOpChild(
|
|
|
|
PClientOpenWindowOpChild* aActor) {
|
|
|
|
return DeallocClientOpenWindowOpChild(aActor);
|
|
|
|
}
|
|
|
|
|
2017-06-14 11:50:44 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvShareCodeCoverageMutex(
|
|
|
|
const CrossProcessMutexHandle& aHandle) {
|
|
|
|
#ifdef MOZ_CODE_COVERAGE
|
|
|
|
CodeCoverageHandler::Init(aHandle);
|
|
|
|
return IPC_OK();
|
|
|
|
#else
|
2017-10-25 09:30:31 +03:00
|
|
|
MOZ_CRASH("Shouldn't receive this message in non-code coverage builds!");
|
2017-06-14 11:50:44 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-10-15 11:36:45 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvFlushCodeCoverageCounters(
|
|
|
|
FlushCodeCoverageCountersResolver&& aResolver) {
|
2017-07-14 11:57:22 +03:00
|
|
|
#ifdef MOZ_CODE_COVERAGE
|
2018-10-15 11:36:45 +03:00
|
|
|
CodeCoverageHandler::FlushCounters();
|
2018-06-22 16:31:59 +03:00
|
|
|
aResolver(/* unused */ true);
|
2017-07-14 11:57:22 +03:00
|
|
|
return IPC_OK();
|
|
|
|
#else
|
2017-10-25 09:30:31 +03:00
|
|
|
MOZ_CRASH("Shouldn't receive this message in non-code coverage builds!");
|
2017-07-14 11:57:22 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-12-05 23:44:53 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvGetMemoryUniqueSetSize(
|
|
|
|
GetMemoryUniqueSetSizeResolver&& aResolver) {
|
|
|
|
MemoryTelemetry::Get().GetUniqueSetSize(std::move(aResolver));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-07-28 10:14:54 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSetInputEventQueueEnabled() {
|
|
|
|
nsThreadManager::get().EnableMainThreadEventPrioritization();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvFlushInputEventQueue() {
|
|
|
|
nsThreadManager::get().FlushInputEventPrioritization();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSuspendInputEventQueue() {
|
|
|
|
nsThreadManager::get().SuspendInputEventPrioritization();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvResumeInputEventQueue() {
|
|
|
|
nsThreadManager::get().ResumeInputEventPrioritization();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-08-29 14:05:40 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvAddDynamicScalars(
|
|
|
|
nsTArray<DynamicScalarDefinition>&& aDefs) {
|
|
|
|
TelemetryIPC::AddDynamicScalarDefinitions(aDefs);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-07-22 14:52:42 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvSaveRecording(
|
|
|
|
const FileDescriptor& aFile) {
|
|
|
|
recordreplay::parent::SaveRecording(aFile);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-01-24 00:27:44 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvCrossProcessRedirect(
|
2019-08-06 09:11:58 +03:00
|
|
|
const uint32_t& aRegistrarId, nsIURI* aURI,
|
2019-11-07 01:37:07 +03:00
|
|
|
const Maybe<ReplacementChannelConfigInit>& aConfig,
|
2019-03-04 09:30:00 +03:00
|
|
|
const Maybe<LoadInfoArgs>& aLoadInfo, const uint64_t& aChannelId,
|
2019-05-02 23:46:34 +03:00
|
|
|
nsIURI* aOriginalURI, const uint64_t& aIdentifier,
|
2019-09-21 14:14:49 +03:00
|
|
|
const uint32_t& aRedirectMode, CrossProcessRedirectResolver&& aResolve) {
|
2019-01-24 00:27:44 +03:00
|
|
|
nsCOMPtr<nsILoadInfo> loadInfo;
|
|
|
|
nsresult rv =
|
|
|
|
mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfo, getter_AddRefs(loadInfo));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "LoadInfoArgsToLoadInfo failed");
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIChannel> newChannel;
|
2019-08-06 09:11:58 +03:00
|
|
|
rv = NS_NewChannelInternal(getter_AddRefs(newChannel), aURI, loadInfo);
|
2019-01-24 00:27:44 +03:00
|
|
|
|
2019-11-07 01:37:07 +03:00
|
|
|
RefPtr<nsIChildChannel> childChannel = do_QueryObject(newChannel);
|
|
|
|
if (NS_FAILED(rv) || !childChannel) {
|
2019-01-24 00:27:44 +03:00
|
|
|
MOZ_DIAGNOSTIC_ASSERT(false, "NS_NewChannelInternal failed");
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is used to report any errors back to the parent by calling
|
|
|
|
// CrossProcessRedirectFinished.
|
2019-11-07 01:37:07 +03:00
|
|
|
RefPtr<HttpChannelChild> httpChild = do_QueryObject(newChannel);
|
2019-09-21 14:14:49 +03:00
|
|
|
auto scopeExit = MakeScopeExit([&]() {
|
2019-11-07 01:37:07 +03:00
|
|
|
if (httpChild) {
|
|
|
|
rv = httpChild->CrossProcessRedirectFinished(rv);
|
|
|
|
}
|
2019-09-21 14:14:49 +03:00
|
|
|
nsCOMPtr<nsILoadInfo> loadInfo;
|
|
|
|
MOZ_ALWAYS_SUCCEEDS(newChannel->GetLoadInfo(getter_AddRefs(loadInfo)));
|
|
|
|
Maybe<LoadInfoArgs> loadInfoArgs;
|
|
|
|
MOZ_ALWAYS_SUCCEEDS(
|
|
|
|
mozilla::ipc::LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs));
|
|
|
|
aResolve(
|
|
|
|
Tuple<const nsresult&, const Maybe<LoadInfoArgs>&>(rv, loadInfoArgs));
|
|
|
|
});
|
2019-01-24 00:27:44 +03:00
|
|
|
|
2019-11-07 01:37:07 +03:00
|
|
|
if (httpChild) {
|
|
|
|
rv = httpChild->SetChannelId(aChannelId);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2019-01-24 00:27:44 +03:00
|
|
|
|
2019-11-07 01:37:07 +03:00
|
|
|
rv = httpChild->SetOriginalURI(aOriginalURI);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2019-05-02 23:46:34 +03:00
|
|
|
|
2019-11-07 01:37:07 +03:00
|
|
|
rv = httpChild->SetRedirectMode(aRedirectMode);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2019-11-06 21:22:47 +03:00
|
|
|
}
|
2019-08-06 09:11:58 +03:00
|
|
|
|
2019-11-07 01:37:07 +03:00
|
|
|
if (aConfig) {
|
|
|
|
HttpBaseChannel::ReplacementChannelConfig config(*aConfig);
|
|
|
|
HttpBaseChannel::ConfigureReplacementChannel(
|
|
|
|
newChannel, config,
|
|
|
|
HttpBaseChannel::ConfigureReason::DocumentChannelReplacement);
|
|
|
|
}
|
2019-11-07 01:32:53 +03:00
|
|
|
|
2019-01-24 00:27:44 +03:00
|
|
|
// connect parent.
|
2019-11-07 01:37:07 +03:00
|
|
|
rv = childChannel->ConnectParent(aRegistrarId); // creates parent channel
|
2019-01-24 00:27:44 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIChildProcessChannelListener> processListener =
|
|
|
|
do_GetService("@mozilla.org/network/childProcessChannelListener;1");
|
|
|
|
// The listener will call completeRedirectSetup on the channel.
|
2019-11-07 01:37:07 +03:00
|
|
|
rv = processListener->OnChannelReady(childChannel, aIdentifier);
|
2019-01-24 00:27:44 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
// scopeExit will call CrossProcessRedirectFinished(rv) here
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-03-20 06:15:36 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvStartDelayedAutoplayMediaComponents(
|
|
|
|
BrowsingContext* aContext) {
|
|
|
|
MOZ_ASSERT(aContext);
|
|
|
|
aContext->StartDelayedAutoplayMediaComponents();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-08-07 04:46:03 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvUpdateMediaAction(
|
|
|
|
BrowsingContext* aContext, MediaControlActions aAction) {
|
|
|
|
MOZ_ASSERT(aContext);
|
2019-11-01 00:22:33 +03:00
|
|
|
MediaActionHandler::UpdateMediaAction(aContext, aAction);
|
2019-08-07 04:46:03 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-03-05 17:46:10 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvDestroySHEntrySharedState(
|
|
|
|
const uint64_t& aID) {
|
|
|
|
SHEntryChildShared::Remove(aID);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-05-07 21:18:00 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvEvictContentViewers(
|
|
|
|
nsTArray<uint64_t>&& aToEvictSharedStateIDs) {
|
|
|
|
SHEntryChildShared::EvictContentViewers(std::move(aToEvictSharedStateIDs));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-06-15 00:28:01 +03:00
|
|
|
already_AddRefed<nsIEventTarget> ContentChild::GetSpecificMessageEventTarget(
|
|
|
|
const Message& aMsg) {
|
2017-08-24 05:16:05 +03:00
|
|
|
switch (aMsg.type()) {
|
2017-09-15 19:20:08 +03:00
|
|
|
// Javascript
|
2017-08-24 05:16:05 +03:00
|
|
|
case PJavaScript::Msg_DropTemporaryStrongReferences__ID:
|
|
|
|
case PJavaScript::Msg_DropObject__ID:
|
2017-09-15 19:20:08 +03:00
|
|
|
|
|
|
|
// Navigation
|
2017-08-24 05:16:05 +03:00
|
|
|
case PContent::Msg_NotifyVisited__ID:
|
2017-09-15 19:20:08 +03:00
|
|
|
|
|
|
|
// Storage API
|
2017-08-24 05:16:05 +03:00
|
|
|
case PContent::Msg_DataStoragePut__ID:
|
|
|
|
case PContent::Msg_DataStorageRemove__ID:
|
|
|
|
case PContent::Msg_DataStorageClear__ID:
|
2017-09-15 19:20:08 +03:00
|
|
|
|
|
|
|
// Blob and BlobURL
|
2017-08-28 12:54:48 +03:00
|
|
|
case PContent::Msg_BlobURLRegistration__ID:
|
|
|
|
case PContent::Msg_BlobURLUnregistration__ID:
|
2017-09-15 19:20:08 +03:00
|
|
|
case PContent::Msg_InitBlobURLs__ID:
|
|
|
|
case PContent::Msg_PIPCBlobInputStreamConstructor__ID:
|
|
|
|
case PContent::Msg_StoreAndBroadcastBlobURLRegistration__ID:
|
|
|
|
|
2017-08-24 05:16:05 +03:00
|
|
|
return do_AddRef(SystemGroup::EventTargetFor(TaskCategory::Other));
|
2017-09-15 19:20:08 +03:00
|
|
|
|
2019-04-17 03:51:38 +03:00
|
|
|
// PBrowserChild Construction
|
|
|
|
case PContent::Msg_ConstructBrowser__ID: {
|
|
|
|
// Deserialize the arguments for this message to get the endpoint and
|
|
|
|
// `sameTabGroupAs`. The endpoint is needed to set up the event target for
|
|
|
|
// our newly created actor, and sameTabGroupAs is needed to determine if
|
|
|
|
// we're going to join an existing TabGroup.
|
|
|
|
ManagedEndpoint<PBrowserChild> endpoint;
|
2019-08-08 19:07:05 +03:00
|
|
|
ManagedEndpoint<PWindowGlobalChild> windowGlobalEndpoint;
|
2019-04-17 03:51:38 +03:00
|
|
|
TabId tabId, sameTabGroupAs;
|
|
|
|
PickleIterator iter(aMsg);
|
|
|
|
if (NS_WARN_IF(!IPC::ReadParam(&aMsg, &iter, &endpoint))) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
aMsg.IgnoreSentinel(&iter);
|
2019-08-08 19:07:05 +03:00
|
|
|
if (NS_WARN_IF(!IPC::ReadParam(&aMsg, &iter, &windowGlobalEndpoint))) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
aMsg.IgnoreSentinel(&iter);
|
2019-04-17 03:51:38 +03:00
|
|
|
if (NS_WARN_IF(!IPC::ReadParam(&aMsg, &iter, &tabId))) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
aMsg.IgnoreSentinel(&iter);
|
|
|
|
if (NS_WARN_IF(!IPC::ReadParam(&aMsg, &iter, &sameTabGroupAs))) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If sameTabGroupAs is non-zero, then the new tab will be in the same
|
|
|
|
// TabGroup as a previously created tab. Rather than try to find the
|
|
|
|
// previously created tab (whose constructor message may not even have
|
|
|
|
// been processed yet, in theory) and look up its event target, we just
|
|
|
|
// use the default event target. This means that runnables for this tab
|
|
|
|
// will not be labeled. However, this path is only taken for print preview
|
|
|
|
// and view source, which are not performance-sensitive.
|
|
|
|
if (sameTabGroupAs) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_WARN_IF(!endpoint.IsValid())) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2019-04-10 01:39:01 +03:00
|
|
|
// If the request for a new BrowserChild is coming from the parent
|
|
|
|
// process, then there is no opener. Therefore, we create a fresh
|
|
|
|
// TabGroup.
|
2019-04-17 03:51:38 +03:00
|
|
|
RefPtr<TabGroup> tabGroup = new TabGroup();
|
|
|
|
nsCOMPtr<nsIEventTarget> target =
|
|
|
|
tabGroup->EventTargetFor(TaskCategory::Other);
|
|
|
|
|
|
|
|
// Set this event target for our newly created entry, and use it for this
|
|
|
|
// message.
|
|
|
|
SetEventTargetForRoute(*endpoint.ActorId(), target);
|
|
|
|
|
|
|
|
return target.forget();
|
|
|
|
}
|
|
|
|
|
2017-08-24 05:16:05 +03:00
|
|
|
default:
|
|
|
|
return nullptr;
|
2017-06-15 00:28:01 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-09 23:59:27 +03:00
|
|
|
void ContentChild::OnChannelReceivedMessage(const Message& aMsg) {
|
2018-12-19 14:38:23 +03:00
|
|
|
if (aMsg.is_sync() && !aMsg.is_reply()) {
|
|
|
|
LSObject::OnSyncMessageReceived();
|
2018-11-29 23:47:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef NIGHTLY_BUILD
|
2017-08-09 23:59:27 +03:00
|
|
|
if (nsContentUtils::IsMessageInputEvent(aMsg)) {
|
|
|
|
mPendingInputEvents++;
|
|
|
|
}
|
2018-11-29 23:47:20 +03:00
|
|
|
#endif
|
2017-08-09 23:59:27 +03:00
|
|
|
}
|
|
|
|
|
2018-11-29 23:47:20 +03:00
|
|
|
#ifdef NIGHTLY_BUILD
|
2017-08-09 23:59:27 +03:00
|
|
|
PContentChild::Result ContentChild::OnMessageReceived(const Message& aMsg) {
|
|
|
|
if (nsContentUtils::IsMessageInputEvent(aMsg)) {
|
|
|
|
DebugOnly<uint32_t> prevEvts = mPendingInputEvents--;
|
|
|
|
MOZ_ASSERT(prevEvts > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return PContentChild::OnMessageReceived(aMsg);
|
|
|
|
}
|
2018-12-19 14:38:23 +03:00
|
|
|
#endif
|
2017-08-09 23:59:27 +03:00
|
|
|
|
|
|
|
PContentChild::Result ContentChild::OnMessageReceived(const Message& aMsg,
|
|
|
|
Message*& aReply) {
|
2018-12-19 14:38:23 +03:00
|
|
|
Result result = PContentChild::OnMessageReceived(aMsg, aReply);
|
|
|
|
|
|
|
|
if (aMsg.is_sync()) {
|
|
|
|
// OnMessageReceived shouldn't be called for sync replies.
|
|
|
|
MOZ_ASSERT(!aMsg.is_reply());
|
|
|
|
|
|
|
|
LSObject::OnSyncMessageHandled();
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
2017-08-09 23:59:27 +03:00
|
|
|
}
|
|
|
|
|
2019-03-14 21:50:38 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvAttachBrowsingContext(
|
2019-03-14 21:51:09 +03:00
|
|
|
BrowsingContext::IPCInitializer&& aInit) {
|
|
|
|
RefPtr<BrowsingContext> child = BrowsingContext::Get(aInit.mId);
|
2019-03-14 21:50:38 +03:00
|
|
|
MOZ_RELEASE_ASSERT(!child || child->IsCached());
|
|
|
|
|
|
|
|
if (!child) {
|
2019-03-14 21:51:09 +03:00
|
|
|
// Determine the BrowsingContextGroup from our parent or opener fields.
|
|
|
|
RefPtr<BrowsingContextGroup> group =
|
|
|
|
BrowsingContextGroup::Select(aInit.mParentId, aInit.mOpenerId);
|
|
|
|
child = BrowsingContext::CreateFromIPC(std::move(aInit), group, nullptr);
|
2019-03-14 21:50:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
child->Attach(/* aFromIPC */ true);
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvDetachBrowsingContext(
|
2019-07-15 23:44:50 +03:00
|
|
|
uint64_t aContextId, DetachBrowsingContextResolver&& aResolve) {
|
|
|
|
// NOTE: Immediately resolve the promise, as we've received the message. This
|
|
|
|
// will allow the parent process to discard references to this BC.
|
|
|
|
aResolve(true);
|
2019-03-14 21:50:38 +03:00
|
|
|
|
2019-07-15 23:44:50 +03:00
|
|
|
// If we can't find a BrowsingContext with the given ID, it's already been
|
|
|
|
// collected and we can ignore the request.
|
|
|
|
RefPtr<BrowsingContext> context = BrowsingContext::Get(aContextId);
|
|
|
|
if (context) {
|
|
|
|
context->Detach(/* aFromIPC */ true);
|
|
|
|
}
|
2019-04-29 14:38:45 +03:00
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvCacheBrowsingContextChildren(
|
|
|
|
BrowsingContext* aContext) {
|
|
|
|
MOZ_RELEASE_ASSERT(aContext);
|
|
|
|
|
|
|
|
aContext->CacheChildren(/* aFromIPC */ true);
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRestoreBrowsingContextChildren(
|
2019-05-28 10:40:00 +03:00
|
|
|
BrowsingContext* aContext, BrowsingContext::Children&& aChildren) {
|
2019-04-29 14:38:45 +03:00
|
|
|
MOZ_DIAGNOSTIC_ASSERT(aContext);
|
|
|
|
|
2019-05-28 10:40:00 +03:00
|
|
|
aContext->RestoreChildren(std::move(aChildren), /* aFromIPC */ true);
|
2019-04-29 14:38:45 +03:00
|
|
|
|
2019-03-14 21:50:38 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-03-14 21:51:09 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvRegisterBrowsingContextGroup(
|
|
|
|
nsTArray<BrowsingContext::IPCInitializer>&& aInits) {
|
|
|
|
RefPtr<BrowsingContextGroup> group = new BrowsingContextGroup();
|
|
|
|
// Each of the initializers in aInits is sorted in pre-order, so our parent
|
|
|
|
// should always be available before the element itself.
|
|
|
|
for (auto& init : aInits) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
RefPtr<BrowsingContext> existing = BrowsingContext::Get(init.mId);
|
|
|
|
MOZ_ASSERT(!existing, "BrowsingContext must not exist yet!");
|
|
|
|
|
|
|
|
RefPtr<BrowsingContext> parent = init.GetParent();
|
|
|
|
MOZ_ASSERT_IF(parent, parent->Group() == group);
|
|
|
|
#endif
|
|
|
|
|
2019-04-29 10:01:50 +03:00
|
|
|
bool cached = init.mCached;
|
2019-03-26 21:27:55 +03:00
|
|
|
RefPtr<BrowsingContext> ctxt =
|
|
|
|
BrowsingContext::CreateFromIPC(std::move(init), group, nullptr);
|
2019-03-14 21:51:09 +03:00
|
|
|
|
2019-04-29 10:01:50 +03:00
|
|
|
// If the browsing context is cached don't attach it, but add it
|
|
|
|
// to the cache here as well
|
|
|
|
if (cached) {
|
|
|
|
ctxt->Group()->CacheContext(ctxt);
|
|
|
|
} else {
|
|
|
|
ctxt->Attach(/* aFromIPC */ true);
|
|
|
|
}
|
2019-03-14 21:51:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-01-02 16:29:18 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvWindowClose(BrowsingContext* aContext,
|
2019-02-14 00:02:55 +03:00
|
|
|
bool aTrustedCaller) {
|
|
|
|
if (!aContext) {
|
2019-01-02 16:29:18 +03:00
|
|
|
MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
|
2019-02-14 00:02:55 +03:00
|
|
|
("ChildIPC: Trying to send a message to dead or detached context"));
|
2019-01-02 16:29:18 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-02-14 00:02:55 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> window = aContext->GetDOMWindow();
|
2019-06-26 15:54:47 +03:00
|
|
|
if (!window) {
|
|
|
|
MOZ_LOG(
|
|
|
|
BrowsingContext::GetLog(), LogLevel::Debug,
|
|
|
|
("ChildIPC: Trying to send a message to a context without a window"));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-01-02 16:29:18 +03:00
|
|
|
nsGlobalWindowOuter::Cast(window)->CloseOuter(aTrustedCaller);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-02-14 00:02:55 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvWindowFocus(
|
|
|
|
BrowsingContext* aContext) {
|
|
|
|
if (!aContext) {
|
2019-01-02 16:29:18 +03:00
|
|
|
MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
|
2019-02-14 00:02:55 +03:00
|
|
|
("ChildIPC: Trying to send a message to dead or detached context"));
|
2019-01-02 16:29:18 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-02-14 00:02:55 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> window = aContext->GetDOMWindow();
|
2019-06-26 15:54:47 +03:00
|
|
|
if (!window) {
|
|
|
|
MOZ_LOG(
|
|
|
|
BrowsingContext::GetLog(), LogLevel::Debug,
|
|
|
|
("ChildIPC: Trying to send a message to a context without a window"));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2019-01-02 16:29:18 +03:00
|
|
|
nsGlobalWindowOuter::Cast(window)->FocusOuter();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvWindowBlur(
|
2019-02-14 00:02:55 +03:00
|
|
|
BrowsingContext* aContext) {
|
|
|
|
if (!aContext) {
|
2019-01-02 16:29:18 +03:00
|
|
|
MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
|
2019-02-14 00:02:55 +03:00
|
|
|
("ChildIPC: Trying to send a message to dead or detached context"));
|
2019-01-02 16:29:18 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-02-14 00:02:55 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> window = aContext->GetDOMWindow();
|
2019-06-26 15:54:47 +03:00
|
|
|
if (!window) {
|
|
|
|
MOZ_LOG(
|
|
|
|
BrowsingContext::GetLog(), LogLevel::Debug,
|
|
|
|
("ChildIPC: Trying to send a message to a context without a window"));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2019-01-02 16:29:18 +03:00
|
|
|
nsGlobalWindowOuter::Cast(window)->BlurOuter();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvWindowPostMessage(
|
2019-02-14 00:02:55 +03:00
|
|
|
BrowsingContext* aContext, const ClonedMessageData& aMessage,
|
2019-01-02 16:29:18 +03:00
|
|
|
const PostMessageData& aData) {
|
2019-02-14 00:02:55 +03:00
|
|
|
if (!aContext) {
|
2019-01-02 16:29:18 +03:00
|
|
|
MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
|
2019-02-14 00:02:55 +03:00
|
|
|
("ChildIPC: Trying to send a message to dead or detached context"));
|
2019-01-02 16:29:18 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<nsGlobalWindowOuter> window =
|
2019-02-14 00:02:55 +03:00
|
|
|
nsGlobalWindowOuter::Cast(aContext->GetDOMWindow());
|
2019-06-26 15:54:47 +03:00
|
|
|
if (!window) {
|
|
|
|
MOZ_LOG(
|
|
|
|
BrowsingContext::GetLog(), LogLevel::Debug,
|
|
|
|
("ChildIPC: Trying to send a message to a context without a window"));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-01-02 16:29:18 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> providedPrincipal;
|
|
|
|
if (!window->GetPrincipalForPostMessage(
|
|
|
|
aData.targetOrigin(), aData.targetOriginURI(),
|
|
|
|
aData.callerPrincipal(), *aData.subjectPrincipal(),
|
|
|
|
getter_AddRefs(providedPrincipal))) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create and asynchronously dispatch a runnable which will handle actual DOM
|
|
|
|
// event creation and dispatch.
|
2019-06-10 18:13:07 +03:00
|
|
|
RefPtr<BrowsingContext> sourceBc = aData.source();
|
2019-01-02 16:29:18 +03:00
|
|
|
RefPtr<PostMessageEvent> event = new PostMessageEvent(
|
|
|
|
sourceBc, aData.origin(), window, providedPrincipal,
|
|
|
|
aData.callerDocumentURI(), aData.isFromPrivateWindow());
|
|
|
|
event->UnpackFrom(aMessage);
|
|
|
|
|
|
|
|
window->Dispatch(TaskCategory::Other, event.forget());
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-02-21 23:14:28 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvCommitBrowsingContextTransaction(
|
2019-03-27 12:19:29 +03:00
|
|
|
BrowsingContext* aContext, BrowsingContext::Transaction&& aTransaction,
|
2019-08-09 17:51:30 +03:00
|
|
|
uint64_t aEpoch) {
|
|
|
|
if (!aContext || aContext->IsDiscarded()) {
|
|
|
|
MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
|
|
|
|
("ChildIPC: Trying to send a message to dead or detached context"));
|
|
|
|
return IPC_OK();
|
2019-02-21 23:14:28 +03:00
|
|
|
}
|
2019-08-09 17:51:30 +03:00
|
|
|
|
2019-09-26 19:16:32 +03:00
|
|
|
if (!aTransaction.ValidateEpochs(aContext, aEpoch)) {
|
2019-08-09 17:51:30 +03:00
|
|
|
return IPC_FAIL(this, "Invalid BrowsingContext transaction from Parent");
|
|
|
|
}
|
|
|
|
|
|
|
|
aTransaction.Apply(aContext);
|
2019-02-21 23:14:28 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-05-03 02:56:41 +03:00
|
|
|
void ContentChild::HoldBrowsingContextGroup(BrowsingContextGroup* aBCG) {
|
2019-07-16 18:07:29 +03:00
|
|
|
mBrowsingContextGroupHolder.AppendElement(aBCG);
|
2019-05-03 02:56:41 +03:00
|
|
|
}
|
|
|
|
|
2019-07-17 03:31:38 +03:00
|
|
|
void ContentChild::ReleaseBrowsingContextGroup(BrowsingContextGroup* aBCG) {
|
|
|
|
mBrowsingContextGroupHolder.RemoveElement(aBCG);
|
|
|
|
}
|
|
|
|
|
2019-08-27 20:37:55 +03:00
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvScriptError(
|
|
|
|
const nsString& aMessage, const nsString& aSourceName,
|
|
|
|
const nsString& aSourceLine, const uint32_t& aLineNumber,
|
|
|
|
const uint32_t& aColNumber, const uint32_t& aFlags,
|
|
|
|
const nsCString& aCategory, const bool& aFromPrivateWindow,
|
|
|
|
const uint64_t& aInnerWindowId, const bool& aFromChromeContext) {
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIConsoleService> consoleService =
|
|
|
|
do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_FAIL(this, "Failed to get console service"));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptError> scriptError(
|
|
|
|
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
|
|
|
|
NS_ENSURE_TRUE(scriptError,
|
|
|
|
IPC_FAIL(this, "Failed to construct nsIScriptError"));
|
|
|
|
|
|
|
|
scriptError->InitWithWindowID(aMessage, aSourceName, aSourceLine, aLineNumber,
|
|
|
|
aColNumber, aFlags, aCategory, aInnerWindowId,
|
|
|
|
aFromChromeContext);
|
|
|
|
rv = consoleService->LogMessage(scriptError);
|
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_FAIL(this, "Failed to log script error"));
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2019-10-14 18:08:47 +03:00
|
|
|
#if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
|
|
|
|
mozilla::ipc::IPCResult ContentChild::RecvInitSandboxTesting(
|
|
|
|
Endpoint<PSandboxTestingChild>&& aEndpoint) {
|
|
|
|
if (!SandboxTestingChild::Initialize(std::move(aEndpoint))) {
|
|
|
|
return IPC_FAIL(
|
|
|
|
this, "InitSandboxTesting failed to initialise the child process.");
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-05-12 18:51:08 +03:00
|
|
|
} // namespace dom
|
2017-08-10 02:09:55 +03:00
|
|
|
|
2019-03-19 01:31:59 +03:00
|
|
|
#if defined(__OpenBSD__) && defined(MOZ_SANDBOX)
|
2018-08-23 14:35:00 +03:00
|
|
|
|
2019-11-07 12:52:18 +03:00
|
|
|
static LazyLogModule sPledgeLog("OpenBSDSandbox");
|
|
|
|
|
2019-11-08 10:31:09 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
OpenBSDFindPledgeUnveilFilePath(const char* file, nsACString& result) {
|
|
|
|
struct stat st;
|
|
|
|
|
|
|
|
// Allow overriding files in /etc/$MOZ_APP_NAME
|
|
|
|
result.Assign(nsPrintfCString("/etc/%s/%s", MOZ_APP_NAME, file));
|
|
|
|
if (stat(PromiseFlatCString(result).get(), &st) == 0) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Or look in the system default directory
|
|
|
|
result.Assign(nsPrintfCString(
|
|
|
|
"/usr/local/lib/%s/browser/defaults/preferences/%s", MOZ_APP_NAME, file));
|
|
|
|
if (stat(PromiseFlatCString(result).get(), &st) == 0) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
errx(1, "can't locate %s", file);
|
|
|
|
}
|
|
|
|
|
2019-11-07 12:52:18 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
OpenBSDPledgePromises(const nsACString& aPath) {
|
|
|
|
// Using NS_LOCAL_FILE_CONTRACTID/NS_LOCALFILEINPUTSTREAM_CONTRACTID requires
|
|
|
|
// a lot of setup before they are supported and we want to pledge early on
|
|
|
|
// before all of that, so read the file directly
|
|
|
|
std::ifstream input(PromiseFlatCString(aPath).get());
|
|
|
|
|
|
|
|
// Build up one line of pledge promises without comments
|
|
|
|
nsAutoCString promises;
|
|
|
|
bool disabled = false;
|
|
|
|
int linenum = 0;
|
|
|
|
for (std::string tLine; std::getline(input, tLine);) {
|
|
|
|
nsAutoCString line(tLine.c_str());
|
|
|
|
linenum++;
|
|
|
|
|
|
|
|
// Cut off any comments at the end of the line, also catches lines
|
|
|
|
// that are entirely a comment
|
|
|
|
int32_t hash = line.FindChar('#');
|
|
|
|
if (hash >= 0) {
|
|
|
|
line = Substring(line, 0, hash);
|
|
|
|
}
|
|
|
|
line.CompressWhitespace(true, true);
|
|
|
|
if (line.IsEmpty()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (linenum == 1 && line.EqualsLiteral("disable")) {
|
|
|
|
disabled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!promises.IsEmpty()) {
|
|
|
|
promises.Append(" ");
|
|
|
|
}
|
|
|
|
promises.Append(line);
|
|
|
|
}
|
|
|
|
input.close();
|
|
|
|
|
|
|
|
if (disabled) {
|
|
|
|
warnx("%s: disabled", PromiseFlatCString(aPath).get());
|
|
|
|
} else {
|
|
|
|
MOZ_LOG(
|
|
|
|
sPledgeLog, LogLevel::Debug,
|
|
|
|
("%s: pledge(%s)\n", PromiseFlatCString(aPath).get(), promises.get()));
|
|
|
|
if (pledge(promises.get(), nullptr) != 0) {
|
|
|
|
err(1, "%s: pledge(%s) failed", PromiseFlatCString(aPath).get(),
|
|
|
|
promises.get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2019-11-08 10:31:09 +03:00
|
|
|
void ExpandUnveilPath(nsAutoCString& path) {
|
|
|
|
// Expand $XDG_CONFIG_HOME to the environment variable, or ~/.config
|
|
|
|
nsCString xdgConfigHome(PR_GetEnv("XDG_CONFIG_HOME"));
|
|
|
|
if (xdgConfigHome.IsEmpty()) {
|
|
|
|
xdgConfigHome = "~/.config";
|
|
|
|
}
|
|
|
|
path.ReplaceSubstring("$XDG_CONFIG_HOME", xdgConfigHome.get());
|
|
|
|
|
|
|
|
// Expand $XDG_CACHE_HOME to the environment variable, or ~/.cache
|
|
|
|
nsCString xdgCacheHome(PR_GetEnv("XDG_CACHE_HOME"));
|
|
|
|
if (xdgCacheHome.IsEmpty()) {
|
|
|
|
xdgCacheHome = "~/.cache";
|
|
|
|
}
|
|
|
|
path.ReplaceSubstring("$XDG_CACHE_HOME", xdgCacheHome.get());
|
|
|
|
|
|
|
|
// Expand $XDG_DATA_HOME to the environment variable, or ~/.local/share
|
|
|
|
nsCString xdgDataHome(PR_GetEnv("XDG_DATA_HOME"));
|
|
|
|
if (xdgDataHome.IsEmpty()) {
|
|
|
|
xdgDataHome = "~/.local/share";
|
|
|
|
}
|
|
|
|
path.ReplaceSubstring("$XDG_DATA_HOME", xdgDataHome.get());
|
|
|
|
|
|
|
|
// Expand leading ~ to the user's home directory
|
|
|
|
nsCOMPtr<nsIFile> homeDir;
|
|
|
|
nsresult rv =
|
|
|
|
GetSpecialSystemDirectory(Unix_HomeDirectory, getter_AddRefs(homeDir));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
errx(1, "failed getting home directory");
|
|
|
|
}
|
|
|
|
if (path.FindChar('~') == 0) {
|
|
|
|
nsCString tHome(homeDir->NativePath());
|
|
|
|
tHome.Append(Substring(path, 1, path.Length() - 1));
|
|
|
|
path = tHome.get();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MkdirP(nsAutoCString& path) {
|
|
|
|
// nsLocalFile::CreateAllAncestors would be nice to use
|
|
|
|
|
|
|
|
nsAutoCString tPath("");
|
|
|
|
for (const nsACString& dir : path.Split('/')) {
|
|
|
|
struct stat st;
|
|
|
|
|
|
|
|
if (dir.IsEmpty()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
tPath.Append("/");
|
|
|
|
tPath.Append(dir);
|
|
|
|
|
|
|
|
if (stat(tPath.get(), &st) == -1) {
|
|
|
|
if (mkdir(tPath.get(), 0700) == -1) {
|
|
|
|
err(1, "failed mkdir(%s) while MkdirP(%s)",
|
|
|
|
PromiseFlatCString(tPath).get(), PromiseFlatCString(path).get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-07 12:52:18 +03:00
|
|
|
NS_IMETHODIMP
|
2019-11-08 10:31:09 +03:00
|
|
|
OpenBSDUnveilPaths(const nsACString& uPath, const nsACString& pledgePath) {
|
|
|
|
// Using NS_LOCAL_FILE_CONTRACTID/NS_LOCALFILEINPUTSTREAM_CONTRACTID requires
|
|
|
|
// a lot of setup before they are allowed/supported and we want to pledge and
|
|
|
|
// unveil early on before all of that is setup
|
|
|
|
std::ifstream input(PromiseFlatCString(uPath).get());
|
2019-11-07 12:52:18 +03:00
|
|
|
|
2019-11-08 10:31:09 +03:00
|
|
|
bool disabled = false;
|
|
|
|
int linenum = 0;
|
|
|
|
for (std::string tLine; std::getline(input, tLine);) {
|
|
|
|
nsAutoCString line(tLine.c_str());
|
|
|
|
linenum++;
|
|
|
|
|
|
|
|
// Cut off any comments at the end of the line, also catches lines
|
|
|
|
// that are entirely a comment
|
|
|
|
int32_t hash = line.FindChar('#');
|
|
|
|
if (hash >= 0) {
|
|
|
|
line = Substring(line, 0, hash);
|
|
|
|
}
|
|
|
|
line.CompressWhitespace(true, true);
|
|
|
|
if (line.IsEmpty()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (linenum == 1 && line.EqualsLiteral("disable")) {
|
|
|
|
disabled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t space = line.FindChar(' ');
|
|
|
|
if (space <= 0) {
|
|
|
|
errx(1, "%s: line %d: invalid format", PromiseFlatCString(uPath).get(),
|
|
|
|
linenum);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoCString uPath(Substring(line, 0, space));
|
|
|
|
ExpandUnveilPath(uPath);
|
|
|
|
|
|
|
|
nsAutoCString perms(Substring(line, space + 1, line.Length() - space - 1));
|
|
|
|
|
|
|
|
MOZ_LOG(sPledgeLog, LogLevel::Debug,
|
|
|
|
("%s: unveil(%s, %s)\n", PromiseFlatCString(uPath).get(),
|
|
|
|
uPath.get(), perms.get()));
|
|
|
|
if (unveil(uPath.get(), perms.get()) == -1 && errno != ENOENT) {
|
|
|
|
err(1, "%s: unveil(%s, %s) failed", PromiseFlatCString(uPath).get(),
|
|
|
|
uPath.get(), perms.get());
|
|
|
|
}
|
2019-11-07 12:52:18 +03:00
|
|
|
}
|
2019-11-08 10:31:09 +03:00
|
|
|
input.close();
|
2019-11-07 12:52:18 +03:00
|
|
|
|
2019-11-08 10:31:09 +03:00
|
|
|
if (disabled) {
|
|
|
|
warnx("%s: disabled", PromiseFlatCString(uPath).get());
|
|
|
|
} else {
|
|
|
|
if (unveil(PromiseFlatCString(pledgePath).get(), "r") == -1) {
|
|
|
|
err(1, "unveil(%s, r) failed", PromiseFlatCString(pledgePath).get());
|
|
|
|
}
|
2019-11-07 12:52:18 +03:00
|
|
|
}
|
|
|
|
|
2019-11-08 10:31:09 +03:00
|
|
|
return NS_OK;
|
2019-11-07 12:52:18 +03:00
|
|
|
}
|
2018-08-23 14:35:00 +03:00
|
|
|
|
|
|
|
bool StartOpenBSDSandbox(GeckoProcessType type) {
|
2019-11-07 12:52:18 +03:00
|
|
|
nsAutoCString pledgeFile;
|
2019-11-08 10:31:09 +03:00
|
|
|
nsAutoCString unveilFile;
|
2018-08-23 14:35:00 +03:00
|
|
|
|
|
|
|
switch (type) {
|
2019-11-08 10:31:09 +03:00
|
|
|
case GeckoProcessType_Default: {
|
|
|
|
OpenBSDFindPledgeUnveilFilePath("pledge.main", pledgeFile);
|
|
|
|
OpenBSDFindPledgeUnveilFilePath("unveil.main", unveilFile);
|
|
|
|
|
|
|
|
// Ensure dconf dir exists before we veil the filesystem
|
|
|
|
nsAutoCString dConf("$XDG_CACHE_HOME/dconf");
|
|
|
|
ExpandUnveilPath(dConf);
|
|
|
|
MkdirP(dConf);
|
2018-08-23 14:35:00 +03:00
|
|
|
break;
|
2019-11-08 10:31:09 +03:00
|
|
|
}
|
2018-08-23 14:35:00 +03:00
|
|
|
|
|
|
|
case GeckoProcessType_Content:
|
2019-11-08 10:31:09 +03:00
|
|
|
OpenBSDFindPledgeUnveilFilePath("pledge.content", pledgeFile);
|
|
|
|
OpenBSDFindPledgeUnveilFilePath("unveil.content", unveilFile);
|
2018-08-23 14:35:00 +03:00
|
|
|
break;
|
|
|
|
|
2019-11-07 12:56:07 +03:00
|
|
|
case GeckoProcessType_GPU:
|
2019-11-08 10:31:09 +03:00
|
|
|
OpenBSDFindPledgeUnveilFilePath("pledge.gpu", pledgeFile);
|
|
|
|
OpenBSDFindPledgeUnveilFilePath("unveil.gpu", unveilFile);
|
2019-11-07 12:56:07 +03:00
|
|
|
break;
|
|
|
|
|
2018-08-23 14:35:00 +03:00
|
|
|
default:
|
|
|
|
MOZ_ASSERT(false, "unknown process type");
|
|
|
|
return false;
|
2019-11-07 12:52:18 +03:00
|
|
|
}
|
2018-08-23 14:35:00 +03:00
|
|
|
|
2019-11-08 10:31:09 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(OpenBSDUnveilPaths(unveilFile, pledgeFile)))) {
|
|
|
|
errx(1, "failed reading/parsing %s", unveilFile.get());
|
|
|
|
}
|
|
|
|
|
2019-11-07 12:52:18 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(OpenBSDPledgePromises(pledgeFile)))) {
|
|
|
|
errx(1, "failed reading/parsing %s", pledgeFile.get());
|
2018-08-23 14:35:00 +03:00
|
|
|
}
|
2019-11-07 12:52:18 +03:00
|
|
|
|
|
|
|
// Don't overwrite an existing session dbus address, but ensure it is set
|
|
|
|
if (!PR_GetEnv("DBUS_SESSION_BUS_ADDRESS")) {
|
|
|
|
PR_SetEnv("DBUS_SESSION_BUS_ADDRESS=");
|
|
|
|
}
|
|
|
|
|
2018-08-23 14:35:00 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-06-13 04:38:56 +03:00
|
|
|
#if !defined(XP_WIN)
|
|
|
|
bool IsDevelopmentBuild() {
|
|
|
|
nsCOMPtr<nsIFile> path = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE);
|
|
|
|
// If the path doesn't exist, we're a dev build.
|
|
|
|
return path == nullptr;
|
|
|
|
}
|
|
|
|
#endif /* !XP_WIN */
|
|
|
|
|
2019-03-01 00:20:40 +03:00
|
|
|
} // namespace mozilla
|