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-09-10 02:00:14 +04:00
|
|
|
|
2012-12-15 03:58:45 +04:00
|
|
|
#include "mozilla/DebugOnly.h"
|
|
|
|
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "base/basictypes.h"
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
#include "base/shared_memory.h"
|
2009-08-12 20:18:08 +04:00
|
|
|
|
2012-08-02 10:02:29 +04:00
|
|
|
#include "ContentParent.h"
|
2015-10-30 02:30:57 +03:00
|
|
|
#include "TabParent.h"
|
2012-08-02 10:02:29 +04:00
|
|
|
|
2012-07-18 03:59:44 +04:00
|
|
|
#if defined(ANDROID) || defined(LINUX)
|
|
|
|
# include <sys/time.h>
|
|
|
|
# include <sys/resource.h>
|
|
|
|
#endif
|
|
|
|
|
2011-07-13 10:52:31 +04:00
|
|
|
#include "chrome/common/process_watcher.h"
|
|
|
|
|
2015-10-08 00:38:08 +03:00
|
|
|
#include "mozilla/a11y/PDocAccessible.h"
|
2017-03-23 04:44:59 +03:00
|
|
|
#include "GeckoProfiler.h"
|
2015-02-10 13:49:03 +03:00
|
|
|
#include "GMPServiceParent.h"
|
2015-08-26 02:42:21 +03:00
|
|
|
#include "HandlerServiceParent.h"
|
2012-11-09 13:55:54 +04:00
|
|
|
#include "IHistory.h"
|
2015-04-17 04:27:13 +03:00
|
|
|
#include "imgIContainer.h"
|
2016-09-27 01:17:58 +03:00
|
|
|
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
|
|
|
#include "mozilla/a11y/AccessibleWrap.h"
|
2017-09-09 00:05:06 +03:00
|
|
|
#include "mozilla/a11y/Compatibility.h"
|
2016-09-27 01:17:58 +03:00
|
|
|
#endif
|
2018-07-13 13:02:19 +03:00
|
|
|
#include "mozilla/AntiTrackingCommon.h"
|
2017-08-03 14:00:41 +03:00
|
|
|
#include "mozilla/BasePrincipal.h"
|
2012-08-16 05:46:03 +04:00
|
|
|
#include "mozilla/ClearOnShutdown.h"
|
2016-09-26 15:03:25 +03:00
|
|
|
#include "mozilla/StyleSheetInlines.h"
|
2015-10-30 22:30:00 +03:00
|
|
|
#include "mozilla/DataStorage.h"
|
2015-09-22 22:09:42 +03:00
|
|
|
#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
|
2014-11-13 03:31:00 +03:00
|
|
|
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
2018-07-26 10:31:00 +03:00
|
|
|
#include "mozilla/dom/BrowsingContext.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"
|
2015-04-08 21:48:11 +03:00
|
|
|
#include "mozilla/dom/DataTransfer.h"
|
2014-09-29 18:46:00 +04:00
|
|
|
#include "mozilla/dom/Element.h"
|
2014-10-08 20:15:23 +04:00
|
|
|
#include "mozilla/dom/File.h"
|
2017-02-08 12:19:01 +03:00
|
|
|
#include "mozilla/dom/FileCreatorHelper.h"
|
2017-03-16 10:53:49 +03:00
|
|
|
#include "mozilla/dom/FileSystemSecurity.h"
|
2017-04-24 13:16:50 +03:00
|
|
|
#include "mozilla/dom/IPCBlobUtils.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "mozilla/dom/ExternalHelperAppParent.h"
|
2016-07-14 10:04:21 +03:00
|
|
|
#include "mozilla/dom/GetFilesHelper.h"
|
2014-09-29 18:46:00 +04:00
|
|
|
#include "mozilla/dom/GeolocationBinding.h"
|
2017-01-27 03:35:53 +03:00
|
|
|
#include "mozilla/dom/MemoryReportRequest.h"
|
2015-10-23 00:10:14 +03:00
|
|
|
#include "mozilla/dom/Notification.h"
|
2014-06-11 09:44:13 +04:00
|
|
|
#include "mozilla/dom/PContentBridgeParent.h"
|
2015-04-14 04:08:00 +03:00
|
|
|
#include "mozilla/dom/PContentPermissionRequestParent.h"
|
2014-05-13 21:13:00 +04:00
|
|
|
#include "mozilla/dom/PCycleCollectWithLogsParent.h"
|
2018-06-02 05:35:44 +03:00
|
|
|
#include "mozilla/dom/PositionError.h"
|
2015-04-24 02:41:00 +03:00
|
|
|
#include "mozilla/dom/ServiceWorkerRegistrar.h"
|
2014-09-29 18:46:00 +04:00
|
|
|
#include "mozilla/dom/power/PowerManagerService.h"
|
2016-03-03 00:09:48 +03:00
|
|
|
#include "mozilla/dom/Permissions.h"
|
2015-03-26 06:16:21 +03:00
|
|
|
#include "mozilla/dom/PresentationParent.h"
|
|
|
|
#include "mozilla/dom/PPresentationParent.h"
|
2016-09-01 21:17:03 +03:00
|
|
|
#include "mozilla/dom/PushNotifier.h"
|
2015-11-22 12:43:55 +03:00
|
|
|
#include "mozilla/dom/quota/QuotaManagerService.h"
|
2018-07-10 02:02:41 +03:00
|
|
|
#include "mozilla/dom/ServiceWorkerUtils.h"
|
2016-11-19 00:54:57 +03:00
|
|
|
#include "mozilla/dom/URLClassifierParent.h"
|
2018-06-23 06:35:49 +03:00
|
|
|
#include "mozilla/dom/ipc/SharedMap.h"
|
2014-10-28 18:59:08 +03:00
|
|
|
#include "mozilla/embedding/printingui/PrintingParent.h"
|
2017-09-08 03:28:27 +03:00
|
|
|
#include "mozilla/extensions/StreamFilterParent.h"
|
2016-08-04 21:33:42 +03:00
|
|
|
#include "mozilla/gfx/gfxVars.h"
|
2016-05-23 10:27:57 +03:00
|
|
|
#include "mozilla/gfx/GPUProcessManager.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "mozilla/hal_sandbox/PHalParent.h"
|
2013-11-27 11:59:41 +04:00
|
|
|
#include "mozilla/ipc/BackgroundChild.h"
|
|
|
|
#include "mozilla/ipc/BackgroundParent.h"
|
2017-10-10 13:43:09 +03:00
|
|
|
#include "mozilla/ipc/CrashReporterHost.h"
|
2014-05-13 21:13:00 +04:00
|
|
|
#include "mozilla/ipc/FileDescriptorUtils.h"
|
2017-03-14 14:28:58 +03:00
|
|
|
#include "mozilla/ipc/PChildToParentStreamParent.h"
|
2009-08-12 22:31:48 +04:00
|
|
|
#include "mozilla/ipc/TestShellParent.h"
|
2017-03-09 16:10:49 +03:00
|
|
|
#include "mozilla/ipc/IPCStreamUtils.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"
|
2015-01-27 00:32:18 +03:00
|
|
|
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
2016-01-08 22:17:39 +03:00
|
|
|
#include "mozilla/layers/PAPZParent.h"
|
2016-05-16 09:39:30 +03:00
|
|
|
#include "mozilla/layers/CompositorThread.h"
|
2012-08-29 16:24:48 +04:00
|
|
|
#include "mozilla/layers/ImageBridgeParent.h"
|
2016-08-16 23:59:13 +03:00
|
|
|
#include "mozilla/layers/LayerTreeOwnerTracker.h"
|
2016-03-29 21:32:41 +03:00
|
|
|
#include "mozilla/layout/RenderFrameParent.h"
|
2017-05-03 03:17:52 +03:00
|
|
|
#include "mozilla/loader/ScriptCacheActors.h"
|
2017-12-07 11:32:52 +03:00
|
|
|
#include "mozilla/LoginReputationIPC.h"
|
2015-04-22 17:58:15 +03:00
|
|
|
#include "mozilla/LookAndFeel.h"
|
2015-06-18 18:46:36 +03:00
|
|
|
#include "mozilla/media/MediaParent.h"
|
2015-07-31 10:25:27 +03:00
|
|
|
#include "mozilla/Move.h"
|
2009-08-18 23:05:15 +04:00
|
|
|
#include "mozilla/net/NeckoParent.h"
|
2017-08-03 14:00:41 +03:00
|
|
|
#include "mozilla/net/CookieServiceParent.h"
|
|
|
|
#include "mozilla/net/PCookieServiceParent.h"
|
2014-10-29 18:05:36 +03:00
|
|
|
#include "mozilla/plugins/PluginBridge.h"
|
2012-08-16 05:46:03 +04:00
|
|
|
#include "mozilla/Preferences.h"
|
2015-01-17 05:34:47 +03:00
|
|
|
#include "mozilla/ProcessHangMonitor.h"
|
|
|
|
#include "mozilla/ProcessHangMonitorIPC.h"
|
2018-07-22 14:51:55 +03:00
|
|
|
#include "mozilla/recordreplay/ParentIPC.h"
|
2017-07-29 00:56:49 +03:00
|
|
|
#include "mozilla/Scheduler.h"
|
2016-08-24 13:49:42 +03:00
|
|
|
#include "mozilla/ScopeExit.h"
|
2017-05-03 03:17:52 +03:00
|
|
|
#include "mozilla/ScriptPreloader.h"
|
2012-08-16 05:46:03 +04:00
|
|
|
#include "mozilla/Services.h"
|
|
|
|
#include "mozilla/StaticPtr.h"
|
2018-06-19 17:14:06 +03:00
|
|
|
#include "mozilla/StaticPrefs.h"
|
2014-12-12 22:13:28 +03:00
|
|
|
#include "mozilla/Telemetry.h"
|
2017-02-15 18:25:40 +03:00
|
|
|
#include "mozilla/TelemetryIPC.h"
|
2015-09-21 15:54:00 +03:00
|
|
|
#include "mozilla/WebBrowserPersistDocumentParent.h"
|
2017-03-09 14:30:26 +03:00
|
|
|
#include "mozilla/widget/ScreenManager.h"
|
2016-08-23 07:09:32 +03:00
|
|
|
#include "mozilla/Unused.h"
|
2018-01-11 01:27:18 +03:00
|
|
|
#include "mozilla/HangDetails.h"
|
2014-06-24 21:11:36 +04:00
|
|
|
#include "nsAnonymousTemporaryFile.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsAppRunner.h"
|
2013-08-16 21:59:31 +04:00
|
|
|
#include "nsCDefaultURIFixup.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsCExternalHandlerService.h"
|
2009-09-03 04:18:27 +04:00
|
|
|
#include "nsCOMPtr.h"
|
2010-03-11 08:33:00 +03:00
|
|
|
#include "nsChromeRegistryChrome.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsConsoleMessage.h"
|
2012-11-09 21:52:09 +04:00
|
|
|
#include "nsConsoleService.h"
|
2014-11-13 03:31:00 +03:00
|
|
|
#include "nsContentUtils.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsDebugImpl.h"
|
2018-07-22 14:52:42 +03:00
|
|
|
#include "nsDirectoryServiceDefs.h"
|
2018-07-22 14:51:55 +03:00
|
|
|
#include "nsEmbedCID.h"
|
2016-11-24 18:08:31 +03:00
|
|
|
#include "nsFrameLoader.h"
|
2010-08-31 22:58:35 +04:00
|
|
|
#include "nsFrameMessageManager.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsHashPropertyBag.h"
|
2010-09-15 20:44:57 +04:00
|
|
|
#include "nsIAlertsService.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsIClipboard.h"
|
2017-08-03 13:00:12 +03:00
|
|
|
#include "nsICookie.h"
|
2015-04-14 04:08:00 +03:00
|
|
|
#include "nsContentPermissionHelper.h"
|
2016-11-02 02:02:43 +03:00
|
|
|
#include "nsIContentProcess.h"
|
2014-05-13 21:13:00 +04:00
|
|
|
#include "nsICycleCollectorListener.h"
|
2015-09-22 00:14:25 +03:00
|
|
|
#include "nsIDocShellTreeOwner.h"
|
2014-09-27 03:21:57 +04:00
|
|
|
#include "nsIDocument.h"
|
2018-06-04 19:41:04 +03:00
|
|
|
#include "nsGeolocation.h"
|
2015-04-08 21:48:11 +03:00
|
|
|
#include "nsIDragService.h"
|
2014-08-01 22:02:55 +04:00
|
|
|
#include "mozilla/dom/WakeLock.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsIDOMWindow.h"
|
2013-09-24 01:30:40 +04:00
|
|
|
#include "nsIExternalProtocolService.h"
|
2014-11-27 01:28:28 +03:00
|
|
|
#include "nsIFormProcessor.h"
|
2014-01-11 05:09:20 +04:00
|
|
|
#include "nsIGfxInfo.h"
|
2013-12-13 20:28:46 +04:00
|
|
|
#include "nsIIdleService.h"
|
2015-09-22 00:14:25 +03:00
|
|
|
#include "nsIInterfaceRequestorUtils.h"
|
2014-05-13 21:13:00 +04:00
|
|
|
#include "nsIMemoryInfoDumper.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsIMemoryReporter.h"
|
2013-02-15 00:41:30 +04:00
|
|
|
#include "nsIMozBrowserFrame.h"
|
2013-01-10 22:16:40 +04:00
|
|
|
#include "nsIMutable.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsIObserverService.h"
|
2016-07-01 06:16:00 +03:00
|
|
|
#include "nsIParentChannel.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsIPresShell.h"
|
2018-08-12 14:50:41 +03:00
|
|
|
#include "nsIPromptService.h"
|
2015-12-04 02:04:28 +03:00
|
|
|
#include "nsIRemoteWindowContext.h"
|
2010-09-24 05:39:32 +04:00
|
|
|
#include "nsIScriptError.h"
|
2015-07-07 05:17:00 +03:00
|
|
|
#include "nsIScriptSecurityManager.h"
|
2014-07-22 16:17:45 +04:00
|
|
|
#include "nsISiteSecurityService.h"
|
2018-01-16 15:24:51 +03:00
|
|
|
#include "nsISound.h"
|
2014-10-03 18:52:37 +04:00
|
|
|
#include "nsISpellChecker.h"
|
2018-06-30 08:53:12 +03:00
|
|
|
#include "nsIStringBundle.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsISupportsPrimitives.h"
|
2015-01-07 08:42:23 +03:00
|
|
|
#include "nsITimer.h"
|
2013-08-16 21:59:31 +04:00
|
|
|
#include "nsIURIFixup.h"
|
2018-01-16 15:24:51 +03:00
|
|
|
#include "nsIURL.h"
|
2015-10-30 02:30:57 +03:00
|
|
|
#include "nsIDocShellTreeOwner.h"
|
|
|
|
#include "nsIXULWindow.h"
|
|
|
|
#include "nsIDOMChromeWindow.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsIWindowWatcher.h"
|
2015-10-30 02:30:57 +03:00
|
|
|
#include "nsPIWindowWatcher.h"
|
2017-10-10 13:43:09 +03:00
|
|
|
#include "nsThread.h"
|
2015-10-30 02:30:57 +03:00
|
|
|
#include "nsWindowWatcher.h"
|
2013-12-13 02:13:20 +04:00
|
|
|
#include "nsIXULRuntime.h"
|
2018-04-16 16:18:48 +03:00
|
|
|
#include "mozilla/dom/ParentProcessMessageManager.h"
|
|
|
|
#include "mozilla/dom/ProcessMessageManager.h"
|
2015-09-09 22:14:27 +03:00
|
|
|
#include "mozilla/dom/nsMixedContentBlocker.h"
|
2014-07-03 02:59:02 +04:00
|
|
|
#include "nsMemoryInfoDumper.h"
|
2013-10-23 09:26:24 +04:00
|
|
|
#include "nsMemoryReporterManager.h"
|
2018-02-24 04:21:49 +03:00
|
|
|
#include "nsScriptError.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsServiceManagerUtils.h"
|
2013-08-27 21:10:39 +04:00
|
|
|
#include "nsStyleSheetService.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "nsThreadUtils.h"
|
|
|
|
#include "nsToolkitCompsCID.h"
|
|
|
|
#include "nsWidgetsCID.h"
|
2017-02-01 15:34:24 +03:00
|
|
|
#include "PreallocatedProcessManager.h"
|
2013-04-26 04:53:26 +04:00
|
|
|
#include "ProcessPriorityManager.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "SandboxHal.h"
|
2015-04-16 22:38:12 +03:00
|
|
|
#include "SourceSurfaceRawData.h"
|
2012-07-18 03:59:44 +04:00
|
|
|
#include "TabParent.h"
|
2012-08-23 23:33:46 +04:00
|
|
|
#include "URIUtils.h"
|
2013-05-07 08:10:31 +04:00
|
|
|
#include "nsIWebBrowserChrome.h"
|
|
|
|
#include "nsIDocShell.h"
|
2015-04-29 11:57:24 +03:00
|
|
|
#include "nsDocShell.h"
|
2015-10-30 02:30:57 +03:00
|
|
|
#include "nsOpenURIInFrameParams.h"
|
2013-10-19 00:57:55 +04:00
|
|
|
#include "mozilla/net/NeckoMessageUtils.h"
|
2017-11-02 23:29:33 +03:00
|
|
|
#include "gfxPlatform.h"
|
2014-02-27 06:52:54 +04:00
|
|
|
#include "gfxPrefs.h"
|
2014-06-24 21:11:36 +04:00
|
|
|
#include "prio.h"
|
|
|
|
#include "private/pprio.h"
|
2014-10-29 21:11:00 +03:00
|
|
|
#include "ContentProcessManager.h"
|
2018-06-02 16:51:42 +03:00
|
|
|
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
2015-09-10 23:50:58 +03:00
|
|
|
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
2018-07-05 17:32:03 +03:00
|
|
|
#include "mozilla/PerformanceMetricsCollector.h"
|
2015-04-22 22:55:23 +03:00
|
|
|
#include "mozilla/psm/PSMContentListener.h"
|
2015-05-01 18:07:19 +03:00
|
|
|
#include "nsPluginHost.h"
|
|
|
|
#include "nsPluginTags.h"
|
|
|
|
#include "nsIBlocklistService.h"
|
2016-09-26 15:03:25 +03:00
|
|
|
#include "mozilla/StyleSheet.h"
|
|
|
|
#include "mozilla/StyleSheetInlines.h"
|
2016-11-17 19:35:24 +03:00
|
|
|
#include "nsICaptivePortalService.h"
|
2017-03-04 02:23:19 +03:00
|
|
|
#include "nsIObjectLoadingContent.h"
|
2015-04-11 01:18:05 +03:00
|
|
|
#include "nsIBidiKeyboard.h"
|
2016-07-21 13:57:35 +03:00
|
|
|
#include "nsLayoutStylesheetCache.h"
|
|
|
|
|
2017-02-07 10:24:35 +03:00
|
|
|
#include "mozilla/Sprintf.h"
|
2017-02-05 08:52:38 +03:00
|
|
|
|
2015-05-06 19:29:33 +03:00
|
|
|
#ifdef MOZ_WEBRTC
|
|
|
|
#include "signaling/src/peerconnection/WebrtcGlobalParent.h"
|
|
|
|
#endif
|
|
|
|
|
2013-09-24 01:30:40 +04:00
|
|
|
#if defined(ANDROID) || defined(LINUX)
|
|
|
|
#include "nsSystemInfo.h"
|
2010-10-09 22:07:38 +04:00
|
|
|
#endif
|
|
|
|
|
2014-05-21 09:49:36 +04:00
|
|
|
#if defined(XP_LINUX)
|
|
|
|
#include "mozilla/Hal.h"
|
|
|
|
#endif
|
|
|
|
|
2013-09-24 01:30:40 +04:00
|
|
|
#ifdef ANDROID
|
|
|
|
# include "gfxAndroidPlatform.h"
|
2010-11-24 16:58:21 +03:00
|
|
|
#endif
|
|
|
|
|
2012-07-18 03:59:44 +04:00
|
|
|
# include "nsPermissionManager.h"
|
2011-02-16 21:43:23 +03:00
|
|
|
|
2011-11-11 04:17:46 +04:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2012-07-18 03:59:44 +04:00
|
|
|
# include "AndroidBridge.h"
|
2011-01-13 07:04:42 +03:00
|
|
|
#endif
|
|
|
|
|
2015-11-05 00:46:10 +03:00
|
|
|
#ifdef MOZ_WIDGET_GTK
|
|
|
|
#include <gdk/gdk.h>
|
|
|
|
#endif
|
|
|
|
|
2014-07-02 02:24:27 +04:00
|
|
|
#include "mozilla/RemoteSpellCheckEngineParent.h"
|
|
|
|
|
2013-02-28 00:31:19 +04:00
|
|
|
#include "Crypto.h"
|
|
|
|
|
2013-04-04 02:13:17 +04:00
|
|
|
#ifdef MOZ_WEBSPEECH
|
|
|
|
#include "mozilla/dom/SpeechSynthesisParent.h"
|
|
|
|
#endif
|
|
|
|
|
2017-05-13 00:04:42 +03:00
|
|
|
#if defined(MOZ_CONTENT_SANDBOX)
|
|
|
|
#include "mozilla/SandboxSettings.h"
|
|
|
|
#if defined(XP_LINUX)
|
2014-11-25 02:22:13 +03:00
|
|
|
#include "mozilla/SandboxInfo.h"
|
2015-10-08 08:13:09 +03:00
|
|
|
#include "mozilla/SandboxBroker.h"
|
|
|
|
#include "mozilla/SandboxBrokerPolicyFactory.h"
|
2014-08-15 22:56:28 +04:00
|
|
|
#endif
|
2017-05-13 00:04:42 +03:00
|
|
|
#endif
|
2014-08-15 22:56:28 +04:00
|
|
|
|
2014-09-11 17:50:55 +04:00
|
|
|
#ifdef MOZ_TOOLKIT_SEARCH
|
|
|
|
#include "nsIBrowserSearchService.h"
|
|
|
|
#endif
|
|
|
|
|
2016-03-13 16:25:23 +03:00
|
|
|
#ifdef XP_WIN
|
2017-07-25 07:34:14 +03:00
|
|
|
#include "mozilla/audio/AudioNotificationSender.h"
|
2016-03-13 16:25:23 +03:00
|
|
|
#include "mozilla/widget/AudioSession.h"
|
|
|
|
#endif
|
|
|
|
|
2016-08-29 18:06:48 +03:00
|
|
|
#ifdef ACCESSIBILITY
|
|
|
|
#include "nsAccessibilityService.h"
|
|
|
|
#endif
|
|
|
|
|
2017-05-30 22:06:14 +03:00
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
|
|
|
#include "nsIProfiler.h"
|
2017-06-02 23:03:39 +03:00
|
|
|
#include "ProfilerParent.h"
|
2017-05-30 22:06:14 +03:00
|
|
|
#endif
|
|
|
|
|
2017-06-14 11:50:44 +03:00
|
|
|
#ifdef MOZ_CODE_COVERAGE
|
|
|
|
#include "mozilla/CodeCoverageHandler.h"
|
|
|
|
#endif
|
|
|
|
|
2016-03-17 09:18:35 +03:00
|
|
|
// For VP9Benchmark::sBenchmarkFpsPref
|
|
|
|
#include "Benchmark.h"
|
|
|
|
|
2011-03-01 08:36:43 +03:00
|
|
|
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
|
|
|
|
2011-01-20 09:14:12 +03:00
|
|
|
using base::KillProcess;
|
2014-11-24 23:05:45 +03:00
|
|
|
|
|
|
|
using namespace CrashReporter;
|
2014-08-01 22:02:55 +04:00
|
|
|
using namespace mozilla::dom::power;
|
2015-06-18 18:46:36 +03:00
|
|
|
using namespace mozilla::media;
|
2014-10-28 18:59:08 +03:00
|
|
|
using namespace mozilla::embedding;
|
2016-05-23 10:27:57 +03:00
|
|
|
using namespace mozilla::gfx;
|
2015-02-10 13:49:03 +03:00
|
|
|
using namespace mozilla::gmp;
|
2013-01-27 01:14:01 +04:00
|
|
|
using namespace mozilla::hal;
|
2012-07-18 03:59:44 +04:00
|
|
|
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:44 +04:00
|
|
|
using namespace mozilla::layers;
|
2016-03-29 21:32:41 +03:00
|
|
|
using namespace mozilla::layout;
|
2012-07-18 03:59:44 +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;
|
2014-07-14 21:22:26 +04:00
|
|
|
using namespace mozilla::widget;
|
2017-05-03 03:17:52 +03:00
|
|
|
using mozilla::loader::PScriptCacheParent;
|
2017-05-23 09:47:58 +03:00
|
|
|
using mozilla::Telemetry::ProcessID;
|
2009-09-03 04:18:27 +04:00
|
|
|
|
2014-05-11 13:47:11 +04:00
|
|
|
// XXX Workaround for bug 986973 to maintain the existing broken semantics
|
|
|
|
template<>
|
|
|
|
struct nsIConsoleService::COMTypeInfo<nsConsoleService, void> {
|
2014-06-02 16:08:24 +04:00
|
|
|
static const nsIID kIID;
|
2014-05-11 13:47:11 +04:00
|
|
|
};
|
|
|
|
const nsIID nsIConsoleService::COMTypeInfo<nsConsoleService, void>::kIID = NS_ICONSOLESERVICE_IID;
|
|
|
|
|
2009-08-12 20:18:08 +04:00
|
|
|
namespace mozilla {
|
2017-12-20 04:51:11 +03:00
|
|
|
namespace CubebUtils {
|
|
|
|
extern FileDescriptor CreateAudioIPCConnection();
|
|
|
|
}
|
|
|
|
|
2009-08-12 20:18:08 +04:00
|
|
|
namespace dom {
|
|
|
|
|
2010-05-11 21:22:34 +04:00
|
|
|
#define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
|
2015-05-02 00:14:39 +03:00
|
|
|
#define NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC "ipc:network:set-connectivity"
|
2010-05-11 16:44:12 +04:00
|
|
|
|
2014-05-13 21:13:00 +04:00
|
|
|
// IPC receiver for remote GC/CC logging.
|
2015-03-21 19:28:04 +03:00
|
|
|
class CycleCollectWithLogsParent final : public PCycleCollectWithLogsParent
|
2014-05-13 21:13:00 +04:00
|
|
|
{
|
|
|
|
public:
|
2016-01-05 12:59:30 +03:00
|
|
|
~CycleCollectWithLogsParent()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(CycleCollectWithLogsParent);
|
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
static bool AllocAndSendConstructor(ContentParent* aManager,
|
|
|
|
bool aDumpAllTraces,
|
|
|
|
nsICycleCollectorLogSink* aSink,
|
|
|
|
nsIDumpGCAndCCLogsCallback* aCallback)
|
|
|
|
{
|
|
|
|
CycleCollectWithLogsParent *actor;
|
|
|
|
FILE* gcLog;
|
|
|
|
FILE* ccLog;
|
|
|
|
nsresult rv;
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
actor = new CycleCollectWithLogsParent(aSink, aCallback);
|
|
|
|
rv = actor->mSink->Open(&gcLog, &ccLog);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
delete actor;
|
|
|
|
return false;
|
2014-05-13 21:13:00 +04:00
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
return aManager->
|
|
|
|
SendPCycleCollectWithLogsConstructor(actor,
|
|
|
|
aDumpAllTraces,
|
|
|
|
FILEToFileDescriptor(gcLog),
|
|
|
|
FILEToFileDescriptor(ccLog));
|
|
|
|
}
|
|
|
|
|
2014-05-13 21:13:00 +04:00
|
|
|
private:
|
2016-11-15 06:26:00 +03:00
|
|
|
virtual mozilla::ipc::IPCResult RecvCloseGCLog() override
|
2016-01-05 12:59:30 +03:00
|
|
|
{
|
|
|
|
Unused << mSink->CloseGCLog();
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
virtual mozilla::ipc::IPCResult RecvCloseCCLog() override
|
2016-01-05 12:59:30 +03:00
|
|
|
{
|
|
|
|
Unused << mSink->CloseCCLog();
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
virtual mozilla::ipc::IPCResult Recv__delete__() override
|
2016-01-05 12:59:30 +03:00
|
|
|
{
|
|
|
|
// Report completion to mCallback only on successful
|
|
|
|
// completion of the protocol.
|
|
|
|
nsCOMPtr<nsIFile> gcLog, ccLog;
|
|
|
|
mSink->GetGcLog(getter_AddRefs(gcLog));
|
|
|
|
mSink->GetCcLog(getter_AddRefs(ccLog));
|
|
|
|
Unused << mCallback->OnDump(gcLog, ccLog, /* parent = */ false);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
virtual void ActorDestroy(ActorDestroyReason aReason) override
|
|
|
|
{
|
|
|
|
// If the actor is unexpectedly destroyed, we deliberately
|
|
|
|
// don't call Close[GC]CLog on the sink, because the logs may
|
|
|
|
// be incomplete. See also the nsCycleCollectorLogSinkToFile
|
|
|
|
// implementaiton of those methods, and its destructor.
|
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
CycleCollectWithLogsParent(nsICycleCollectorLogSink *aSink,
|
|
|
|
nsIDumpGCAndCCLogsCallback *aCallback)
|
|
|
|
: mSink(aSink), mCallback(aCallback)
|
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(CycleCollectWithLogsParent);
|
|
|
|
}
|
2014-05-13 21:13:00 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsICycleCollectorLogSink> mSink;
|
|
|
|
nsCOMPtr<nsIDumpGCAndCCLogsCallback> mCallback;
|
2014-05-13 21:13:00 +04:00
|
|
|
};
|
|
|
|
|
2013-11-06 07:58:20 +04:00
|
|
|
// A memory reporter for ContentParent objects themselves.
|
2015-03-21 19:28:04 +03:00
|
|
|
class ContentParentsMemoryReporter final : public nsIMemoryReporter
|
2013-07-18 01:31:10 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
~ContentParentsMemoryReporter() {}
|
2013-07-18 01:31:10 +04:00
|
|
|
public:
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSIMEMORYREPORTER
|
2013-11-06 07:58:20 +04:00
|
|
|
};
|
2013-12-08 09:39:47 +04:00
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS(ContentParentsMemoryReporter, nsIMemoryReporter)
|
2013-07-18 01:31:10 +04:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2016-08-24 08:23:45 +03:00
|
|
|
ContentParentsMemoryReporter::CollectReports(
|
|
|
|
nsIHandleReportCallback* aHandleReport,
|
|
|
|
nsISupports* aData,
|
|
|
|
bool aAnonymize)
|
2013-07-18 01:31:10 +04:00
|
|
|
{
|
2016-02-02 18:36:30 +03:00
|
|
|
AutoTArray<ContentParent*, 16> cps;
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentParent::GetAllEvenIfDead(cps);
|
2013-07-18 01:31:10 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
for (uint32_t i = 0; i < cps.Length(); i++) {
|
|
|
|
ContentParent* cp = cps[i];
|
|
|
|
MessageChannel* channel = cp->GetIPCChannel();
|
2013-07-18 01:31:10 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsString friendlyName;
|
|
|
|
cp->FriendlyName(friendlyName, aAnonymize);
|
2013-07-18 01:31:10 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
cp->AddRef();
|
|
|
|
nsrefcnt refcnt = cp->Release();
|
2013-07-18 01:31:10 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
const char* channelStr = "no channel";
|
|
|
|
uint32_t numQueuedMessages = 0;
|
|
|
|
if (channel) {
|
|
|
|
if (channel->Unsound_IsClosed()) {
|
|
|
|
channelStr = "closed channel";
|
|
|
|
} else {
|
|
|
|
channelStr = "open channel";
|
|
|
|
}
|
|
|
|
numQueuedMessages = channel->Unsound_NumQueuedMessages();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPrintfCString path("queued-ipc-messages/content-parent"
|
2016-12-14 19:32:21 +03:00
|
|
|
"(%s, pid=%d, %s, 0x%p, refcnt=%" PRIuPTR ")",
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_ConvertUTF16toUTF8(friendlyName).get(),
|
|
|
|
cp->Pid(), channelStr,
|
|
|
|
static_cast<nsIContentParent*>(cp), refcnt);
|
|
|
|
|
|
|
|
NS_NAMED_LITERAL_CSTRING(desc,
|
|
|
|
"The number of unset IPC messages held in this ContentParent's "
|
|
|
|
"channel. A large value here might indicate that we're leaking "
|
|
|
|
"messages. Similarly, a ContentParent object for a process that's no "
|
|
|
|
"longer running could indicate that we're leaking ContentParents.");
|
|
|
|
|
2016-08-24 08:23:45 +03:00
|
|
|
aHandleReport->Callback(/* process */ EmptyCString(), path,
|
|
|
|
KIND_OTHER, UNITS_COUNT,
|
|
|
|
numQueuedMessages, desc, aData);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2013-07-18 01:31:10 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
return NS_OK;
|
2013-07-18 01:31:10 +04:00
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:32 +03:00
|
|
|
nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* ContentParent::sBrowserContentParents;
|
2016-11-02 02:02:43 +03:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
class ScriptableCPInfo final : public nsIContentProcessInfo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit ScriptableCPInfo(ContentParent* aParent)
|
|
|
|
: mContentParent(aParent)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mContentParent);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSICONTENTPROCESSINFO
|
|
|
|
|
|
|
|
void ProcessDied()
|
|
|
|
{
|
|
|
|
mContentParent = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
~ScriptableCPInfo()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(!mContentParent, "must call ProcessDied");
|
|
|
|
}
|
|
|
|
|
|
|
|
ContentParent* mContentParent;
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(ScriptableCPInfo, nsIContentProcessInfo)
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
ScriptableCPInfo::GetIsAlive(bool* aIsAlive)
|
|
|
|
{
|
|
|
|
*aIsAlive = mContentParent != nullptr;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
ScriptableCPInfo::GetProcessId(int32_t* aPID)
|
|
|
|
{
|
|
|
|
if (!mContentParent) {
|
|
|
|
*aPID = -1;
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aPID = mContentParent->Pid();
|
|
|
|
if (*aPID == -1) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
ScriptableCPInfo::GetOpener(nsIContentProcessInfo** aInfo)
|
|
|
|
{
|
|
|
|
*aInfo = nullptr;
|
|
|
|
if (!mContentParent) {
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ContentParent* opener = mContentParent->Opener()) {
|
|
|
|
nsCOMPtr<nsIContentProcessInfo> info = opener->ScriptableHelper();
|
|
|
|
info.forget(aInfo);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-03-07 22:00:28 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
ScriptableCPInfo::GetTabCount(int32_t* aTabCount)
|
|
|
|
{
|
|
|
|
if (!mContentParent) {
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
|
|
|
*aTabCount = cpm->GetTabParentCountByProcessId(mContentParent->ChildID());
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-11-02 02:02:43 +03:00
|
|
|
NS_IMETHODIMP
|
2018-03-01 22:19:56 +03:00
|
|
|
ScriptableCPInfo::GetMessageManager(nsISupports** aMessenger)
|
2016-11-02 02:02:43 +03:00
|
|
|
{
|
|
|
|
*aMessenger = nullptr;
|
|
|
|
if (!mContentParent) {
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
2018-04-16 16:18:48 +03:00
|
|
|
RefPtr<ProcessMessageManager> manager = mContentParent->GetMessageManager();
|
2016-11-02 02:02:43 +03:00
|
|
|
manager.forget(aMessenger);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-05-23 09:47:58 +03:00
|
|
|
ProcessID
|
|
|
|
GetTelemetryProcessID(const nsAString& remoteType)
|
|
|
|
{
|
|
|
|
// OOP WebExtensions run in a content process.
|
|
|
|
// For Telemetry though we want to break out collected data from the WebExtensions process into
|
|
|
|
// a separate bucket, to make sure we can analyze it separately and avoid skewing normal content
|
|
|
|
// process metrics.
|
|
|
|
return remoteType.EqualsLiteral(EXTENSION_REMOTE_TYPE) ? ProcessID::Extension : ProcessID::Content;
|
|
|
|
}
|
|
|
|
|
2016-11-02 02:02:43 +03:00
|
|
|
} // anonymous namespace
|
|
|
|
|
2017-05-29 13:38:46 +03:00
|
|
|
nsDataHashtable<nsUint32HashKey, ContentParent*>* ContentParent::sJSPluginContentParents;
|
2013-04-26 04:53:26 +04:00
|
|
|
nsTArray<ContentParent*>* ContentParent::sPrivateContent;
|
2013-07-18 01:31:10 +04:00
|
|
|
StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
|
2015-10-08 08:13:09 +03:00
|
|
|
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
|
|
|
|
UniquePtr<SandboxBrokerPolicyFactory> ContentParent::sSandboxBrokerPolicyFactory;
|
|
|
|
#endif
|
2017-04-17 01:52:02 +03:00
|
|
|
uint64_t ContentParent::sNextTabParentId = 0;
|
|
|
|
nsDataHashtable<nsUint64HashKey, TabParent*> ContentParent::sNextTabParents;
|
2009-08-12 20:18:08 +04:00
|
|
|
|
2012-12-28 13:45:16 +04:00
|
|
|
// This is true when subprocess launching is enabled. This is the
|
2017-08-02 03:09:26 +03:00
|
|
|
// case between StartUp() and ShutDown().
|
2012-12-28 13:45:16 +04:00
|
|
|
static bool sCanLaunchSubprocesses;
|
|
|
|
|
2015-04-10 18:56:49 +03:00
|
|
|
// Set to true if the DISABLE_UNSAFE_CPOW_WARNINGS environment variable is
|
|
|
|
// set.
|
|
|
|
static bool sDisableUnsafeCPOWWarnings = false;
|
|
|
|
|
2011-09-30 11:00:48 +04:00
|
|
|
// The first content child has ID 1, so the chrome process can have ID 0.
|
2012-08-22 19:56:38 +04:00
|
|
|
static uint64_t gContentChildID = 1;
|
2011-09-30 11:00:48 +04:00
|
|
|
|
2014-02-13 10:55:28 +04:00
|
|
|
static const char* sObserverTopics[] = {
|
2016-01-05 12:59:30 +03:00
|
|
|
"xpcom-shutdown",
|
|
|
|
"profile-before-change",
|
|
|
|
NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC,
|
|
|
|
NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC,
|
2016-11-17 19:35:24 +03:00
|
|
|
NS_IPC_CAPTIVE_PORTAL_SET_STATE,
|
2016-01-05 12:59:30 +03:00
|
|
|
"memory-pressure",
|
|
|
|
"child-gc-request",
|
|
|
|
"child-cc-request",
|
|
|
|
"child-mmu-request",
|
2018-01-12 01:14:09 +03:00
|
|
|
"child-ghost-request",
|
2016-01-05 12:59:30 +03:00
|
|
|
"last-pb-context-exited",
|
|
|
|
"file-watcher-update",
|
2014-02-13 10:55:28 +04:00
|
|
|
#ifdef ACCESSIBILITY
|
2016-01-05 12:59:30 +03:00
|
|
|
"a11y-init-or-shutdown",
|
2014-11-18 20:50:25 +03:00
|
|
|
#endif
|
2016-08-08 06:04:55 +03:00
|
|
|
"cacheservice:empty-cache",
|
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
|
|
|
"intl:app-locales-changed",
|
|
|
|
"intl:requested-locales-changed",
|
2018-04-19 14:18:50 +03:00
|
|
|
"cookie-changed",
|
|
|
|
"private-cookie-changed",
|
2018-06-20 18:57:50 +03:00
|
|
|
"clear-site-data-reload-needed",
|
2014-02-13 10:55:28 +04:00
|
|
|
};
|
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
// PreallocateProcess is called by the PreallocatedProcessManager.
|
|
|
|
// ContentParent then takes this process back within GetNewOrUsedBrowserProcess.
|
|
|
|
/*static*/ already_AddRefed<ContentParent>
|
|
|
|
ContentParent::PreallocateProcess()
|
|
|
|
{
|
|
|
|
RefPtr<ContentParent> process =
|
|
|
|
new ContentParent(/* aOpener = */ nullptr,
|
2018-07-22 14:52:42 +03:00
|
|
|
NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
|
|
|
|
eNotRecordingOrReplaying,
|
|
|
|
/* aRecordingFile = */ EmptyString());
|
2017-02-01 15:34:24 +03:00
|
|
|
|
2017-07-11 18:30:08 +03:00
|
|
|
PreallocatedProcessManager::AddBlocker(process);
|
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
if (!process->LaunchSubprocess(PROCESS_PRIORITY_PREALLOC)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return process.forget();
|
|
|
|
}
|
|
|
|
|
2012-08-16 05:46:03 +04:00
|
|
|
/*static*/ void
|
|
|
|
ContentParent::StartUp()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// We could launch sub processes from content process
|
|
|
|
// FIXME Bug 1023701 - Stop using ContentParent static methods in
|
|
|
|
// child process
|
|
|
|
sCanLaunchSubprocesses = true;
|
2014-06-18 21:22:05 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!XRE_IsParentProcess()) {
|
|
|
|
return;
|
|
|
|
}
|
2014-06-18 21:22:05 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Note: This reporter measures all ContentParents.
|
|
|
|
RegisterStrongMemoryReporter(new ContentParentsMemoryReporter());
|
2013-07-18 01:31:10 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
BackgroundChild::Startup();
|
2017-11-09 08:19:59 +03:00
|
|
|
ClientManager::Startup();
|
2013-11-27 11:59:41 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
sDisableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
|
2015-10-08 08:13:09 +03:00
|
|
|
|
|
|
|
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
|
2016-01-05 12:59:30 +03:00
|
|
|
sSandboxBrokerPolicyFactory = MakeUnique<SandboxBrokerPolicyFactory>();
|
2015-10-08 08:13:09 +03:00
|
|
|
#endif
|
2012-08-16 05:46:03 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void
|
|
|
|
ContentParent::ShutDown()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// No-op for now. We rely on normal process shutdown and
|
|
|
|
// ClearOnShutdown() to clean up our state.
|
|
|
|
sCanLaunchSubprocesses = false;
|
2015-10-08 08:13:09 +03:00
|
|
|
|
|
|
|
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
|
2016-01-05 12:59:30 +03:00
|
|
|
sSandboxBrokerPolicyFactory = nullptr;
|
2015-10-08 08:13:09 +03:00
|
|
|
#endif
|
2012-12-28 13:45:16 +04:00
|
|
|
}
|
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
/*static*/ uint32_t
|
|
|
|
ContentParent::GetPoolSize(const nsAString& aContentProcessType)
|
2009-08-12 20:18:08 +04:00
|
|
|
{
|
2017-02-01 15:34:24 +03:00
|
|
|
if (!sBrowserContentParents) {
|
|
|
|
return 0;
|
2017-01-26 22:20:44 +03:00
|
|
|
}
|
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
nsTArray<ContentParent*>* parents =
|
|
|
|
sBrowserContentParents->Get(aContentProcessType);
|
|
|
|
|
|
|
|
return parents ? parents->Length() : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*static*/ nsTArray<ContentParent*>&
|
|
|
|
ContentParent::GetOrCreatePool(const nsAString& aContentProcessType)
|
|
|
|
{
|
2016-11-24 18:08:32 +03:00
|
|
|
if (!sBrowserContentParents) {
|
|
|
|
sBrowserContentParents =
|
|
|
|
new nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>;
|
|
|
|
}
|
2012-08-09 06:58:06 +04:00
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
return *sBrowserContentParents->LookupOrAdd(aContentProcessType);
|
|
|
|
}
|
2016-10-21 23:56:51 +03:00
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
/*static*/ uint32_t
|
|
|
|
ContentParent::GetMaxProcessCount(const nsAString& aContentProcessType)
|
|
|
|
{
|
2017-04-18 00:36:04 +03:00
|
|
|
if (aContentProcessType.EqualsLiteral("web")) {
|
|
|
|
return GetMaxWebProcessCount();
|
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:32 +03:00
|
|
|
nsAutoCString processCountPref("dom.ipc.processCount.");
|
2017-02-01 15:34:24 +03:00
|
|
|
processCountPref.Append(NS_ConvertUTF16toUTF8(aContentProcessType));
|
2017-03-30 19:44:20 +03:00
|
|
|
|
|
|
|
int32_t maxContentParents;
|
2016-11-24 18:08:32 +03:00
|
|
|
if (NS_FAILED(Preferences::GetInt(processCountPref.get(), &maxContentParents))) {
|
2016-10-21 23:56:51 +03:00
|
|
|
maxContentParents = Preferences::GetInt("dom.ipc.processCount", 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (maxContentParents < 1) {
|
|
|
|
maxContentParents = 1;
|
|
|
|
}
|
2015-05-11 10:24:40 +03:00
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
return static_cast<uint32_t>(maxContentParents);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ bool
|
|
|
|
ContentParent::IsMaxProcessCountReached(const nsAString& aContentProcessType)
|
|
|
|
{
|
|
|
|
return GetPoolSize(aContentProcessType) >= GetMaxProcessCount(aContentProcessType);
|
|
|
|
}
|
|
|
|
|
2017-02-21 13:27:23 +03:00
|
|
|
/*static*/ void
|
|
|
|
ContentParent::ReleaseCachedProcesses()
|
|
|
|
{
|
2017-04-04 18:45:20 +03:00
|
|
|
if (!GetPoolSize(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-02-21 13:27:23 +03:00
|
|
|
// We might want to extend this for other process types as well in the future...
|
|
|
|
nsTArray<ContentParent*>& contentParents = GetOrCreatePool(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE));
|
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
|
|
|
nsTArray<ContentParent*> toRelease;
|
|
|
|
|
|
|
|
// Shuting down these processes will change the array so let's use another array for the removal.
|
|
|
|
for (auto* cp : contentParents) {
|
|
|
|
nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(cp->mChildID);
|
|
|
|
if (!tabIds.Length()) {
|
|
|
|
toRelease.AppendElement(cp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto* cp : toRelease) {
|
|
|
|
// Start a soft shutdown.
|
|
|
|
cp->ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
|
|
|
|
// Make sure we don't select this process for new tabs.
|
|
|
|
cp->MarkAsDead();
|
|
|
|
// Make sure that this process is no longer accessible from JS by its message manager.
|
|
|
|
cp->ShutDownMessageManager();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
/*static*/ already_AddRefed<ContentParent>
|
2017-03-07 22:00:28 +03:00
|
|
|
ContentParent::MinTabSelect(const nsTArray<ContentParent*>& aContentParents,
|
2017-02-01 15:34:24 +03:00
|
|
|
ContentParent* aOpener, int32_t aMaxContentParents)
|
|
|
|
{
|
|
|
|
uint32_t maxSelectable = std::min(static_cast<uint32_t>(aContentParents.Length()),
|
|
|
|
static_cast<uint32_t>(aMaxContentParents));
|
2017-03-07 22:00:28 +03:00
|
|
|
uint32_t min = INT_MAX;
|
|
|
|
RefPtr<ContentParent> candidate;
|
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < maxSelectable; i++) {
|
|
|
|
ContentParent* p = aContentParents[i];
|
2017-02-01 15:34:24 +03:00
|
|
|
NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in sBrowserContentParents?");
|
|
|
|
if (p->mOpener == aOpener) {
|
2017-03-07 22:00:28 +03:00
|
|
|
uint32_t tabCount = cpm->GetTabParentCountByProcessId(p->ChildID());
|
|
|
|
if (tabCount < min) {
|
|
|
|
candidate = p;
|
|
|
|
min = tabCount;
|
|
|
|
}
|
2017-02-01 15:34:24 +03:00
|
|
|
}
|
2017-03-07 22:00:28 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
|
2017-03-07 22:00:28 +03:00
|
|
|
return candidate.forget();
|
2017-02-01 15:34:24 +03:00
|
|
|
}
|
|
|
|
|
2018-07-22 14:52:42 +03:00
|
|
|
static bool
|
|
|
|
CreateTemporaryRecordingFile(nsAString& aResult)
|
|
|
|
{
|
|
|
|
unsigned long elapsed = (TimeStamp::Now() - TimeStamp::ProcessCreation()).ToMilliseconds();
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFile> file;
|
|
|
|
return !NS_FAILED(NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(file)))
|
|
|
|
&& !NS_FAILED(file->AppendNative(nsPrintfCString("Recording%lu", elapsed)))
|
|
|
|
&& !NS_FAILED(file->GetPath(aResult));
|
|
|
|
}
|
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
/*static*/ already_AddRefed<ContentParent>
|
2018-07-22 14:52:42 +03:00
|
|
|
ContentParent::GetNewOrUsedBrowserProcess(Element* aFrameElement,
|
|
|
|
const nsAString& aRemoteType,
|
2017-02-01 15:34:24 +03:00
|
|
|
ProcessPriority aPriority,
|
2017-08-16 14:00:22 +03:00
|
|
|
ContentParent* aOpener,
|
|
|
|
bool aPreferUsed)
|
2017-02-01 15:34:24 +03:00
|
|
|
{
|
2018-07-22 14:52:42 +03:00
|
|
|
// Figure out if this process will be recording or replaying, and which file
|
|
|
|
// to use for the recording.
|
|
|
|
RecordReplayState recordReplayState = eNotRecordingOrReplaying;
|
|
|
|
nsAutoString recordingFile;
|
|
|
|
if (aFrameElement) {
|
|
|
|
aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::ReplayExecution, recordingFile);
|
|
|
|
if (!recordingFile.IsEmpty()) {
|
|
|
|
recordReplayState = eReplaying;
|
|
|
|
} else {
|
|
|
|
aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::RecordExecution, recordingFile);
|
|
|
|
if (recordingFile.IsEmpty() && recordreplay::parent::SaveAllRecordingsDirectory()) {
|
|
|
|
recordingFile.AssignLiteral("*");
|
|
|
|
}
|
|
|
|
if (!recordingFile.IsEmpty()) {
|
|
|
|
if (recordingFile.EqualsLiteral("*") && !CreateTemporaryRecordingFile(recordingFile)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
recordReplayState = eRecording;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-10 00:30:59 +03:00
|
|
|
nsTArray<ContentParent*>& contentParents = GetOrCreatePool(aRemoteType);
|
|
|
|
uint32_t maxContentParents = GetMaxProcessCount(aRemoteType);
|
2018-07-22 14:52:42 +03:00
|
|
|
if (recordReplayState != eNotRecordingOrReplaying) {
|
|
|
|
// Fall through and always create a new process when recording or replaying.
|
|
|
|
} else if (aRemoteType.EqualsLiteral(LARGE_ALLOCATION_REMOTE_TYPE)) {
|
2017-02-10 01:49:46 +03:00
|
|
|
// We never want to re-use Large-Allocation processes.
|
2016-11-02 02:02:43 +03:00
|
|
|
if (contentParents.Length() >= maxContentParents) {
|
2018-07-22 14:52:42 +03:00
|
|
|
return GetNewOrUsedBrowserProcess(aFrameElement,
|
|
|
|
NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
|
2017-02-10 01:49:46 +03:00
|
|
|
aPriority,
|
|
|
|
aOpener);
|
|
|
|
}
|
2016-11-02 02:02:43 +03:00
|
|
|
} else {
|
2017-08-16 14:00:22 +03:00
|
|
|
uint32_t numberOfParents = contentParents.Length();
|
|
|
|
nsTArray<nsIContentProcessInfo*> infos(numberOfParents);
|
2016-11-02 02:02:43 +03:00
|
|
|
for (auto* cp : contentParents) {
|
|
|
|
infos.AppendElement(cp->mScriptableHelper);
|
|
|
|
}
|
|
|
|
|
2017-08-16 14:00:22 +03:00
|
|
|
if (aPreferUsed && numberOfParents) {
|
|
|
|
// For the preloaded browser we don't want to create a new process but reuse an
|
|
|
|
// existing one.
|
|
|
|
maxContentParents = numberOfParents;
|
|
|
|
}
|
|
|
|
|
2016-11-02 02:02:43 +03:00
|
|
|
nsCOMPtr<nsIContentProcessProvider> cpp =
|
|
|
|
do_GetService("@mozilla.org/ipc/processselector;1");
|
|
|
|
nsIContentProcessInfo* openerInfo = aOpener ? aOpener->mScriptableHelper.get() : nullptr;
|
|
|
|
int32_t index;
|
|
|
|
if (cpp &&
|
|
|
|
NS_SUCCEEDED(cpp->ProvideProcess(aRemoteType, openerInfo,
|
|
|
|
infos.Elements(), infos.Length(),
|
2017-03-30 19:44:20 +03:00
|
|
|
maxContentParents, &index))) {
|
2016-11-02 02:02:43 +03:00
|
|
|
// If the provider returned an existing ContentParent, use that one.
|
|
|
|
if (0 <= index && static_cast<uint32_t>(index) <= maxContentParents) {
|
|
|
|
RefPtr<ContentParent> retval = contentParents[index];
|
|
|
|
return retval.forget();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// If there was a problem with the JS chooser, fall back to a random
|
|
|
|
// selection.
|
|
|
|
NS_WARNING("nsIContentProcessProvider failed to return a process");
|
|
|
|
RefPtr<ContentParent> random;
|
|
|
|
if (contentParents.Length() >= maxContentParents &&
|
2017-03-07 22:00:28 +03:00
|
|
|
(random = MinTabSelect(contentParents, aOpener, maxContentParents))) {
|
2016-11-02 02:02:43 +03:00
|
|
|
return random.forget();
|
|
|
|
}
|
|
|
|
}
|
2017-02-10 01:49:46 +03:00
|
|
|
|
2016-11-02 02:02:43 +03:00
|
|
|
// Try to take the preallocated process only for the default process type.
|
2017-05-30 14:46:41 +03:00
|
|
|
// The preallocated process manager might not had the chance yet to release the process
|
|
|
|
// after a very recent ShutDownProcess, let's make sure we don't try to reuse a process
|
|
|
|
// that is being shut down.
|
2016-11-02 02:02:43 +03:00
|
|
|
RefPtr<ContentParent> p;
|
|
|
|
if (aRemoteType.EqualsLiteral(DEFAULT_REMOTE_TYPE) &&
|
2017-05-30 14:46:41 +03:00
|
|
|
(p = PreallocatedProcessManager::Take()) &&
|
|
|
|
!p->mShutdownPending) {
|
2016-11-02 02:02:43 +03:00
|
|
|
// For pre-allocated process we have not set the opener yet.
|
|
|
|
p->mOpener = aOpener;
|
|
|
|
contentParents.AppendElement(p);
|
2017-05-30 14:46:41 +03:00
|
|
|
p->mActivateTS = TimeStamp::Now();
|
2017-02-10 01:49:46 +03:00
|
|
|
return p.forget();
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2016-11-02 13:13:37 +03:00
|
|
|
|
2016-11-02 02:02:43 +03:00
|
|
|
// Create a new process from scratch.
|
2018-07-22 14:52:42 +03:00
|
|
|
RefPtr<ContentParent> p = new ContentParent(aOpener, aRemoteType, recordReplayState, recordingFile);
|
2017-02-01 15:34:24 +03:00
|
|
|
|
2017-07-11 18:30:08 +03:00
|
|
|
// Until the new process is ready let's not allow to start up any preallocated processes.
|
|
|
|
PreallocatedProcessManager::AddBlocker(p);
|
|
|
|
|
2016-11-02 02:02:43 +03:00
|
|
|
if (!p->LaunchSubprocess(aPriority)) {
|
|
|
|
return nullptr;
|
2017-02-01 15:34:24 +03:00
|
|
|
}
|
2016-10-19 04:54:12 +03:00
|
|
|
|
2018-07-22 14:52:42 +03:00
|
|
|
if (recordReplayState == eNotRecordingOrReplaying) {
|
|
|
|
contentParents.AppendElement(p);
|
|
|
|
}
|
|
|
|
|
2017-05-30 14:46:41 +03:00
|
|
|
p->mActivateTS = TimeStamp::Now();
|
2016-01-05 12:59:30 +03:00
|
|
|
return p.forget();
|
2011-08-02 23:35:42 +04:00
|
|
|
}
|
2010-12-26 23:03:52 +03:00
|
|
|
|
2017-05-29 13:38:46 +03:00
|
|
|
/*static*/ already_AddRefed<ContentParent>
|
|
|
|
ContentParent::GetNewOrUsedJSPluginProcess(uint32_t aPluginID,
|
|
|
|
const hal::ProcessPriority& aPriority)
|
|
|
|
{
|
|
|
|
RefPtr<ContentParent> p;
|
|
|
|
if (sJSPluginContentParents) {
|
|
|
|
p = sJSPluginContentParents->Get(aPluginID);
|
|
|
|
} else {
|
|
|
|
sJSPluginContentParents =
|
|
|
|
new nsDataHashtable<nsUint32HashKey, ContentParent*>();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p) {
|
|
|
|
return p.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
p = new ContentParent(aPluginID);
|
|
|
|
|
|
|
|
if (!p->LaunchSubprocess(aPriority)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
sJSPluginContentParents->Put(aPluginID, p);
|
|
|
|
|
|
|
|
return p.forget();
|
|
|
|
}
|
|
|
|
|
2013-02-15 00:41:30 +04:00
|
|
|
/*static*/ ProcessPriority
|
2013-07-24 03:39:17 +04:00
|
|
|
ContentParent::GetInitialProcessPriority(Element* aFrameElement)
|
2013-02-15 00:41:30 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// Frames with mozapptype == critical which are expecting a system message
|
|
|
|
// get FOREGROUND_HIGH priority.
|
2013-02-15 00:41:30 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!aFrameElement) {
|
|
|
|
return PROCESS_PRIORITY_FOREGROUND;
|
|
|
|
}
|
2013-02-15 00:41:30 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(aFrameElement);
|
|
|
|
if (!browserFrame) {
|
|
|
|
return PROCESS_PRIORITY_FOREGROUND;
|
|
|
|
}
|
2013-02-15 00:41:30 +04:00
|
|
|
|
2016-04-20 20:04:13 +03:00
|
|
|
return PROCESS_PRIORITY_FOREGROUND;
|
2013-02-15 00:41:30 +04:00
|
|
|
}
|
|
|
|
|
2015-04-07 16:17:27 +03:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
extern const wchar_t* kPluginWidgetContentParentProperty;
|
|
|
|
|
|
|
|
/*static*/ void
|
|
|
|
ContentParent::SendAsyncUpdate(nsIWidget* aWidget)
|
|
|
|
{
|
|
|
|
if (!aWidget || aWidget->Destroyed()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Fire off an async request to the plugin to paint its window
|
|
|
|
HWND hwnd = (HWND)aWidget->GetNativeData(NS_NATIVE_WINDOW);
|
|
|
|
NS_ASSERTION(hwnd, "Expected valid hwnd value.");
|
|
|
|
ContentParent* cp = reinterpret_cast<ContentParent*>(
|
|
|
|
::GetPropW(hwnd, kPluginWidgetContentParentProperty));
|
|
|
|
if (cp && !cp->IsDestroyed()) {
|
2016-09-15 02:28:26 +03:00
|
|
|
Unused << cp->SendUpdateWindow((uintptr_t)hwnd);
|
2015-04-07 16:17:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // defined(XP_WIN)
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2014-06-11 09:44:13 +04:00
|
|
|
ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
|
|
|
|
const hal::ProcessPriority& aPriority,
|
2014-10-29 21:11:00 +03:00
|
|
|
const TabId& aOpenerTabId,
|
2017-04-05 13:42:00 +03:00
|
|
|
const TabId& aTabId,
|
2014-10-29 21:11:00 +03:00
|
|
|
ContentParentId* aCpId,
|
2017-04-05 13:42:00 +03:00
|
|
|
bool* aIsForBrowser)
|
2014-06-11 09:44:13 +04:00
|
|
|
{
|
|
|
|
#if 0
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!CanOpenBrowser(aContext)) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-06-11 09:44:13 +04:00
|
|
|
#endif
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<ContentParent> cp;
|
|
|
|
MaybeInvalidTabContext tc(aContext);
|
|
|
|
if (!tc.IsValid()) {
|
|
|
|
NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
|
|
|
|
"the child process. (%s)",
|
|
|
|
tc.GetInvalidReason()).get());
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-08-13 10:18:00 +04:00
|
|
|
|
2017-05-29 13:38:46 +03:00
|
|
|
if (tc.GetTabContext().IsJSPlugin()) {
|
|
|
|
cp = GetNewOrUsedJSPluginProcess(tc.GetTabContext().JSPluginId(),
|
|
|
|
aPriority);
|
|
|
|
}
|
|
|
|
else {
|
2018-07-22 14:52:42 +03:00
|
|
|
cp = GetNewOrUsedBrowserProcess(nullptr, NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
|
2017-05-29 13:38:46 +03:00
|
|
|
aPriority, this);
|
|
|
|
}
|
2014-08-13 10:18:00 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!cp) {
|
|
|
|
*aCpId = 0;
|
|
|
|
*aIsForBrowser = false;
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-06-11 09:44:13 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
*aCpId = cp->ChildID();
|
|
|
|
*aIsForBrowser = cp->IsForBrowser();
|
2014-10-29 21:11:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
|
2017-05-29 13:38:46 +03:00
|
|
|
if (cp->IsForJSPlugin()) {
|
|
|
|
// We group all the iframes for a specific JS plugin into one process, regardless of
|
|
|
|
// origin. As a consequence that process can't be a child of the content process that
|
|
|
|
// contains the document with the element loading the plugin. All content processes
|
|
|
|
// need to be able to communicate with the process for the JS plugin.
|
|
|
|
cpm->RegisterRemoteFrame(aTabId, ChildID(), aOpenerTabId, aContext, cp->ChildID());
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
// cp was already added to the ContentProcessManager, this just sets the parent ID.
|
2016-01-05 12:59:30 +03:00
|
|
|
cpm->AddContentProcess(cp, this->ChildID());
|
2014-10-29 21:11:00 +03:00
|
|
|
|
2017-04-05 13:42:00 +03:00
|
|
|
if (cpm->AddGrandchildProcess(this->ChildID(), cp->ChildID()) &&
|
2017-01-16 23:15:11 +03:00
|
|
|
cpm->RegisterRemoteFrame(aTabId, ChildID(), aOpenerTabId, aContext, cp->ChildID())) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-10-29 21:11:00 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2014-06-11 09:44:13 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-01-27 01:40:17 +03:00
|
|
|
ContentParent::RecvBridgeToChildProcess(const ContentParentId& aCpId,
|
|
|
|
Endpoint<PContentBridgeParent>* aEndpoint)
|
2014-10-24 10:29:00 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
|
|
|
|
ContentParent* cp = cpm->GetContentProcessById(aCpId);
|
2014-10-29 21:11:00 +03:00
|
|
|
|
2017-05-29 13:38:46 +03:00
|
|
|
if (cp && cp->CanCommunicateWith(ChildID())) {
|
|
|
|
Endpoint<PContentBridgeParent> parent;
|
|
|
|
Endpoint<PContentBridgeChild> child;
|
2017-01-27 01:40:17 +03:00
|
|
|
|
2017-05-29 13:38:46 +03:00
|
|
|
if (NS_FAILED(PContentBridge::CreateEndpoints(OtherPid(), cp->OtherPid(),
|
|
|
|
&parent, &child))) {
|
|
|
|
return IPC_FAIL(this, "CreateEndpoints failed");
|
|
|
|
}
|
2017-01-27 01:40:17 +03:00
|
|
|
|
2018-05-30 22:15:35 +03:00
|
|
|
*aEndpoint = std::move(parent);
|
2017-01-27 01:40:17 +03:00
|
|
|
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!cp->SendInitContentBridgeChild(std::move(child))) {
|
2017-05-29 13:38:46 +03:00
|
|
|
return IPC_FAIL(this, "SendInitContentBridgeChild failed");
|
2014-10-29 21:11:00 +03:00
|
|
|
}
|
2017-05-29 13:38:46 +03:00
|
|
|
|
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-10-29 21:11:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// You can't bridge to a process you didn't open!
|
|
|
|
KillHard("BridgeToChildProcess");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2014-10-29 21:11:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static nsIDocShell* GetOpenerDocShellHelper(Element* aFrameElement)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// Propagate the private-browsing status of the element's parent
|
|
|
|
// docshell to the remote docshell, via the chrome flags.
|
|
|
|
nsCOMPtr<Element> frameElement = do_QueryInterface(aFrameElement);
|
|
|
|
MOZ_ASSERT(frameElement);
|
2016-01-30 20:05:36 +03:00
|
|
|
nsPIDOMWindowOuter* win = frameElement->OwnerDoc()->GetWindow();
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!win) {
|
|
|
|
NS_WARNING("Remote frame has no window");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
nsIDocShell* docShell = win->GetDocShell();
|
|
|
|
if (!docShell) {
|
|
|
|
NS_WARNING("Remote frame has no docshell");
|
|
|
|
return nullptr;
|
|
|
|
}
|
2014-10-29 21:11:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
return docShell;
|
2014-06-11 09:44:13 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-02-10 13:49:03 +03:00
|
|
|
ContentParent::RecvCreateGMPService()
|
|
|
|
{
|
2017-01-05 23:55:57 +03:00
|
|
|
Endpoint<PGMPServiceParent> parent;
|
|
|
|
Endpoint<PGMPServiceChild> child;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
rv = PGMPService::CreateEndpoints(base::GetCurrentProcId(),
|
|
|
|
OtherPid(),
|
|
|
|
&parent, &child);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
MOZ_ASSERT(false, "CreateEndpoints failed");
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!GMPServiceParent::Create(std::move(parent))) {
|
2017-01-05 23:55:57 +03:00
|
|
|
MOZ_ASSERT(false, "GMPServiceParent::Create failed");
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!SendInitGMPService(std::move(child))) {
|
2017-01-05 23:55:57 +03:00
|
|
|
MOZ_ASSERT(false, "SendInitGMPService failed");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
2017-01-05 23:55:57 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-02-10 13:49:03 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-01-26 01:17:17 +03:00
|
|
|
ContentParent::RecvLoadPlugin(const uint32_t& aPluginId,
|
|
|
|
nsresult* aRv,
|
|
|
|
uint32_t* aRunID,
|
|
|
|
Endpoint<PPluginModuleParent>* aEndpoint)
|
2014-10-29 18:05:36 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
*aRv = NS_OK;
|
2017-04-18 09:56:43 +03:00
|
|
|
if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, aRunID, aEndpoint)) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
2014-10-29 18:05:36 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-11-05 00:46:10 +03:00
|
|
|
ContentParent::RecvUngrabPointer(const uint32_t& aTime)
|
|
|
|
{
|
|
|
|
#if !defined(MOZ_WIDGET_GTK)
|
2017-10-25 09:30:31 +03:00
|
|
|
MOZ_CRASH("This message only makes sense on GTK platforms");
|
2015-11-05 00:46:10 +03:00
|
|
|
#else
|
2016-01-05 12:59:30 +03:00
|
|
|
gdk_pointer_ungrab(aTime);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-11-05 00:46:10 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-03-03 00:09:48 +03:00
|
|
|
ContentParent::RecvRemovePermission(const IPC::Principal& aPrincipal,
|
|
|
|
const nsCString& aPermissionType,
|
|
|
|
nsresult* aRv) {
|
|
|
|
*aRv = Permissions::RemovePermission(aPrincipal, aPermissionType.get());
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-03-03 00:09:48 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-01-26 01:17:17 +03:00
|
|
|
ContentParent::RecvConnectPluginBridge(const uint32_t& aPluginId,
|
|
|
|
nsresult* aRv,
|
|
|
|
Endpoint<PPluginModuleParent>* aEndpoint)
|
2015-01-17 00:03:27 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
*aRv = NS_OK;
|
|
|
|
// We don't need to get the run ID for the plugin, since we already got it
|
|
|
|
// in the first call to SetupBridge in RecvLoadPlugin, so we pass in a dummy
|
|
|
|
// pointer and just throw it away.
|
|
|
|
uint32_t dummy = 0;
|
2017-04-18 09:56:43 +03:00
|
|
|
if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, &dummy, aEndpoint)) {
|
2017-01-26 01:17:17 +03:00
|
|
|
return IPC_FAIL(this, "SetupBridge failed");
|
2016-11-15 06:26:00 +03:00
|
|
|
}
|
|
|
|
return IPC_OK();
|
2015-01-17 00:03:27 +03:00
|
|
|
}
|
|
|
|
|
2012-08-09 06:58:06 +04:00
|
|
|
/*static*/ TabParent*
|
2016-10-15 04:46:26 +03:00
|
|
|
ContentParent::CreateBrowser(const TabContext& aContext,
|
|
|
|
Element* aFrameElement,
|
2017-04-07 02:46:18 +03:00
|
|
|
ContentParent* aOpenerContentParent,
|
2017-04-17 01:52:02 +03:00
|
|
|
TabParent* aSameTabGroupAs,
|
|
|
|
uint64_t aNextTabParentId)
|
2012-07-14 01:10:20 +04:00
|
|
|
{
|
Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange.
This patch makes the following changes to the macros.
- Removes PROFILER_LABEL_FUNC. It's only suitable for use in functions outside
classes, due to PROFILER_FUNCTION_NAME not getting class names, and it was
mostly misused.
- Removes PROFILER_FUNCTION_NAME. It's no longer used, and __func__ is
universally available now anyway.
- Combines the first two string literal arguments of PROFILER_LABEL and
PROFILER_LABEL_DYNAMIC into a single argument. There was no good reason for
them to be separate, and it forced a '::' in the label, which isn't always
appropriate. Also, the meaning of the "name_space" argument was interpreted
in an interesting variety of ways.
- Adds an "AUTO_" prefix to PROFILER_LABEL and PROFILER_LABEL_DYNAMIC, to make
it clearer they construct RAII objects rather than just being function calls.
(I myself have screwed up the scoping because of this in the past.)
- Fills in the 'js::ProfileEntry::Category::' qualifier within the macro, so
the caller doesn't need to. This makes a *lot* more of the uses fit onto a
single line.
The patch also makes the following changes to the macro uses (beyond those
required by the changes described above).
- Fixes a bunch of labels that had gotten out of sync with the name of the
class and/or function that encloses them.
- Removes a useless PROFILER_LABEL use within a trivial scope in
EventStateManager::DispatchMouseOrPointerEvent(). It clearly wasn't serving
any useful purpose. It also serves as extra evidence that the AUTO_ prefix is
a good idea.
- Tweaks DecodePool::SyncRunIf{Preferred,Possible} so that the labelling is
done within them, instead of at their callsites, because that's a more
standard way of doing things.
--HG--
extra : rebase_source : 318d1bc6fc1425a94aacbf489dd46e4f83211de4
2017-06-22 10:08:53 +03:00
|
|
|
AUTO_PROFILER_LABEL("ContentParent::CreateBrowser", OTHER);
|
2016-01-15 01:03:11 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!sCanLaunchSubprocesses) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2012-12-28 13:45:16 +04:00
|
|
|
|
2017-08-17 01:11:59 +03:00
|
|
|
nsAutoString remoteType;
|
|
|
|
if (!aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType,
|
|
|
|
remoteType)) {
|
|
|
|
remoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
|
|
|
|
}
|
|
|
|
|
2017-04-17 01:52:02 +03:00
|
|
|
if (aNextTabParentId) {
|
|
|
|
if (TabParent* parent =
|
|
|
|
sNextTabParents.GetAndRemove(aNextTabParentId).valueOr(nullptr)) {
|
|
|
|
MOZ_ASSERT(!parent->GetOwnerElement(),
|
|
|
|
"Shouldn't have an owner elemnt before");
|
|
|
|
parent->SetOwnerElement(aFrameElement);
|
|
|
|
return parent;
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-01-16 21:07:50 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
|
|
|
|
bool isInContentProcess = !XRE_IsParentProcess();
|
2017-04-05 13:42:00 +03:00
|
|
|
TabId tabId(nsContentUtils::GenerateTabId());
|
2014-10-29 21:11:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsIDocShell* docShell = GetOpenerDocShellHelper(aFrameElement);
|
|
|
|
TabId openerTabId;
|
|
|
|
if (docShell) {
|
|
|
|
openerTabId = TabParent::GetTabIdFrom(docShell);
|
|
|
|
}
|
2014-05-30 17:29:43 +04:00
|
|
|
|
2017-08-16 14:00:22 +03:00
|
|
|
bool isPreloadBrowser = false;
|
|
|
|
nsAutoString isPreloadBrowserStr;
|
2018-01-04 23:54:37 +03:00
|
|
|
if (aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::preloadedState,
|
2017-08-16 14:00:22 +03:00
|
|
|
isPreloadBrowserStr)) {
|
2018-01-04 23:54:37 +03:00
|
|
|
isPreloadBrowser = isPreloadBrowserStr.EqualsLiteral("preloaded");
|
2017-08-16 14:00:22 +03:00
|
|
|
}
|
|
|
|
|
2016-10-15 04:46:26 +03:00
|
|
|
RefPtr<nsIContentParent> constructorSender;
|
|
|
|
if (isInContentProcess) {
|
2017-05-29 13:38:46 +03:00
|
|
|
MOZ_ASSERT(aContext.IsMozBrowserElement() || aContext.IsJSPlugin());
|
2016-10-15 04:46:26 +03:00
|
|
|
constructorSender = CreateContentBridgeParent(aContext, initialPriority,
|
2017-04-05 13:42:00 +03:00
|
|
|
openerTabId, tabId);
|
2016-10-15 04:46:26 +03:00
|
|
|
} else {
|
|
|
|
if (aOpenerContentParent) {
|
|
|
|
constructorSender = aOpenerContentParent;
|
2016-01-05 12:59:30 +03:00
|
|
|
} else {
|
2017-05-29 13:38:46 +03:00
|
|
|
if (aContext.IsJSPlugin()) {
|
|
|
|
constructorSender =
|
|
|
|
GetNewOrUsedJSPluginProcess(aContext.JSPluginId(),
|
|
|
|
initialPriority);
|
|
|
|
} else {
|
|
|
|
constructorSender =
|
2018-07-22 14:52:42 +03:00
|
|
|
GetNewOrUsedBrowserProcess(aFrameElement, remoteType, initialPriority,
|
2017-08-16 14:00:22 +03:00
|
|
|
nullptr, isPreloadBrowser);
|
2017-05-29 13:38:46 +03:00
|
|
|
}
|
2016-10-15 04:46:26 +03:00
|
|
|
if (!constructorSender) {
|
2012-08-09 06:58:06 +04:00
|
|
|
return nullptr;
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
}
|
2017-04-05 13:42:00 +03:00
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
|
|
|
cpm->RegisterRemoteFrame(tabId,
|
2017-01-16 23:15:11 +03:00
|
|
|
ContentParentId(0),
|
2017-04-05 13:42:00 +03:00
|
|
|
openerTabId,
|
|
|
|
aContext.AsIPCTabContext(),
|
|
|
|
constructorSender->ChildID());
|
2016-10-15 04:46:26 +03:00
|
|
|
}
|
|
|
|
if (constructorSender) {
|
|
|
|
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
|
|
|
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
|
|
|
if (!treeOwner) {
|
|
|
|
return nullptr;
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
2016-10-15 04:46:26 +03:00
|
|
|
nsCOMPtr<nsIWebBrowserChrome> wbc = do_GetInterface(treeOwner);
|
|
|
|
if (!wbc) {
|
2016-01-05 12:59:30 +03:00
|
|
|
return nullptr;
|
|
|
|
}
|
2016-10-15 04:46:26 +03:00
|
|
|
uint32_t chromeFlags = 0;
|
|
|
|
wbc->GetChromeFlags(&chromeFlags);
|
2016-01-05 12:59:30 +03:00
|
|
|
|
2016-10-15 04:46:26 +03:00
|
|
|
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
|
|
|
|
if (loadContext && loadContext->UsePrivateBrowsing()) {
|
|
|
|
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2016-10-15 04:46:26 +03:00
|
|
|
if (docShell->GetAffectPrivateSessionLifetime()) {
|
|
|
|
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
|
2014-08-13 10:18:00 +04:00
|
|
|
}
|
|
|
|
|
2016-10-15 04:46:26 +03:00
|
|
|
if (tabId == 0) {
|
|
|
|
return nullptr;
|
2012-07-14 01:10:20 +04:00
|
|
|
}
|
2016-10-15 04:46:26 +03:00
|
|
|
RefPtr<TabParent> tp(new TabParent(constructorSender, tabId,
|
|
|
|
aContext, chromeFlags));
|
|
|
|
tp->SetInitedByParent();
|
|
|
|
|
|
|
|
PBrowserParent* browser =
|
|
|
|
constructorSender->SendPBrowserConstructor(
|
|
|
|
// DeallocPBrowserParent() releases this ref.
|
|
|
|
tp.forget().take(), tabId,
|
2017-04-07 02:46:18 +03:00
|
|
|
aSameTabGroupAs ? aSameTabGroupAs->GetTabId() : TabId(0),
|
2016-10-15 04:46:26 +03:00
|
|
|
aContext.AsIPCTabContext(),
|
|
|
|
chromeFlags,
|
|
|
|
constructorSender->ChildID(),
|
|
|
|
constructorSender->IsForBrowser());
|
|
|
|
|
2017-02-10 00:30:59 +03:00
|
|
|
if (remoteType.EqualsLiteral(LARGE_ALLOCATION_REMOTE_TYPE)) {
|
2017-01-26 22:20:44 +03:00
|
|
|
// Tell the TabChild object that it was created due to a Large-Allocation
|
2017-02-10 01:49:46 +03:00
|
|
|
// request.
|
|
|
|
Unused << browser->SendAwaitLargeAlloc();
|
2014-08-13 10:18:00 +04:00
|
|
|
}
|
|
|
|
|
2016-10-15 04:46:26 +03:00
|
|
|
if (browser) {
|
|
|
|
RefPtr<TabParent> constructedTabParent = TabParent::GetFrom(browser);
|
|
|
|
constructedTabParent->SetOwnerElement(aFrameElement);
|
|
|
|
return constructedTabParent;
|
2014-07-09 02:56:22 +04:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2016-10-15 04:46:26 +03:00
|
|
|
return nullptr;
|
2012-07-14 01:10:20 +04:00
|
|
|
}
|
|
|
|
|
2014-08-13 10:18:00 +04:00
|
|
|
/*static*/ ContentBridgeParent*
|
|
|
|
ContentParent::CreateContentBridgeParent(const TabContext& aContext,
|
2014-10-29 21:11:00 +03:00
|
|
|
const hal::ProcessPriority& aPriority,
|
|
|
|
const TabId& aOpenerTabId,
|
2017-04-05 13:42:00 +03:00
|
|
|
const TabId& aTabId)
|
2014-08-13 10:18:00 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(aTabId);
|
|
|
|
|
|
|
|
ContentChild* child = ContentChild::GetSingleton();
|
|
|
|
ContentParentId cpId;
|
|
|
|
bool isForBrowser;
|
|
|
|
if (!child->SendCreateChildProcess(aContext.AsIPCTabContext(),
|
|
|
|
aPriority,
|
|
|
|
aOpenerTabId,
|
2017-04-05 13:42:00 +03:00
|
|
|
aTabId,
|
2016-01-05 12:59:30 +03:00
|
|
|
&cpId,
|
2017-04-05 13:42:00 +03:00
|
|
|
&isForBrowser)) {
|
2016-01-05 12:59:30 +03:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
if (cpId == 0) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2017-01-27 01:40:17 +03:00
|
|
|
Endpoint<PContentBridgeParent> endpoint;
|
|
|
|
if (!child->SendBridgeToChildProcess(cpId, &endpoint)) {
|
2016-01-05 12:59:30 +03:00
|
|
|
return nullptr;
|
|
|
|
}
|
2018-05-30 22:15:35 +03:00
|
|
|
ContentBridgeParent* parent = ContentBridgeParent::Create(std::move(endpoint));
|
2016-01-05 12:59:30 +03:00
|
|
|
parent->SetChildID(cpId);
|
|
|
|
parent->SetIsForBrowser(isForBrowser);
|
2017-05-29 13:38:46 +03:00
|
|
|
parent->SetIsForJSPlugin(aContext.IsJSPlugin());
|
2016-01-05 12:59:30 +03:00
|
|
|
return parent;
|
2014-08-13 10:18:00 +04:00
|
|
|
}
|
|
|
|
|
2011-08-02 23:35:42 +04:00
|
|
|
void
|
|
|
|
ContentParent::GetAll(nsTArray<ContentParent*>& aArray)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
aArray.Clear();
|
2012-07-14 01:10:20 +04:00
|
|
|
|
2016-06-07 01:23:43 +03:00
|
|
|
for (auto* cp : AllProcesses(eLive)) {
|
|
|
|
aArray.AppendElement(cp);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2013-07-18 01:31:10 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ContentParent::GetAllEvenIfDead(nsTArray<ContentParent*>& aArray)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
aArray.Clear();
|
2013-07-18 01:31:10 +04:00
|
|
|
|
2016-06-07 01:23:43 +03:00
|
|
|
for (auto* cp : AllProcesses(eAll)) {
|
2016-01-05 12:59:30 +03:00
|
|
|
aArray.AppendElement(cp);
|
|
|
|
}
|
2009-08-12 20:18:08 +04:00
|
|
|
}
|
|
|
|
|
2018-06-30 08:53:12 +03:00
|
|
|
void
|
|
|
|
ContentParent::BroadcastStringBundle(const StringBundleDescriptor& aBundle)
|
|
|
|
{
|
|
|
|
AutoTArray<StringBundleDescriptor, 1> array;
|
|
|
|
array.AppendElement(aBundle);
|
|
|
|
|
|
|
|
for (auto* cp : AllProcesses(eLive)) {
|
|
|
|
Unused << cp->SendRegisterStringBundles(array);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-25 10:18:00 +03:00
|
|
|
const nsAString&
|
|
|
|
ContentParent::GetRemoteType() const
|
|
|
|
{
|
|
|
|
return mRemoteType;
|
|
|
|
}
|
|
|
|
|
2010-12-26 23:03:52 +03:00
|
|
|
void
|
|
|
|
ContentParent::Init()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
if (obs) {
|
|
|
|
size_t length = ArrayLength(sObserverTopics);
|
|
|
|
for (size_t i = 0; i < length; ++i) {
|
|
|
|
obs->AddObserver(this, sObserverTopics[i], false);
|
2010-12-26 23:03:52 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2017-11-13 01:19:43 +03:00
|
|
|
|
|
|
|
// Register ContentParent as an observer for changes to any pref whose prefix
|
|
|
|
// matches the empty string, i.e. all of them.
|
2016-01-05 12:59:30 +03:00
|
|
|
Preferences::AddStrongObserver(this, "");
|
2017-11-13 01:19:43 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (obs) {
|
|
|
|
nsAutoString cpId;
|
|
|
|
cpId.AppendInt(static_cast<uint64_t>(this->ChildID()));
|
|
|
|
obs->NotifyObservers(static_cast<nsIObserver*>(this), "ipc:content-created", cpId.get());
|
|
|
|
}
|
2011-07-21 08:37:32 +04:00
|
|
|
|
|
|
|
#ifdef ACCESSIBILITY
|
2016-01-05 12:59:30 +03:00
|
|
|
// If accessibility is running in chrome process then start it in content
|
|
|
|
// process.
|
|
|
|
if (nsIPresShell::IsAccessibilityActive()) {
|
2016-10-17 22:08:21 +03:00
|
|
|
#if defined(XP_WIN)
|
2017-09-09 00:05:06 +03:00
|
|
|
// Don't init content a11y if we detect an incompat version of JAWS in use.
|
|
|
|
if (!mozilla::a11y::Compatibility::IsOldJAWS()) {
|
|
|
|
Unused << SendActivateA11y(::GetCurrentThreadId(),
|
|
|
|
a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
|
|
|
|
}
|
2016-10-17 22:08:21 +03:00
|
|
|
#else
|
2017-06-07 02:35:51 +03:00
|
|
|
Unused << SendActivateA11y(0, 0);
|
2011-07-21 08:37:32 +04:00
|
|
|
#endif
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
#endif
|
2015-08-11 21:26:27 +03:00
|
|
|
|
2017-05-23 05:45:35 +03:00
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
2017-05-30 22:06:14 +03:00
|
|
|
Unused << SendInitProfiler(ProfilerParent::CreateForProcess(OtherPid()));
|
2017-05-23 05:45:35 +03:00
|
|
|
#endif
|
|
|
|
|
2017-03-03 00:55:09 +03:00
|
|
|
// Ensure that the default set of permissions are avaliable in the content
|
|
|
|
// process before we try to load any URIs in it.
|
|
|
|
EnsurePermissionsByKey(EmptyCString());
|
|
|
|
|
2016-11-01 06:25:19 +03:00
|
|
|
RefPtr<GeckoMediaPluginServiceParent> gmps(GeckoMediaPluginServiceParent::GetSingleton());
|
|
|
|
gmps->UpdateContentProcessGMPCapabilities();
|
2016-11-02 02:02:43 +03:00
|
|
|
|
|
|
|
mScriptableHelper = new ScriptableCPInfo(this);
|
2010-12-26 23:03:52 +03:00
|
|
|
}
|
|
|
|
|
2014-08-01 22:02:55 +04:00
|
|
|
namespace {
|
|
|
|
|
2015-12-04 02:04:28 +03:00
|
|
|
class RemoteWindowContext final : public nsIRemoteWindowContext
|
|
|
|
, public nsIInterfaceRequestor
|
|
|
|
{
|
|
|
|
public:
|
2016-01-05 12:59:30 +03:00
|
|
|
explicit RemoteWindowContext(TabParent* aTabParent)
|
|
|
|
: mTabParent(aTabParent)
|
|
|
|
{
|
|
|
|
}
|
2015-12-04 02:04:28 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSIINTERFACEREQUESTOR
|
|
|
|
NS_DECL_NSIREMOTEWINDOWCONTEXT
|
2015-12-04 02:04:28 +03:00
|
|
|
|
|
|
|
private:
|
2016-01-05 12:59:30 +03:00
|
|
|
~RemoteWindowContext();
|
|
|
|
RefPtr<TabParent> mTabParent;
|
2015-12-04 02:04:28 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(RemoteWindowContext, nsIRemoteWindowContext, nsIInterfaceRequestor)
|
|
|
|
|
|
|
|
RemoteWindowContext::~RemoteWindowContext()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
RemoteWindowContext::GetInterface(const nsIID& aIID, void** aSink)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return QueryInterface(aIID, aSink);
|
2015-12-04 02:04:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2016-03-12 01:31:55 +03:00
|
|
|
RemoteWindowContext::OpenURI(nsIURI* aURI)
|
2015-12-04 02:04:28 +03:00
|
|
|
{
|
2016-03-12 01:31:55 +03:00
|
|
|
mTabParent->LoadURL(aURI);
|
2016-01-05 12:59:30 +03:00
|
|
|
return NS_OK;
|
2015-12-04 02:04:28 +03:00
|
|
|
}
|
|
|
|
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace
|
2014-08-01 22:02:55 +04:00
|
|
|
|
2012-08-16 05:46:03 +04:00
|
|
|
void
|
2015-01-10 21:18:59 +03:00
|
|
|
ContentParent::ShutDownProcess(ShutDownMethod aMethod)
|
2015-01-07 10:33:50 +03:00
|
|
|
{
|
2016-11-02 02:02:43 +03:00
|
|
|
if (mScriptableHelper) {
|
|
|
|
static_cast<ScriptableCPInfo*>(mScriptableHelper.get())->ProcessDied();
|
|
|
|
mScriptableHelper = nullptr;
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Shutting down by sending a shutdown message works differently than the
|
|
|
|
// other methods. We first call Shutdown() in the child. After the child is
|
|
|
|
// ready, it calls FinishShutdown() on us. Then we close the channel.
|
|
|
|
if (aMethod == SEND_SHUTDOWN_MESSAGE) {
|
2018-07-22 14:52:42 +03:00
|
|
|
if (const char* directory = recordreplay::parent::SaveAllRecordingsDirectory()) {
|
|
|
|
// Save a recording for the child process before it shuts down.
|
|
|
|
unsigned long elapsed = (TimeStamp::Now() - TimeStamp::ProcessCreation()).ToMilliseconds();
|
|
|
|
nsCOMPtr<nsIFile> file;
|
|
|
|
if (!NS_FAILED(NS_NewNativeLocalFile(nsDependentCString(directory), false,
|
|
|
|
getter_AddRefs(file))) &&
|
|
|
|
!NS_FAILED(file->AppendNative(nsPrintfCString("Recording%lu", elapsed)))) {
|
|
|
|
bool unused;
|
|
|
|
SaveRecording(file, &unused);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-02 11:53:04 +03:00
|
|
|
if (mIPCOpen && !mShutdownPending) {
|
|
|
|
// Stop sending input events with input priority when shutting down.
|
|
|
|
SetInputPriorityEventEnabled(false);
|
|
|
|
if (SendShutdown()) {
|
|
|
|
mShutdownPending = true;
|
|
|
|
// Start the force-kill timer if we haven't already.
|
|
|
|
StartForceKillTimer();
|
|
|
|
}
|
2015-01-10 21:18:59 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
// If call was not successful, the channel must have been broken
|
|
|
|
// somehow, and we will clean up the error in ActorDestroy.
|
|
|
|
return;
|
|
|
|
}
|
2014-09-27 03:21:57 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
using mozilla::dom::quota::QuotaManagerService;
|
2013-08-07 22:08:52 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (QuotaManagerService* quotaManagerService = QuotaManagerService::Get()) {
|
|
|
|
quotaManagerService->AbortOperationsForProcess(mChildID);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If Close() fails with an error, we'll end up back in this function, but
|
2016-06-10 00:52:33 +03:00
|
|
|
// with aMethod = CLOSE_CHANNEL_WITH_ERROR.
|
2013-08-07 22:08:52 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (aMethod == CLOSE_CHANNEL && !mCalledClose) {
|
|
|
|
// Close() can only be called once: It kicks off the destruction
|
|
|
|
// sequence.
|
|
|
|
mCalledClose = true;
|
|
|
|
Close();
|
|
|
|
}
|
2013-08-07 22:08:52 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
const ManagedContainer<POfflineCacheUpdateParent>& ocuParents =
|
|
|
|
ManagedPOfflineCacheUpdateParent();
|
|
|
|
for (auto iter = ocuParents.ConstIter(); !iter.Done(); iter.Next()) {
|
|
|
|
RefPtr<mozilla::docshell::OfflineCacheUpdateParent> ocuParent =
|
|
|
|
static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(iter.Get()->GetKey());
|
|
|
|
ocuParent->StopSendingMessagesToChild();
|
|
|
|
}
|
2014-11-13 03:31:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// NB: must MarkAsDead() here so that this isn't accidentally
|
|
|
|
// returned from Get*() while in the midst of shutdown.
|
|
|
|
MarkAsDead();
|
2013-08-07 22:08:52 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// A ContentParent object might not get freed until after XPCOM shutdown has
|
|
|
|
// shut down the cycle collector. But by then it's too late to release any
|
|
|
|
// CC'ed objects, so we need to null them out here, while we still can. See
|
|
|
|
// bug 899761.
|
|
|
|
ShutDownMessageManager();
|
2014-05-31 01:03:05 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-01-10 21:18:59 +03:00
|
|
|
ContentParent::RecvFinishShutdown()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// At this point, we already called ShutDownProcess once with
|
|
|
|
// SEND_SHUTDOWN_MESSAGE. To actually close the channel, we call
|
|
|
|
// ShutDownProcess again with CLOSE_CHANNEL.
|
|
|
|
MOZ_ASSERT(mShutdownPending);
|
|
|
|
ShutDownProcess(CLOSE_CHANNEL);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-01-10 21:18:59 +03:00
|
|
|
}
|
|
|
|
|
2014-05-31 01:03:05 +04:00
|
|
|
void
|
|
|
|
ContentParent::ShutDownMessageManager()
|
|
|
|
{
|
|
|
|
if (!mMessageManager) {
|
2016-01-05 12:59:30 +03:00
|
|
|
return;
|
2014-05-31 01:03:05 +04:00
|
|
|
}
|
|
|
|
|
2018-02-16 17:28:31 +03:00
|
|
|
mMessageManager->ReceiveMessage(mMessageManager, nullptr,
|
2016-01-05 12:59:30 +03:00
|
|
|
CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
|
2018-02-16 17:28:31 +03:00
|
|
|
nullptr, nullptr, nullptr, nullptr, IgnoreErrors());
|
2014-05-31 01:03:05 +04:00
|
|
|
|
|
|
|
mMessageManager->Disconnect();
|
|
|
|
mMessageManager = nullptr;
|
2012-07-17 22:27:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-05-30 14:46:41 +03:00
|
|
|
ContentParent::RemoveFromList()
|
2012-07-17 22:27:27 +04:00
|
|
|
{
|
2017-05-29 13:38:46 +03:00
|
|
|
if (IsForJSPlugin()) {
|
|
|
|
if (sJSPluginContentParents) {
|
|
|
|
sJSPluginContentParents->Remove(mJSPluginID);
|
|
|
|
if (!sJSPluginContentParents->Count()) {
|
|
|
|
delete sJSPluginContentParents;
|
|
|
|
sJSPluginContentParents = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (sBrowserContentParents) {
|
2017-06-28 02:03:15 +03:00
|
|
|
if (auto entry = sBrowserContentParents->Lookup(mRemoteType)) {
|
|
|
|
nsTArray<ContentParent*>* contentParents = entry.Data();
|
2016-11-24 18:08:32 +03:00
|
|
|
contentParents->RemoveElement(this);
|
|
|
|
if (contentParents->IsEmpty()) {
|
2017-06-28 02:03:15 +03:00
|
|
|
entry.Remove();
|
2016-11-24 18:08:32 +03:00
|
|
|
}
|
2012-07-17 22:27:27 +04:00
|
|
|
}
|
2017-06-28 02:03:15 +03:00
|
|
|
if (sBrowserContentParents->IsEmpty()) {
|
|
|
|
delete sBrowserContentParents;
|
|
|
|
sBrowserContentParents = nullptr;
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2012-07-17 22:27:27 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (sPrivateContent) {
|
|
|
|
sPrivateContent->RemoveElement(this);
|
|
|
|
if (!sPrivateContent->Length()) {
|
|
|
|
delete sPrivateContent;
|
|
|
|
sPrivateContent = nullptr;
|
2012-07-17 22:27:27 +04:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2017-05-30 14:46:41 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ContentParent::MarkAsTroubled()
|
|
|
|
{
|
|
|
|
RemoveFromList();
|
2017-02-07 19:46:44 +03:00
|
|
|
mIsAvailable = false;
|
|
|
|
}
|
2012-07-17 22:27:27 +04:00
|
|
|
|
2017-02-07 19:46:44 +03:00
|
|
|
void
|
|
|
|
ContentParent::MarkAsDead()
|
|
|
|
{
|
|
|
|
MarkAsTroubled();
|
2016-01-05 12:59:30 +03:00
|
|
|
mIsAlive = false;
|
2012-07-17 22:27:27 +04:00
|
|
|
}
|
|
|
|
|
2013-06-03 14:14:40 +04:00
|
|
|
void
|
|
|
|
ContentParent::OnChannelError()
|
|
|
|
{
|
2017-08-15 22:08:14 +03:00
|
|
|
RefPtr<ContentParent> content(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
PContentParent::OnChannelError();
|
2013-06-03 14:14:40 +04:00
|
|
|
}
|
|
|
|
|
2010-11-24 16:58:21 +03:00
|
|
|
void
|
2012-09-17 12:37:20 +04:00
|
|
|
ContentParent::OnChannelConnected(int32_t pid)
|
2010-11-24 16:58:21 +03:00
|
|
|
{
|
2018-02-16 18:24:21 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2011-02-15 01:34:46 +03:00
|
|
|
|
2018-05-12 03:00:40 +03:00
|
|
|
#ifndef ASYNC_CONTENTPROC_LAUNCH
|
|
|
|
SetOtherProcessId(pid);
|
|
|
|
#endif
|
|
|
|
|
2011-02-15 01:34:46 +03:00
|
|
|
#if defined(ANDROID) || defined(LINUX)
|
2016-01-05 12:59:30 +03:00
|
|
|
// Check nice preference
|
|
|
|
int32_t nice = Preferences::GetInt("dom.ipc.content.nice", 0);
|
2015-04-01 11:40:35 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Environment variable overrides preference
|
|
|
|
char* relativeNicenessStr = getenv("MOZ_CHILD_PROCESS_RELATIVE_NICENESS");
|
|
|
|
if (relativeNicenessStr) {
|
|
|
|
nice = atoi(relativeNicenessStr);
|
|
|
|
}
|
2015-04-01 11:40:35 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
/* make the GUI thread have higher priority on single-cpu devices */
|
|
|
|
nsCOMPtr<nsIPropertyBag2> infoService = do_GetService(NS_SYSTEMINFO_CONTRACTID);
|
|
|
|
if (infoService) {
|
|
|
|
int32_t cpus;
|
|
|
|
nsresult rv = infoService->GetPropertyAsInt32(NS_LITERAL_STRING("cpucount"), &cpus);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
cpus = 1;
|
2010-11-24 16:58:21 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
if (nice != 0 && cpus == 1) {
|
|
|
|
setpriority(PRIO_PROCESS, pid, getpriority(PRIO_PROCESS, pid) + nice);
|
|
|
|
}
|
|
|
|
}
|
2015-04-01 11:40:35 +03:00
|
|
|
#endif
|
2018-02-16 18:24:21 +03:00
|
|
|
|
2018-05-12 03:00:40 +03:00
|
|
|
#if defined(MOZ_CODE_COVERAGE) && defined(ASYNC_CONTENTPROC_LAUNCH)
|
2018-02-16 18:24:21 +03:00
|
|
|
Unused << SendShareCodeCoverageMutex(
|
|
|
|
CodeCoverageHandler::Get()->GetMutexHandle(pid));
|
|
|
|
#endif
|
2010-11-24 16:58:21 +03:00
|
|
|
}
|
|
|
|
|
2011-07-13 10:52:31 +04:00
|
|
|
void
|
2015-02-03 20:09:27 +03:00
|
|
|
ContentParent::ProcessingError(Result aCode, const char* aReason)
|
2011-07-13 10:52:31 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (MsgDropped == aCode) {
|
|
|
|
return;
|
|
|
|
}
|
2018-04-05 22:47:34 +03:00
|
|
|
#ifndef FUZZING
|
2016-01-05 12:59:30 +03:00
|
|
|
// Other errors are big deals.
|
|
|
|
KillHard(aReason);
|
2018-04-05 22:47:34 +03:00
|
|
|
#endif
|
2011-07-13 10:52:31 +04:00
|
|
|
}
|
|
|
|
|
2016-01-08 22:17:39 +03:00
|
|
|
/* static */
|
2014-06-11 09:44:39 +04:00
|
|
|
bool
|
2018-03-25 02:06:01 +03:00
|
|
|
ContentParent::AllocateLayerTreeId(TabParent* aTabParent, layers::LayersId* aId)
|
2016-01-08 22:17:39 +03:00
|
|
|
{
|
|
|
|
return AllocateLayerTreeId(aTabParent->Manager()->AsContentParent(),
|
|
|
|
aTabParent, aTabParent->GetTabId(), aId);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */
|
|
|
|
bool
|
|
|
|
ContentParent::AllocateLayerTreeId(ContentParent* aContent,
|
|
|
|
TabParent* aTopLevel, const TabId& aTabId,
|
2018-03-25 02:06:01 +03:00
|
|
|
layers::LayersId* aId)
|
2014-06-11 09:44:39 +04:00
|
|
|
{
|
2016-05-23 10:28:51 +03:00
|
|
|
GPUProcessManager* gpu = GPUProcessManager::Get();
|
2016-08-16 23:59:13 +03:00
|
|
|
|
2016-05-23 10:28:51 +03:00
|
|
|
*aId = gpu->AllocateLayerTreeId();
|
2016-08-30 14:32:55 +03:00
|
|
|
|
|
|
|
if (!aContent || !aTopLevel) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-16 23:59:13 +03:00
|
|
|
gpu->MapLayerTreeId(*aId, aContent->OtherPid());
|
2014-06-11 09:44:39 +04:00
|
|
|
|
2016-11-29 07:21:27 +03:00
|
|
|
return true;
|
2016-01-08 22:17:39 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-01-08 22:17:39 +03:00
|
|
|
ContentParent::RecvAllocateLayerTreeId(const ContentParentId& aCpId,
|
2018-03-25 02:06:01 +03:00
|
|
|
const TabId& aTabId, layers::LayersId* aId)
|
2016-01-08 22:17:39 +03:00
|
|
|
{
|
|
|
|
// Protect against spoofing by a compromised child. aCpId must either
|
|
|
|
// correspond to the process that this ContentParent represents or be a
|
|
|
|
// child of it.
|
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
2017-01-16 23:15:11 +03:00
|
|
|
RefPtr<ContentParent> contentParent = cpm->GetContentProcessById(aCpId);
|
2018-05-24 22:30:32 +03:00
|
|
|
if (!contentParent ||
|
|
|
|
(ChildID() != aCpId && !contentParent->CanCommunicateWith(ChildID()))) {
|
2017-05-29 13:38:46 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-08 22:17:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetTopLevelTabParentByProcessAndTabId will make sure that aTabId
|
|
|
|
// lives in the process for aCpId.
|
|
|
|
RefPtr<TabParent> browserParent =
|
|
|
|
cpm->GetTopLevelTabParentByProcessAndTabId(aCpId, aTabId);
|
|
|
|
MOZ_ASSERT(contentParent && browserParent);
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
if (!AllocateLayerTreeId(contentParent, browserParent, aTabId, aId)) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
2014-06-11 09:44:39 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-05-29 13:38:46 +03:00
|
|
|
ContentParent::RecvDeallocateLayerTreeId(const ContentParentId& aCpId,
|
2018-03-25 02:06:01 +03:00
|
|
|
const layers::LayersId& aId)
|
2014-06-11 09:44:39 +04:00
|
|
|
{
|
2016-08-16 23:59:13 +03:00
|
|
|
GPUProcessManager* gpu = GPUProcessManager::Get();
|
|
|
|
|
2017-05-29 13:38:46 +03:00
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
|
|
|
RefPtr<ContentParent> contentParent = cpm->GetContentProcessById(aCpId);
|
2018-05-29 20:56:12 +03:00
|
|
|
if (!contentParent || !contentParent->CanCommunicateWith(ChildID())) {
|
2017-05-29 13:38:46 +03:00
|
|
|
return IPC_FAIL(this, "Spoofed DeallocateLayerTreeId call");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!gpu->IsLayerTreeIdMapped(aId, contentParent->OtherPid())) {
|
2016-01-05 12:59:30 +03:00
|
|
|
// You can't deallocate layer tree ids that you didn't allocate
|
|
|
|
KillHard("DeallocateLayerTreeId");
|
|
|
|
}
|
2016-08-16 23:59:13 +03:00
|
|
|
|
2017-05-29 13:38:46 +03:00
|
|
|
gpu->UnmapLayerTreeId(aId, contentParent->OtherPid());
|
2016-08-16 23:59:13 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-06-11 09:44:39 +04:00
|
|
|
}
|
|
|
|
|
2010-11-24 16:58:21 +03:00
|
|
|
namespace {
|
2011-08-31 08:11:25 +04:00
|
|
|
|
2016-05-28 04:03:12 +03:00
|
|
|
void
|
|
|
|
DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
|
|
|
|
{
|
|
|
|
RefPtr<DeleteTask<GeckoChildProcessHost>> task = new DeleteTask<GeckoChildProcessHost>(aSubprocess);
|
|
|
|
XRE_GetIOMessageLoop()->PostTask(task.forget());
|
|
|
|
}
|
|
|
|
|
2011-08-31 08:11:25 +04:00
|
|
|
// This runnable only exists to delegate ownership of the
|
|
|
|
// ContentParent to this runnable, until it's deleted by the event
|
|
|
|
// system.
|
2016-04-26 03:23:21 +03:00
|
|
|
struct DelayedDeleteContentParentTask : public Runnable
|
2011-08-31 08:11:25 +04:00
|
|
|
{
|
2017-06-12 22:34:10 +03:00
|
|
|
explicit DelayedDeleteContentParentTask(ContentParent* aObj)
|
|
|
|
: Runnable("dom::DelayedDeleteContentParentTask")
|
|
|
|
, mObj(aObj)
|
|
|
|
{
|
|
|
|
}
|
2011-08-31 08:11:25 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// No-op
|
2016-08-08 05:18:10 +03:00
|
|
|
NS_IMETHOD Run() override { return NS_OK; }
|
2011-08-31 08:11:25 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<ContentParent> mObj;
|
2011-08-31 08:11:25 +04:00
|
|
|
};
|
|
|
|
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace
|
2010-11-24 16:58:21 +03:00
|
|
|
|
2010-02-02 04:53:52 +03:00
|
|
|
void
|
2010-07-19 22:33:33 +04:00
|
|
|
ContentParent::ActorDestroy(ActorDestroyReason why)
|
2010-02-02 04:53:52 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (mForceKillTimer) {
|
|
|
|
mForceKillTimer->Cancel();
|
|
|
|
mForceKillTimer = nullptr;
|
|
|
|
}
|
2015-01-07 08:40:56 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Signal shutdown completion regardless of error state, so we can
|
|
|
|
// finish waiting in the xpcom-shutdown/profile-before-change observer.
|
|
|
|
mIPCOpen = false;
|
2015-01-10 21:18:59 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (mHangMonitorActor) {
|
|
|
|
ProcessHangMonitor::RemoveProcess(mHangMonitorActor);
|
|
|
|
mHangMonitorActor = nullptr;
|
|
|
|
}
|
2015-01-17 05:34:47 +03:00
|
|
|
|
2017-03-16 10:53:49 +03:00
|
|
|
RefPtr<FileSystemSecurity> fss = FileSystemSecurity::Get();
|
|
|
|
if (fss) {
|
|
|
|
fss->Forget(ChildID());
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (why == NormalShutdown && !mCalledClose) {
|
|
|
|
// If we shut down normally but haven't called Close, assume somebody
|
|
|
|
// else called Close on us. In that case, we still need to call
|
|
|
|
// ShutDownProcess below to perform other necessary clean up.
|
|
|
|
mCalledClose = true;
|
|
|
|
}
|
2015-01-10 21:18:59 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Make sure we always clean up.
|
|
|
|
ShutDownProcess(why == NormalShutdown ? CLOSE_CHANNEL
|
|
|
|
: CLOSE_CHANNEL_WITH_ERROR);
|
|
|
|
|
|
|
|
RefPtr<ContentParent> kungFuDeathGrip(this);
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
if (obs) {
|
|
|
|
size_t length = ArrayLength(sObserverTopics);
|
|
|
|
for (size_t i = 0; i < length; ++i) {
|
|
|
|
obs->RemoveObserver(static_cast<nsIObserver*>(this),
|
|
|
|
sObserverTopics[i]);
|
2010-12-26 22:27:50 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2010-12-26 22:27:50 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// remove the global remote preferences observers
|
|
|
|
Preferences::RemoveObserver(this, "");
|
2016-08-04 21:33:42 +03:00
|
|
|
gfxVars::RemoveReceiver(this);
|
2010-12-26 22:27:50 +03:00
|
|
|
|
2016-09-20 11:18:50 +03:00
|
|
|
if (GPUProcessManager* gpu = GPUProcessManager::Get()) {
|
|
|
|
// Note: the manager could have shutdown already.
|
|
|
|
gpu->RemoveListener(this);
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
RecvRemoveGeolocationListener();
|
2010-12-26 22:27:50 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
mConsoleService = nullptr;
|
2012-11-09 21:52:09 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (obs) {
|
|
|
|
RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
|
2010-11-24 16:58:21 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
props->SetPropertyAsUint64(NS_LITERAL_STRING("childID"), mChildID);
|
2012-11-17 19:05:18 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (AbnormalShutdown == why) {
|
|
|
|
Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT,
|
|
|
|
NS_LITERAL_CSTRING("content"), 1);
|
2014-12-12 22:13:28 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
props->SetPropertyAsBool(NS_LITERAL_STRING("abnormal"), true);
|
2010-11-24 16:58:21 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// There's a window in which child processes can crash
|
|
|
|
// after IPC is established, but before a crash reporter
|
|
|
|
// is created.
|
2017-02-17 05:44:16 +03:00
|
|
|
if (mCrashReporter) {
|
2016-01-05 12:59:30 +03:00
|
|
|
// if mCreatedPairedMinidumps is true, we've already generated
|
2017-02-17 05:44:16 +03:00
|
|
|
// parent/child dumps for desktop crashes.
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!mCreatedPairedMinidumps) {
|
2017-02-17 05:44:16 +03:00
|
|
|
mCrashReporter->GenerateCrashReport(OtherPid());
|
2015-08-28 10:18:00 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
|
2017-02-17 05:44:16 +03:00
|
|
|
nsAutoString dumpID;
|
|
|
|
if (mCrashReporter->HasMinidump()) {
|
|
|
|
dumpID = mCrashReporter->MinidumpID();
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
props->SetPropertyAsAString(NS_LITERAL_STRING("dumpID"), dumpID);
|
2015-08-28 10:18:00 +03:00
|
|
|
}
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
nsAutoString cpId;
|
|
|
|
cpId.AppendInt(static_cast<uint64_t>(this->ChildID()));
|
|
|
|
obs->NotifyObservers((nsIPropertyBag2*) props, "ipc:content-shutdown", cpId.get());
|
|
|
|
}
|
2015-08-28 10:18:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Remove any and all idle listeners.
|
|
|
|
nsCOMPtr<nsIIdleService> idleService =
|
|
|
|
do_GetService("@mozilla.org/widget/idleservice;1");
|
|
|
|
MOZ_ASSERT(idleService);
|
|
|
|
RefPtr<ParentIdleListener> listener;
|
|
|
|
for (int32_t i = mIdleListeners.Length() - 1; i >= 0; --i) {
|
|
|
|
listener = static_cast<ParentIdleListener*>(mIdleListeners[i].get());
|
|
|
|
idleService->RemoveIdleObserver(listener, listener->mTime);
|
|
|
|
}
|
|
|
|
mIdleListeners.Clear();
|
|
|
|
|
2016-05-28 04:03:12 +03:00
|
|
|
MessageLoop::current()->
|
2017-10-27 23:39:28 +03:00
|
|
|
PostTask(NewRunnableFunction("DelayedDeleteSubprocessRunnable",
|
|
|
|
DelayedDeleteSubprocess, mSubprocess));
|
2016-05-28 04:03:12 +03:00
|
|
|
mSubprocess = nullptr;
|
2016-01-05 12:59:30 +03:00
|
|
|
|
2018-07-22 14:52:42 +03:00
|
|
|
// Delete any remaining replaying children.
|
|
|
|
for (auto& replayingProcess : mReplayingChildren) {
|
|
|
|
if (replayingProcess) {
|
|
|
|
DelayedDeleteSubprocess(replayingProcess);
|
|
|
|
replayingProcess = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// IPDL rules require actors to live on past ActorDestroy, but it
|
|
|
|
// may be that the kungFuDeathGrip above is the last reference to
|
|
|
|
// |this|. If so, when we go out of scope here, we're deleted and
|
|
|
|
// all hell breaks loose.
|
|
|
|
//
|
|
|
|
// This runnable ensures that a reference to |this| lives on at
|
|
|
|
// least until after the current task finishes running.
|
|
|
|
NS_DispatchToCurrentThread(new DelayedDeleteContentParentTask(this));
|
|
|
|
|
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
|
|
|
nsTArray<ContentParentId> childIDArray =
|
|
|
|
cpm->GetAllChildProcessById(this->ChildID());
|
|
|
|
|
|
|
|
// Destroy any processes created by this ContentParent
|
|
|
|
for(uint32_t i = 0; i < childIDArray.Length(); i++) {
|
|
|
|
ContentParent* cp = cpm->GetContentProcessById(childIDArray[i]);
|
2017-06-12 22:34:10 +03:00
|
|
|
MessageLoop::current()->PostTask(
|
|
|
|
NewRunnableMethod<ShutDownMethod>("dom::ContentParent::ShutDownProcess",
|
|
|
|
cp,
|
|
|
|
&ContentParent::ShutDownProcess,
|
|
|
|
SEND_SHUTDOWN_MESSAGE));
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
cpm->RemoveContentProcess(this->ChildID());
|
|
|
|
|
|
|
|
if (mDriverCrashGuard) {
|
|
|
|
mDriverCrashGuard->NotifyCrashed();
|
|
|
|
}
|
2016-07-18 12:12:18 +03:00
|
|
|
|
|
|
|
// Unregister all the BlobURLs registered by the ContentChild.
|
|
|
|
for (uint32_t i = 0; i < mBlobURLs.Length(); ++i) {
|
2018-06-02 16:51:42 +03:00
|
|
|
BlobURLProtocolHandler::RemoveDataEntry(mBlobURLs[i]);
|
2016-07-18 12:12:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mBlobURLs.Clear();
|
2016-09-27 01:17:58 +03:00
|
|
|
|
|
|
|
#if defined(XP_WIN32) && defined(ACCESSIBILITY)
|
|
|
|
a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
|
|
|
|
#endif
|
2018-06-29 02:41:00 +03:00
|
|
|
|
|
|
|
BrowsingContext::CleanupContexts(ChildID());
|
2010-02-02 04:53:52 +03:00
|
|
|
}
|
|
|
|
|
2017-05-30 14:46:41 +03:00
|
|
|
bool
|
|
|
|
ContentParent::TryToRecycle()
|
|
|
|
{
|
|
|
|
// This life time check should be replaced by a memory health check (memory usage + fragmentation).
|
|
|
|
const double kMaxLifeSpan = 5;
|
|
|
|
if (mShutdownPending ||
|
|
|
|
mCalledKillHard ||
|
|
|
|
!IsAvailable() ||
|
|
|
|
!mRemoteType.EqualsLiteral(DEFAULT_REMOTE_TYPE) ||
|
|
|
|
(TimeStamp::Now() - mActivateTS).ToSeconds() > kMaxLifeSpan ||
|
|
|
|
!PreallocatedProcessManager::Provide(this)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The PreallocatedProcessManager took over the ownership let's not keep a reference to it,
|
|
|
|
// until we don't take it back.
|
|
|
|
RemoveFromList();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:32 +03:00
|
|
|
bool
|
|
|
|
ContentParent::ShouldKeepProcessAlive() const
|
|
|
|
{
|
2017-05-29 13:38:46 +03:00
|
|
|
if (IsForJSPlugin()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:32 +03:00
|
|
|
if (!sBrowserContentParents) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-02-07 19:46:44 +03:00
|
|
|
// If we have already been marked as troubled/dead, don't prevent shutdown.
|
|
|
|
if (!IsAvailable()) {
|
2016-11-24 18:08:32 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-07-30 18:44:54 +03:00
|
|
|
// Recording/replaying content parents cannot be reused and should not be
|
|
|
|
// kept alive.
|
|
|
|
if (this->IsRecordingOrReplaying()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:32 +03:00
|
|
|
auto contentParents = sBrowserContentParents->Get(mRemoteType);
|
|
|
|
if (!contentParents) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-06-20 21:04:51 +03:00
|
|
|
// We might want to keep some content processes alive for performance reasons.
|
|
|
|
// e.g. test runs and privileged content process for some about: pages.
|
2016-11-24 18:08:32 +03:00
|
|
|
// We don't want to alter behavior if the pref is not set, so default to 0.
|
2017-01-13 00:48:23 +03:00
|
|
|
int32_t processesToKeepAlive = 0;
|
|
|
|
|
|
|
|
nsAutoCString keepAlivePref("dom.ipc.keepProcessesAlive.");
|
|
|
|
keepAlivePref.Append(NS_ConvertUTF16toUTF8(mRemoteType));
|
|
|
|
if (NS_FAILED(Preferences::GetInt(keepAlivePref.get(), &processesToKeepAlive))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:32 +03:00
|
|
|
int32_t numberOfAliveProcesses = contentParents->Length();
|
|
|
|
|
|
|
|
return numberOfAliveProcesses <= processesToKeepAlive;
|
|
|
|
}
|
|
|
|
|
2012-07-17 22:27:27 +04:00
|
|
|
void
|
2015-08-28 10:18:00 +03:00
|
|
|
ContentParent::NotifyTabDestroying(const TabId& aTabId,
|
|
|
|
const ContentParentId& aCpId)
|
2013-01-10 17:22:14 +04:00
|
|
|
{
|
2015-08-28 10:18:00 +03:00
|
|
|
if (XRE_IsParentProcess()) {
|
2013-01-10 17:22:14 +04:00
|
|
|
// There can be more than one PBrowser for a given app process
|
|
|
|
// because of popup windows. PBrowsers can also destroy
|
|
|
|
// concurrently. When all the PBrowsers are destroying, kick off
|
|
|
|
// another task to ensure the child process *really* shuts down,
|
|
|
|
// even if the PBrowsers themselves never finish destroying.
|
2015-08-28 10:18:00 +03:00
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
|
|
|
ContentParent* cp = cpm->GetContentProcessById(aCpId);
|
|
|
|
if (!cp) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
++cp->mNumDestroyingTabs;
|
|
|
|
nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(aCpId);
|
|
|
|
if (static_cast<size_t>(cp->mNumDestroyingTabs) != tabIds.Length()) {
|
2013-01-10 17:22:14 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:32 +03:00
|
|
|
if (cp->ShouldKeepProcessAlive()) {
|
2016-11-18 02:58:51 +03:00
|
|
|
return;
|
2016-11-02 13:13:37 +03:00
|
|
|
}
|
|
|
|
|
2017-05-30 14:46:41 +03:00
|
|
|
if (cp->TryToRecycle()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-01-10 17:22:14 +04:00
|
|
|
// We're dying now, so prevent this content process from being
|
|
|
|
// recycled during its shutdown procedure.
|
2015-08-28 10:18:00 +03:00
|
|
|
cp->MarkAsDead();
|
|
|
|
cp->StartForceKillTimer();
|
|
|
|
} else {
|
|
|
|
ContentChild::GetSingleton()->SendNotifyTabDestroying(aTabId, aCpId);
|
|
|
|
}
|
2015-01-10 21:45:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ContentParent::StartForceKillTimer()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (mForceKillTimer || !mIPCOpen) {
|
|
|
|
return;
|
|
|
|
}
|
2013-01-10 17:22:14 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
int32_t timeoutSecs = Preferences::GetInt("dom.ipc.tabs.shutdownTimeoutSecs", 5);
|
|
|
|
if (timeoutSecs > 0) {
|
2017-10-16 09:15:40 +03:00
|
|
|
NS_NewTimerWithFuncCallback(getter_AddRefs(mForceKillTimer),
|
|
|
|
ContentParent::ForceKillTimerCallback,
|
|
|
|
this,
|
|
|
|
timeoutSecs * 1000,
|
|
|
|
nsITimer::TYPE_ONE_SHOT,
|
|
|
|
"dom::ContentParent::StartForceKillTimer");
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(mForceKillTimer);
|
|
|
|
}
|
2013-01-10 17:22:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-08-28 10:18:00 +03:00
|
|
|
ContentParent::NotifyTabDestroyed(const TabId& aTabId,
|
2013-01-10 17:22:14 +04:00
|
|
|
bool aNotifiedDestroying)
|
2012-07-17 22:27:27 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (aNotifiedDestroying) {
|
|
|
|
--mNumDestroyingTabs;
|
|
|
|
}
|
2013-01-10 17:22:14 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsTArray<PContentPermissionRequestParent*> parentArray =
|
|
|
|
nsContentPermissionUtils::GetContentPermissionRequestParentById(aTabId);
|
2015-04-14 04:08:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Need to close undeleted ContentPermissionRequestParents before tab is closed.
|
|
|
|
for (auto& permissionRequestParent : parentArray) {
|
|
|
|
Unused << PContentPermissionRequestParent::Send__delete__(permissionRequestParent);
|
|
|
|
}
|
2015-04-14 04:08:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// There can be more than one PBrowser for a given app process
|
|
|
|
// because of popup windows. When the last one closes, shut
|
|
|
|
// us down.
|
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
|
|
|
nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(this->ChildID());
|
2016-11-02 13:13:37 +03:00
|
|
|
|
2017-05-30 14:46:41 +03:00
|
|
|
if (tabIds.Length() == 1 && !ShouldKeepProcessAlive() && !TryToRecycle()) {
|
2016-01-05 12:59:30 +03:00
|
|
|
// In the case of normal shutdown, send a shutdown message to child to
|
|
|
|
// allow it to perform shutdown tasks.
|
2017-06-12 22:34:10 +03:00
|
|
|
MessageLoop::current()->PostTask(
|
|
|
|
NewRunnableMethod<ShutDownMethod>("dom::ContentParent::ShutDownProcess",
|
|
|
|
this,
|
|
|
|
&ContentParent::ShutDownProcess,
|
|
|
|
SEND_SHUTDOWN_MESSAGE));
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2012-07-17 22:27:27 +04:00
|
|
|
}
|
|
|
|
|
2018-07-22 14:52:42 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvOpenRecordReplayChannel(const uint32_t& aChannelId,
|
|
|
|
FileDescriptor* aConnection)
|
|
|
|
{
|
|
|
|
// We should only get this message from the child if it is recording or replaying.
|
2018-07-24 00:51:24 +03:00
|
|
|
if (!this->IsRecordingOrReplaying()) {
|
2018-07-22 14:52:42 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
recordreplay::parent::OpenChannel(Pid(), aChannelId, aConnection);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvCreateReplayingProcess(const uint32_t& aChannelId)
|
|
|
|
{
|
|
|
|
// We should only get this message from the child if it is recording or replaying.
|
2018-07-24 00:51:24 +03:00
|
|
|
if (!this->IsRecordingOrReplaying()) {
|
2018-07-22 14:52:42 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (aChannelId >= mReplayingChildren.length()) {
|
|
|
|
if (!mReplayingChildren.append(nullptr)) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mReplayingChildren[aChannelId]) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> extraArgs;
|
|
|
|
recordreplay::parent::GetArgumentsForChildProcess(Pid(), aChannelId,
|
|
|
|
NS_ConvertUTF16toUTF8(mRecordingFile).get(),
|
|
|
|
/* aRecording = */ false,
|
|
|
|
extraArgs);
|
|
|
|
|
|
|
|
mReplayingChildren[aChannelId] = new GeckoChildProcessHost(GeckoProcessType_Content);
|
|
|
|
if (!mReplayingChildren[aChannelId]->LaunchAndWaitForProcessHandle(extraArgs)) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvTerminateReplayingProcess(const uint32_t& aChannelId)
|
|
|
|
{
|
|
|
|
// We should only get this message from the child if it is recording or replaying.
|
2018-07-24 00:51:24 +03:00
|
|
|
if (!this->IsRecordingOrReplaying()) {
|
2018-07-22 14:52:42 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aChannelId < mReplayingChildren.length() && mReplayingChildren[aChannelId]) {
|
|
|
|
DelayedDeleteSubprocess(mReplayingChildren[aChannelId]);
|
|
|
|
mReplayingChildren[aChannelId] = nullptr;
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2015-01-27 00:32:18 +03:00
|
|
|
jsipc::CPOWManager*
|
2013-07-03 11:24:32 +04:00
|
|
|
ContentParent::GetCPOWManager()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (PJavaScriptParent* p = LoneManagedOrNullAsserts(ManagedPJavaScriptParent())) {
|
|
|
|
return CPOWManagerFor(p);
|
|
|
|
}
|
|
|
|
return nullptr;
|
2013-07-03 11:24:32 +04:00
|
|
|
}
|
|
|
|
|
2009-08-12 22:31:48 +04:00
|
|
|
TestShellParent*
|
2010-07-19 22:33:33 +04:00
|
|
|
ContentParent::CreateTestShell()
|
2009-08-12 22:31:48 +04:00
|
|
|
{
|
2009-09-10 02:00:14 +04:00
|
|
|
return static_cast<TestShellParent*>(SendPTestShellConstructor());
|
2009-08-12 22:31:48 +04:00
|
|
|
}
|
|
|
|
|
2009-11-11 11:34:08 +03:00
|
|
|
bool
|
2010-07-19 22:33:33 +04:00
|
|
|
ContentParent::DestroyTestShell(TestShellParent* aTestShell)
|
2009-11-11 11:34:08 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return PTestShellParent::Send__delete__(aTestShell);
|
2009-11-11 11:34:08 +03:00
|
|
|
}
|
|
|
|
|
2011-06-24 03:31:58 +04:00
|
|
|
TestShellParent*
|
|
|
|
ContentParent::GetTestShellSingleton()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
PTestShellParent* p = LoneManagedOrNullAsserts(ManagedPTestShellParent());
|
|
|
|
return static_cast<TestShellParent*>(p);
|
2011-06-24 03:31:58 +04:00
|
|
|
}
|
|
|
|
|
2015-05-11 10:24:40 +03:00
|
|
|
bool
|
|
|
|
ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */)
|
|
|
|
{
|
Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange.
This patch makes the following changes to the macros.
- Removes PROFILER_LABEL_FUNC. It's only suitable for use in functions outside
classes, due to PROFILER_FUNCTION_NAME not getting class names, and it was
mostly misused.
- Removes PROFILER_FUNCTION_NAME. It's no longer used, and __func__ is
universally available now anyway.
- Combines the first two string literal arguments of PROFILER_LABEL and
PROFILER_LABEL_DYNAMIC into a single argument. There was no good reason for
them to be separate, and it forced a '::' in the label, which isn't always
appropriate. Also, the meaning of the "name_space" argument was interpreted
in an interesting variety of ways.
- Adds an "AUTO_" prefix to PROFILER_LABEL and PROFILER_LABEL_DYNAMIC, to make
it clearer they construct RAII objects rather than just being function calls.
(I myself have screwed up the scoping because of this in the past.)
- Fills in the 'js::ProfileEntry::Category::' qualifier within the macro, so
the caller doesn't need to. This makes a *lot* more of the uses fit onto a
single line.
The patch also makes the following changes to the macro uses (beyond those
required by the changes described above).
- Fixes a bunch of labels that had gotten out of sync with the name of the
class and/or function that encloses them.
- Removes a useless PROFILER_LABEL use within a trivial scope in
EventStateManager::DispatchMouseOrPointerEvent(). It clearly wasn't serving
any useful purpose. It also serves as extra evidence that the AUTO_ prefix is
a good idea.
- Tweaks DecodePool::SyncRunIf{Preferred,Possible} so that the labelling is
done within them, instead of at their callsites, because that's a more
standard way of doing things.
--HG--
extra : rebase_source : 318d1bc6fc1425a94aacbf489dd46e4f83211de4
2017-06-22 10:08:53 +03:00
|
|
|
AUTO_PROFILER_LABEL("ContentParent::LaunchSubprocess", OTHER);
|
2016-01-15 01:03:11 +03:00
|
|
|
|
2018-01-22 15:11:46 +03:00
|
|
|
if (!ContentProcessManager::GetSingleton()) {
|
|
|
|
// Shutdown has begun, we shouldn't spawn any more child processes.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
std::vector<std::string> extraArgs;
|
2017-02-05 08:52:38 +03:00
|
|
|
extraArgs.push_back("-childID");
|
|
|
|
char idStr[21];
|
|
|
|
SprintfLiteral(idStr, "%" PRId64, static_cast<uint64_t>(mChildID));
|
|
|
|
extraArgs.push_back(idStr);
|
|
|
|
extraArgs.push_back(IsForBrowser() ? "-isForBrowser" : "-notForBrowser");
|
|
|
|
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
// Prefs information is passed via anonymous shared memory to avoid bloating
|
|
|
|
// the command line.
|
2017-02-05 08:52:38 +03:00
|
|
|
|
2018-07-03 01:40:38 +03:00
|
|
|
size_t prefMapSize;
|
|
|
|
auto prefMapHandle = Preferences::EnsureSnapshot(&prefMapSize).ClonePlatformHandle();
|
|
|
|
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
// Serialize the early prefs.
|
|
|
|
nsAutoCStringN<1024> prefs;
|
2018-03-08 07:47:24 +03:00
|
|
|
Preferences::SerializePreferences(prefs);
|
2017-02-05 08:52:38 +03:00
|
|
|
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
// Set up the shared memory.
|
|
|
|
base::SharedMemory shm;
|
2018-02-20 23:07:32 +03:00
|
|
|
if (!shm.Create(prefs.Length())) {
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
NS_ERROR("failed to create shared memory in the parent");
|
|
|
|
MarkAsDead();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!shm.Map(prefs.Length())) {
|
|
|
|
NS_ERROR("failed to map shared memory in the parent");
|
|
|
|
MarkAsDead();
|
|
|
|
return false;
|
2017-02-05 08:52:38 +03:00
|
|
|
}
|
|
|
|
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
// Copy the serialized prefs into the shared memory.
|
|
|
|
memcpy(static_cast<char*>(shm.memory()), prefs.get(), prefs.Length());
|
2017-07-29 00:56:49 +03:00
|
|
|
|
2018-07-03 01:40:38 +03:00
|
|
|
// Formats a pointer or pointer-sized-integer as a string suitable for passing
|
|
|
|
// in an arguments list.
|
|
|
|
auto formatPtrArg = [] (auto arg) {
|
|
|
|
return nsPrintfCString("%zu", uintptr_t(arg));
|
|
|
|
};
|
|
|
|
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
// Record the handle as to-be-shared, and pass it via a command flag. This
|
|
|
|
// works because Windows handles are system-wide.
|
|
|
|
HANDLE prefsHandle = shm.handle();
|
|
|
|
mSubprocess->AddHandleToShare(prefsHandle);
|
2018-07-03 01:40:38 +03:00
|
|
|
mSubprocess->AddHandleToShare(prefMapHandle.get());
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
extraArgs.push_back("-prefsHandle");
|
2018-07-03 01:40:38 +03:00
|
|
|
extraArgs.push_back(formatPtrArg(prefsHandle).get());
|
|
|
|
extraArgs.push_back("-prefMapHandle");
|
|
|
|
extraArgs.push_back(formatPtrArg(prefMapHandle.get()).get());
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
#else
|
|
|
|
// In contrast, Unix fds are per-process. So remap the fd to a fixed one that
|
|
|
|
// will be used in the child.
|
|
|
|
// XXX: bug 1440207 is about improving how fixed fds are used.
|
|
|
|
//
|
|
|
|
// Note: on Android, AddFdToRemap() sets up the fd to be passed via a Parcel,
|
|
|
|
// and the fixed fd isn't used. However, we still need to mark it for
|
|
|
|
// remapping so it doesn't get closed in the child.
|
|
|
|
mSubprocess->AddFdToRemap(shm.handle().fd, kPrefsFileDescriptor);
|
2018-07-03 01:40:38 +03:00
|
|
|
mSubprocess->AddFdToRemap(prefMapHandle.get(), kPrefMapFileDescriptor);
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
#endif
|
|
|
|
|
2018-07-03 01:40:38 +03:00
|
|
|
// Pass the lengths via command line flags.
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
extraArgs.push_back("-prefsLen");
|
2018-07-03 01:40:38 +03:00
|
|
|
extraArgs.push_back(formatPtrArg(prefs.Length()).get());
|
|
|
|
|
|
|
|
extraArgs.push_back("-prefMapSize");
|
|
|
|
extraArgs.push_back(formatPtrArg(prefMapSize).get());
|
2017-02-05 08:52:38 +03:00
|
|
|
|
2017-07-29 00:56:49 +03:00
|
|
|
// Scheduler prefs need to be handled differently because the scheduler needs
|
|
|
|
// to start up in the content process before the normal preferences service.
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
nsCString schedulerPrefs = Scheduler::GetPrefs();
|
2017-07-29 00:56:49 +03:00
|
|
|
extraArgs.push_back("-schedulerPrefs");
|
|
|
|
extraArgs.push_back(schedulerPrefs.get());
|
|
|
|
|
2017-02-09 02:45:01 +03:00
|
|
|
if (gSafeMode) {
|
|
|
|
extraArgs.push_back("-safeMode");
|
|
|
|
}
|
|
|
|
|
2018-05-08 17:31:44 +03:00
|
|
|
nsCString parentBuildID(mozilla::PlatformBuildID());
|
|
|
|
extraArgs.push_back("-parentBuildID");
|
|
|
|
extraArgs.push_back(parentBuildID.get());
|
|
|
|
|
2018-07-22 14:52:42 +03:00
|
|
|
// Specify whether the process is recording or replaying an execution.
|
|
|
|
if (mRecordReplayState != eNotRecordingOrReplaying) {
|
|
|
|
nsPrintfCString buf("%d", mRecordReplayState == eRecording
|
|
|
|
? (int) recordreplay::ProcessKind::MiddlemanRecording
|
|
|
|
: (int) recordreplay::ProcessKind::MiddlemanReplaying);
|
|
|
|
extraArgs.push_back(recordreplay::gProcessKindOption);
|
|
|
|
extraArgs.push_back(buf.get());
|
|
|
|
|
|
|
|
extraArgs.push_back(recordreplay::gRecordingFileOption);
|
|
|
|
extraArgs.push_back(NS_ConvertUTF16toUTF8(mRecordingFile).get());
|
|
|
|
}
|
|
|
|
|
2018-02-22 18:36:55 +03:00
|
|
|
SetOtherProcessId(kInvalidProcessId, ProcessIdState::ePending);
|
2018-05-12 03:00:40 +03:00
|
|
|
#ifdef ASYNC_CONTENTPROC_LAUNCH
|
2018-02-16 18:24:21 +03:00
|
|
|
if (!mSubprocess->Launch(extraArgs)) {
|
2018-05-12 03:00:40 +03:00
|
|
|
#else
|
|
|
|
if (!mSubprocess->LaunchAndWaitForProcessHandle(extraArgs)) {
|
|
|
|
#endif
|
Bug 1438678 - Pass early prefs via shared memory instead of the command line. r=bobowen,jld,glandium.
This patch replaces the large -intPrefs/-boolPrefs/-stringPrefs flags with
a short-lived, anonymous, shared memory segment that is used to pass the early
prefs.
Removing the bloat from the command line is nice, but more important is the
fact that this will let us pass more prefs at content process start-up, which
will allow us to remove the early/late prefs split (bug 1436911).
Although this mechanism is only used for prefs, it's conceivable that it could
be used for other data that must be received very early by children, and for
which the command line isn't ideal.
Notable details:
- Much of the patch deals with the various platform-specific ways of passing
handles/fds to children.
- Linux and Mac: we use a fixed fd (8) in combination with the new
GeckoChildProcessHost::AddFdToRemap() function (which ensures the child
won't close the fd).
- Android: like Linux and Mac, but the handles get passed via "parcels" and
we use the new SetPrefsFd() function instead of the fixed fd.
- Windows: there is no need to duplicate the handle because Windows handles
are system-wide. But we do use the new
GeckoChildProcessHost::AddHandleToShare() function to add it to the list of
inheritable handles. We also ensure that list is processed on all paths
(MOZ_SANDBOX with sandbox, MOZ_SANDBOX without sandbox, non-MOZ_SANDBOX) so
that the handles are marked as inheritable. The handle is passed via the
-prefsHandle flag.
The -prefsLen flag is used on all platforms to indicate the size of the
shared memory segment.
- The patch also moves the serialization/deserialization of the prefs in/out of
the shared memory into libpref, which is a better spot for it. (This means
Preferences::MustSendToContentProcesses() can be removed.)
MozReview-Commit-ID: 8fREEBiYFvc
--HG--
extra : rebase_source : 7e4c8ebdbcd7d74d6bd2ab3c9e75a6a17dbd8dfe
2018-02-16 09:54:16 +03:00
|
|
|
NS_ERROR("failed to launch child in the parent");
|
2016-01-05 12:59:30 +03:00
|
|
|
MarkAsDead();
|
|
|
|
return false;
|
|
|
|
}
|
2015-05-11 10:24:40 +03:00
|
|
|
|
2018-05-12 03:00:40 +03:00
|
|
|
#ifdef ASYNC_CONTENTPROC_LAUNCH
|
2018-02-16 18:24:21 +03:00
|
|
|
OpenWithAsyncPid(mSubprocess->GetChannel());
|
2018-05-12 03:00:40 +03:00
|
|
|
#else
|
|
|
|
base::ProcessId procId =
|
|
|
|
base::GetProcId(mSubprocess->GetChildProcessHandle());
|
|
|
|
Open(mSubprocess->GetChannel(), procId);
|
|
|
|
#ifdef MOZ_CODE_COVERAGE
|
|
|
|
Unused << SendShareCodeCoverageMutex(
|
|
|
|
CodeCoverageHandler::Get()->GetMutexHandle(procId));
|
|
|
|
#endif
|
|
|
|
#endif // ASYNC_CONTENTPROC_LAUNCH
|
2017-08-15 22:08:14 +03:00
|
|
|
|
2018-02-21 21:35:36 +03:00
|
|
|
InitInternal(aInitialPriority);
|
2015-05-11 10:24:40 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentProcessManager::GetSingleton()->AddContentProcess(this);
|
2015-05-11 10:24:40 +03:00
|
|
|
|
2017-01-05 23:54:52 +03:00
|
|
|
mHangMonitorActor = ProcessHangMonitor::AddProcess(this);
|
2015-05-11 10:24:40 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Set a reply timeout for CPOWs.
|
|
|
|
SetReplyTimeoutMs(Preferences::GetInt("dom.ipc.cpow.timeout", 0));
|
2015-05-11 10:24:40 +03:00
|
|
|
|
2018-05-12 03:00:40 +03:00
|
|
|
// TODO: In ASYNC_CONTENTPROC_LAUNCH, if OtherPid() is not called between
|
|
|
|
// mSubprocess->Launch() and this, then we're not really measuring how long it
|
|
|
|
// took to spawn the process.
|
2017-02-05 08:52:38 +03:00
|
|
|
Telemetry::Accumulate(Telemetry::CONTENT_PROCESS_LAUNCH_TIME_MS,
|
|
|
|
static_cast<uint32_t>((TimeStamp::Now() - mLaunchTS)
|
|
|
|
.ToMilliseconds()));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
if (obs) {
|
|
|
|
nsAutoString cpId;
|
|
|
|
cpId.AppendInt(static_cast<uint64_t>(this->ChildID()));
|
|
|
|
obs->NotifyObservers(static_cast<nsIObserver*>(this), "ipc:content-initializing", cpId.get());
|
|
|
|
}
|
|
|
|
|
2018-03-22 23:02:57 +03:00
|
|
|
Init();
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
return true;
|
2015-05-11 10:24:40 +03:00
|
|
|
}
|
|
|
|
|
2016-10-15 04:46:26 +03:00
|
|
|
ContentParent::ContentParent(ContentParent* aOpener,
|
2017-05-29 13:38:46 +03:00
|
|
|
const nsAString& aRemoteType,
|
2018-07-22 14:52:42 +03:00
|
|
|
RecordReplayState aRecordReplayState,
|
|
|
|
const nsAString& aRecordingFile,
|
2017-05-29 13:38:46 +03:00
|
|
|
int32_t aJSPluginID)
|
2016-01-05 12:59:30 +03:00
|
|
|
: nsIContentParent()
|
2017-02-22 02:19:49 +03:00
|
|
|
, mSubprocess(nullptr)
|
2016-12-09 21:52:28 +03:00
|
|
|
, mLaunchTS(TimeStamp::Now())
|
2017-05-30 14:46:41 +03:00
|
|
|
, mActivateTS(TimeStamp::Now())
|
2016-01-05 12:59:30 +03:00
|
|
|
, mOpener(aOpener)
|
2016-11-24 18:08:31 +03:00
|
|
|
, mRemoteType(aRemoteType)
|
2017-02-22 02:19:49 +03:00
|
|
|
, mChildID(gContentChildID++)
|
|
|
|
, mGeolocationWatchID(-1)
|
2017-05-29 13:38:46 +03:00
|
|
|
, mJSPluginID(aJSPluginID)
|
2017-02-22 02:19:49 +03:00
|
|
|
, mNumDestroyingTabs(0)
|
|
|
|
, mIsAvailable(true)
|
|
|
|
, mIsAlive(true)
|
2016-11-24 18:08:31 +03:00
|
|
|
, mIsForBrowser(!mRemoteType.IsEmpty())
|
2018-07-22 14:52:42 +03:00
|
|
|
, mRecordReplayState(aRecordReplayState)
|
|
|
|
, mRecordingFile(aRecordingFile)
|
2017-02-22 02:19:49 +03:00
|
|
|
, mCalledClose(false)
|
|
|
|
, mCalledKillHard(false)
|
|
|
|
, mCreatedPairedMinidumps(false)
|
|
|
|
, mShutdownPending(false)
|
|
|
|
, mIPCOpen(true)
|
2017-07-28 10:14:54 +03:00
|
|
|
, mIsRemoteInputEventQueueEnabled(false)
|
|
|
|
, mIsInputPriorityEventEnabled(false)
|
2017-02-22 02:19:49 +03:00
|
|
|
, mHangMonitorActor(nullptr)
|
2009-08-12 20:18:08 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// Insert ourselves into the global linked list of ContentParent objects.
|
|
|
|
if (!sContentParents) {
|
|
|
|
sContentParents = new LinkedList<ContentParent>();
|
|
|
|
}
|
2016-08-02 15:54:00 +03:00
|
|
|
sContentParents->insertBack(this);
|
2013-04-26 04:53:26 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// From this point on, NS_WARNING, NS_ASSERTION, etc. should print out the
|
|
|
|
// PID along with the warning.
|
|
|
|
nsDebugImpl::SetMultiprocessMode("Parent");
|
2012-04-10 23:57:20 +04:00
|
|
|
|
2017-07-25 07:34:14 +03:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
if (XRE_IsParentProcess()) {
|
|
|
|
audio::AudioNotificationSender::Init();
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
// Request Windows message deferral behavior on our side of the PContent
|
|
|
|
// channel. Generally only applies to the situation where we get caught in
|
|
|
|
// a deadlock with the plugin process when sending CPOWs.
|
|
|
|
GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
|
2014-11-15 04:22:44 +03:00
|
|
|
#endif
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
2017-09-09 01:16:50 +03:00
|
|
|
bool isFile = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE);
|
2018-02-22 22:29:49 +03:00
|
|
|
mSubprocess = new ContentProcessHost(this, isFile);
|
2009-08-12 20:18:08 +04:00
|
|
|
}
|
|
|
|
|
2010-07-19 22:33:33 +04:00
|
|
|
ContentParent::~ContentParent()
|
2009-08-12 20:18:08 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (mForceKillTimer) {
|
|
|
|
mForceKillTimer->Cancel();
|
|
|
|
}
|
2013-01-10 17:22:14 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
2012-07-14 01:10:20 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// We should be removed from all these lists in ActorDestroy.
|
|
|
|
MOZ_ASSERT(!sPrivateContent || !sPrivateContent->Contains(this));
|
2017-05-29 13:38:46 +03:00
|
|
|
if (IsForJSPlugin()) {
|
|
|
|
MOZ_ASSERT(!sJSPluginContentParents ||
|
|
|
|
!sJSPluginContentParents->Get(mJSPluginID));
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(!sBrowserContentParents ||
|
|
|
|
!sBrowserContentParents->Contains(mRemoteType) ||
|
|
|
|
!sBrowserContentParents->Get(mRemoteType)->Contains(this));
|
|
|
|
}
|
2010-04-12 04:24:45 +04:00
|
|
|
}
|
|
|
|
|
2013-11-29 13:28:54 +04:00
|
|
|
void
|
2018-02-21 21:35:36 +03:00
|
|
|
ContentParent::InitInternal(ProcessPriority aInitialPriority)
|
2013-11-29 13:28:54 +04:00
|
|
|
{
|
2017-02-05 08:52:38 +03:00
|
|
|
Telemetry::Accumulate(Telemetry::CONTENT_PROCESS_LAUNCH_TIME_MS,
|
|
|
|
static_cast<uint32_t>((TimeStamp::Now() - mLaunchTS)
|
|
|
|
.ToMilliseconds()));
|
|
|
|
|
|
|
|
XPCOMInitData xpcomInit;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIIOService> io(do_GetIOService());
|
|
|
|
MOZ_ASSERT(io, "No IO service?");
|
|
|
|
DebugOnly<nsresult> rv = io->GetOffline(&xpcomInit.isOffline());
|
|
|
|
MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting offline?");
|
|
|
|
|
|
|
|
rv = io->GetConnectivity(&xpcomInit.isConnected());
|
|
|
|
MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting connectivity?");
|
|
|
|
|
|
|
|
xpcomInit.captivePortalState() = nsICaptivePortalService::UNKNOWN;
|
|
|
|
nsCOMPtr<nsICaptivePortalService> cps = do_GetService(NS_CAPTIVEPORTAL_CONTRACTID);
|
|
|
|
if (cps) {
|
|
|
|
cps->GetState(&xpcomInit.captivePortalState());
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIBidiKeyboard* bidi = nsContentUtils::GetBidiKeyboard();
|
|
|
|
|
|
|
|
xpcomInit.isLangRTL() = false;
|
|
|
|
xpcomInit.haveBidiKeyboards() = false;
|
|
|
|
if (bidi) {
|
|
|
|
bidi->IsLangRTL(&xpcomInit.isLangRTL());
|
|
|
|
bidi->GetHaveBidiKeyboards(&xpcomInit.haveBidiKeyboards());
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID));
|
|
|
|
MOZ_ASSERT(spellChecker, "No spell checker?");
|
|
|
|
|
|
|
|
spellChecker->GetDictionaryList(&xpcomInit.dictionaries());
|
|
|
|
|
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()->GetAppLocalesAsLangTags(xpcomInit.appLocales());
|
|
|
|
LocaleService::GetInstance()->GetRequestedLocales(xpcomInit.requestedLocales());
|
|
|
|
|
2017-02-05 08:52:38 +03:00
|
|
|
nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1"));
|
|
|
|
MOZ_ASSERT(clipboard, "No clipboard?");
|
|
|
|
|
|
|
|
rv = clipboard->SupportsSelectionClipboard(&xpcomInit.clipboardCaps().supportsSelectionClipboard());
|
|
|
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
|
|
|
|
rv = clipboard->SupportsFindClipboard(&xpcomInit.clipboardCaps().supportsFindClipboard());
|
|
|
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
|
|
|
|
|
|
|
// Let's copy the domain policy from the parent to the child (if it's active).
|
|
|
|
StructuredCloneData initialData;
|
|
|
|
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
|
|
|
if (ssm) {
|
|
|
|
ssm->CloneDomainPolicy(&xpcomInit.domainPolicy());
|
|
|
|
|
2018-04-16 16:18:48 +03:00
|
|
|
if (ParentProcessMessageManager* mm = nsFrameMessageManager::sParentProcessManager) {
|
2017-02-05 08:52:38 +03:00
|
|
|
AutoJSAPI jsapi;
|
|
|
|
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
|
|
|
|
MOZ_CRASH();
|
|
|
|
}
|
|
|
|
JS::RootedValue init(jsapi.cx());
|
2018-02-09 17:59:02 +03:00
|
|
|
// We'll crash on failure, so use a IgnoredErrorResult (which also auto-suppresses
|
|
|
|
// exceptions).
|
|
|
|
IgnoredErrorResult rv;
|
|
|
|
mm->GetInitialProcessData(jsapi.cx(), &init, rv);
|
|
|
|
if (NS_WARN_IF(rv.Failed())) {
|
2017-02-05 08:52:38 +03:00
|
|
|
MOZ_CRASH();
|
|
|
|
}
|
|
|
|
|
|
|
|
initialData.Write(jsapi.cx(), init, rv);
|
|
|
|
if (NS_WARN_IF(rv.Failed())) {
|
|
|
|
MOZ_CRASH();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-11-02 23:29:33 +03:00
|
|
|
// This is only implemented (returns a non-empty list) by MacOSX and Linux
|
|
|
|
// at present.
|
2017-11-02 20:23:16 +03:00
|
|
|
nsTArray<SystemFontListEntry> fontList;
|
2017-11-02 23:29:33 +03:00
|
|
|
gfxPlatform::GetPlatform()->ReadSystemFontList(&fontList);
|
2017-02-05 08:52:38 +03:00
|
|
|
nsTArray<LookAndFeelInt> lnfCache = LookAndFeel::GetIntCache();
|
|
|
|
|
|
|
|
// Content processes have no permission to access profile directory, so we
|
|
|
|
// send the file URL instead.
|
2018-03-28 18:34:34 +03:00
|
|
|
StyleSheet* ucs = nsLayoutStylesheetCache::Singleton()->UserContentSheet();
|
2017-02-05 08:52:38 +03:00
|
|
|
if (ucs) {
|
|
|
|
SerializeURI(ucs->GetSheetURI(), xpcomInit.userContentSheetURL());
|
|
|
|
} else {
|
|
|
|
SerializeURI(nullptr, xpcomInit.userContentSheetURL());
|
|
|
|
}
|
|
|
|
|
2017-06-28 00:04:17 +03:00
|
|
|
// 1. Build ContentDeviceData first, as it may affect some gfxVars.
|
2017-06-22 20:45:48 +03:00
|
|
|
gfxPlatform::GetPlatform()->BuildContentDeviceData(&xpcomInit.contentDeviceData());
|
2017-06-28 00:04:17 +03:00
|
|
|
// 2. Gather non-default gfxVars.
|
|
|
|
xpcomInit.gfxNonDefaultVarUpdates() = gfxVars::FetchNonDefaultVars();
|
|
|
|
// 3. Start listening for gfxVars updates, to notify content process later on.
|
|
|
|
gfxVars::AddReceiver(this);
|
2017-06-22 20:45:48 +03:00
|
|
|
|
2017-02-11 02:46:59 +03:00
|
|
|
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
|
|
|
if (gfxInfo) {
|
|
|
|
for (int32_t i = 1; i <= nsIGfxInfo::FEATURE_MAX_VALUE; ++i) {
|
|
|
|
int32_t status = 0;
|
|
|
|
nsAutoCString failureId;
|
|
|
|
gfxInfo->GetFeatureStatus(i, failureId, &status);
|
|
|
|
dom::GfxInfoFeatureStatus gfxFeatureStatus;
|
|
|
|
gfxFeatureStatus.feature() = i;
|
|
|
|
gfxFeatureStatus.status() = status;
|
|
|
|
gfxFeatureStatus.failureId() = failureId;
|
|
|
|
xpcomInit.gfxFeatureStatus().AppendElement(gfxFeatureStatus);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-16 05:19:14 +03:00
|
|
|
DataStorage::GetAllChildProcessData(xpcomInit.dataStorage());
|
|
|
|
|
2017-08-29 14:05:40 +03:00
|
|
|
// Send the dynamic scalar definitions to the new process.
|
|
|
|
TelemetryIPC::GetDynamicScalarDefinitions(xpcomInit.dynamicScalarDefs());
|
|
|
|
|
2017-03-09 14:30:26 +03:00
|
|
|
// Must send screen info before send initialData
|
|
|
|
ScreenManager& screenManager = ScreenManager::GetSingleton();
|
|
|
|
screenManager.CopyScreensToRemote(this);
|
2017-02-25 19:14:04 +03:00
|
|
|
|
2018-07-21 00:44:00 +03:00
|
|
|
Unused << SendSetXPCOMProcessAttributes(xpcomInit, initialData, lnfCache,
|
|
|
|
fontList);
|
|
|
|
|
2018-06-23 06:35:49 +03:00
|
|
|
ipc::WritableSharedMap* sharedData = nsFrameMessageManager::sParentProcessManager->SharedData();
|
|
|
|
sharedData->Flush();
|
2018-07-21 00:44:00 +03:00
|
|
|
sharedData->SendTo(this);
|
2017-02-05 08:52:38 +03:00
|
|
|
|
2018-02-21 21:35:36 +03:00
|
|
|
nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
|
|
|
|
nsChromeRegistryChrome* chromeRegistry =
|
|
|
|
static_cast<nsChromeRegistryChrome*>(registrySvc.get());
|
|
|
|
chromeRegistry->SendRegisteredChrome(this);
|
2015-04-20 22:50:34 +03:00
|
|
|
|
2018-06-30 08:53:12 +03:00
|
|
|
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
|
|
|
services::GetStringBundleService();
|
|
|
|
stringBundleService->SendContentBundles(this);
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (gAppData) {
|
|
|
|
nsCString version(gAppData->version);
|
|
|
|
nsCString buildID(gAppData->buildID);
|
|
|
|
nsCString name(gAppData->name);
|
|
|
|
nsCString UAName(gAppData->UAName);
|
|
|
|
nsCString ID(gAppData->ID);
|
|
|
|
nsCString vendor(gAppData->vendor);
|
2018-05-16 02:44:44 +03:00
|
|
|
nsCString sourceURL(gAppData->sourceURL);
|
2015-05-14 17:49:38 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Sending all information to content process.
|
2018-05-16 02:44:44 +03:00
|
|
|
Unused << SendAppInfo(version, buildID, name, UAName, ID, vendor, sourceURL);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-05-14 17:49:38 +03:00
|
|
|
|
2017-01-25 01:26:21 +03:00
|
|
|
// Send the child its remote type. On Mac, this needs to be sent prior
|
|
|
|
// to the message we send to enable the Sandbox (SendStartProcessSandbox)
|
|
|
|
// because different remote types require different sandbox privileges.
|
|
|
|
Unused << SendRemoteType(mRemoteType);
|
|
|
|
|
2017-05-03 03:17:52 +03:00
|
|
|
ScriptPreloader::InitContentChild(*this);
|
|
|
|
|
|
|
|
// Initialize the message manager (and load delayed scripts) now that we
|
|
|
|
// have established communications with the child.
|
|
|
|
mMessageManager->InitWithCallback(this);
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Set the subprocess's priority. We do this early on because we're likely
|
|
|
|
// /lowering/ the process's CPU and memory priority, which it has inherited
|
|
|
|
// from this process.
|
|
|
|
//
|
|
|
|
// This call can cause us to send IPC messages to the child process, so it
|
|
|
|
// must come after the Open() call above.
|
2017-08-15 22:08:14 +03:00
|
|
|
ProcessPriorityManager::SetProcessPriority(this, aInitialPriority);
|
|
|
|
|
2018-02-21 21:35:36 +03:00
|
|
|
// NB: internally, this will send an IPC message to the child
|
|
|
|
// process to get it to create the CompositorBridgeChild. This
|
|
|
|
// message goes through the regular IPC queue for this
|
|
|
|
// channel, so delivery will happen-before any other messages
|
|
|
|
// we send. The CompositorBridgeChild must be created before any
|
|
|
|
// PBrowsers are created, because they rely on the Compositor
|
|
|
|
// already being around. (Creation is async, so can't happen
|
|
|
|
// on demand.)
|
|
|
|
GPUProcessManager* gpm = GPUProcessManager::Get();
|
|
|
|
|
|
|
|
Endpoint<PCompositorManagerChild> compositor;
|
|
|
|
Endpoint<PImageBridgeChild> imageBridge;
|
|
|
|
Endpoint<PVRManagerChild> vrBridge;
|
|
|
|
Endpoint<PVideoDecoderManagerChild> videoManager;
|
|
|
|
AutoTArray<uint32_t, 3> namespaces;
|
|
|
|
|
|
|
|
DebugOnly<bool> opened = gpm->CreateContentBridges(OtherPid(),
|
|
|
|
&compositor,
|
|
|
|
&imageBridge,
|
|
|
|
&vrBridge,
|
|
|
|
&videoManager,
|
|
|
|
&namespaces);
|
|
|
|
MOZ_ASSERT(opened);
|
|
|
|
|
2018-05-30 22:15:35 +03:00
|
|
|
Unused << SendInitRendering(std::move(compositor),
|
|
|
|
std::move(imageBridge),
|
|
|
|
std::move(vrBridge),
|
|
|
|
std::move(videoManager),
|
2018-02-21 21:35:36 +03:00
|
|
|
namespaces);
|
|
|
|
|
|
|
|
gpm->AddListener(this);
|
2013-11-29 13:28:54 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
|
|
|
|
if (sheetService) {
|
|
|
|
// This looks like a lot of work, but in a normal browser session we just
|
|
|
|
// send two loads.
|
2017-02-21 05:42:27 +03:00
|
|
|
//
|
|
|
|
// The URIs of the Gecko and Servo sheets should be the same, so it
|
2018-02-01 07:04:04 +03:00
|
|
|
// shouldn't matter which we look at.
|
2013-11-29 13:28:54 +04:00
|
|
|
|
2018-03-28 18:34:34 +03:00
|
|
|
for (StyleSheet* sheet : *sheetService->AgentStyleSheets()) {
|
2016-01-05 12:59:30 +03:00
|
|
|
URIParams uri;
|
|
|
|
SerializeURI(sheet->GetSheetURI(), uri);
|
|
|
|
Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::AGENT_SHEET);
|
|
|
|
}
|
2013-11-29 13:28:54 +04:00
|
|
|
|
2018-03-28 18:34:34 +03:00
|
|
|
for (StyleSheet* sheet : *sheetService->UserStyleSheets()) {
|
2016-01-05 12:59:30 +03:00
|
|
|
URIParams uri;
|
|
|
|
SerializeURI(sheet->GetSheetURI(), uri);
|
|
|
|
Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::USER_SHEET);
|
|
|
|
}
|
2013-11-29 13:28:54 +04:00
|
|
|
|
2018-03-28 18:34:34 +03:00
|
|
|
for (StyleSheet* sheet : *sheetService->AuthorStyleSheets()) {
|
2016-01-05 12:59:30 +03:00
|
|
|
URIParams uri;
|
|
|
|
SerializeURI(sheet->GetSheetURI(), uri);
|
|
|
|
Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::AUTHOR_SHEET);
|
2013-11-29 13:28:54 +04:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2013-11-29 13:28:54 +04:00
|
|
|
|
2018-01-11 01:07:56 +03:00
|
|
|
#if defined(XP_WIN)
|
|
|
|
// Send the info needed to join the browser process's audio session.
|
|
|
|
nsID id;
|
|
|
|
nsString sessionName;
|
|
|
|
nsString iconPath;
|
|
|
|
if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName,
|
|
|
|
iconPath))) {
|
|
|
|
Unused << SendSetAudioSessionData(id, sessionName, iconPath);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-11-29 13:28:54 +04:00
|
|
|
#ifdef MOZ_CONTENT_SANDBOX
|
2016-01-05 12:59:30 +03:00
|
|
|
bool shouldSandbox = true;
|
|
|
|
MaybeFileDesc brokerFd = void_t();
|
2016-06-16 13:39:07 +03:00
|
|
|
// XXX: Checking the pref here makes it possible to enable/disable sandboxing
|
|
|
|
// during an active session. Currently the pref is only used for testing
|
|
|
|
// purpose. If the decision is made to permanently rely on the pref, this
|
|
|
|
// should be changed so that it is required to restart firefox for the change
|
|
|
|
// of value to take effect.
|
2017-06-01 17:38:22 +03:00
|
|
|
shouldSandbox = IsContentSandboxEnabled();
|
2016-06-16 13:39:07 +03:00
|
|
|
|
2017-06-07 22:30:09 +03:00
|
|
|
#ifdef XP_LINUX
|
2016-01-05 12:59:30 +03:00
|
|
|
if (shouldSandbox) {
|
|
|
|
MOZ_ASSERT(!mSandboxBroker);
|
2017-07-24 17:32:22 +03:00
|
|
|
bool isFileProcess = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE);
|
2016-01-05 12:59:30 +03:00
|
|
|
UniquePtr<SandboxBroker::Policy> policy =
|
2017-07-24 17:32:22 +03:00
|
|
|
sSandboxBrokerPolicyFactory->GetContentPolicy(Pid(), isFileProcess);
|
2016-01-05 12:59:30 +03:00
|
|
|
if (policy) {
|
|
|
|
brokerFd = FileDescriptor();
|
2018-05-30 22:15:35 +03:00
|
|
|
mSandboxBroker = SandboxBroker::Create(std::move(policy), Pid(), brokerFd);
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!mSandboxBroker) {
|
|
|
|
KillHard("SandboxBroker::Create failed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(static_cast<const FileDescriptor&>(brokerFd).IsValid());
|
2015-10-08 08:13:09 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-10-08 08:13:09 +03:00
|
|
|
#endif
|
2016-01-05 12:59:30 +03:00
|
|
|
if (shouldSandbox && !SendSetProcessSandbox(brokerFd)) {
|
|
|
|
KillHard("SandboxInitFailed");
|
|
|
|
}
|
2013-11-29 13:28:54 +04:00
|
|
|
#endif
|
2016-07-13 11:34:24 +03:00
|
|
|
|
2018-07-10 02:02:41 +03:00
|
|
|
if (!ServiceWorkerParentInterceptEnabled()) {
|
2016-07-17 17:50:50 +03:00
|
|
|
RefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();
|
|
|
|
MOZ_ASSERT(swr);
|
2016-07-13 11:34:24 +03:00
|
|
|
|
2016-07-17 17:50:50 +03:00
|
|
|
nsTArray<ServiceWorkerRegistrationData> registrations;
|
|
|
|
swr->GetRegistrations(registrations);
|
2017-04-11 23:37:15 +03:00
|
|
|
|
|
|
|
// Send down to the content process the permissions for each of the
|
|
|
|
// registered service worker scopes.
|
|
|
|
for (auto& registration : registrations) {
|
|
|
|
nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(registration.principal());
|
|
|
|
if (principal) {
|
|
|
|
TransmitPermissionsForPrincipal(principal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-17 17:50:50 +03:00
|
|
|
Unused << SendInitServiceWorkers(ServiceWorkerConfiguration(registrations));
|
|
|
|
}
|
2016-07-13 11:34:24 +03:00
|
|
|
|
2016-07-17 17:50:50 +03:00
|
|
|
{
|
|
|
|
nsTArray<BlobURLRegistrationData> registrations;
|
2018-06-02 16:51:42 +03:00
|
|
|
if (BlobURLProtocolHandler::GetAllBlobURLEntries(registrations, this)) {
|
2018-05-17 14:36:50 +03:00
|
|
|
for (const BlobURLRegistrationData& registration : registrations) {
|
|
|
|
nsresult rv = TransmitPermissionsForPrincipal(registration.principal());
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(rv));
|
|
|
|
}
|
|
|
|
|
2016-07-17 17:50:50 +03:00
|
|
|
Unused << SendInitBlobURLs(registrations);
|
|
|
|
}
|
|
|
|
}
|
2017-06-06 20:39:46 +03:00
|
|
|
|
|
|
|
// Start up nsPluginHost and run FindPlugins to cache the plugin list.
|
|
|
|
// If this isn't our first content process, just send over cached list.
|
|
|
|
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
|
|
|
|
pluginHost->SendPluginsToContent();
|
2017-07-28 10:14:54 +03:00
|
|
|
MaybeEnableRemoteInputEventQueue();
|
2013-11-29 13:28:54 +04:00
|
|
|
}
|
|
|
|
|
2010-04-12 04:24:45 +04:00
|
|
|
bool
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentParent::IsAlive() const
|
2010-04-12 04:24:45 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return mIsAlive;
|
2009-09-03 04:18:27 +04:00
|
|
|
}
|
|
|
|
|
2013-07-18 01:31:10 +04:00
|
|
|
int32_t
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentParent::Pid() const
|
2013-07-18 01:31:10 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!mSubprocess || !mSubprocess->GetChildProcessHandle()) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return base::GetProcId(mSubprocess->GetChildProcessHandle());
|
2013-07-18 01:31:10 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-08-04 21:33:42 +03:00
|
|
|
ContentParent::RecvGetGfxVars(InfallibleTArray<GfxVarUpdate>* aVars)
|
|
|
|
{
|
|
|
|
// Ensure gfxVars is initialized (for xpcshell tests).
|
|
|
|
gfxVars::Initialize();
|
|
|
|
|
|
|
|
*aVars = gfxVars::FetchNonDefaultVars();
|
|
|
|
|
|
|
|
// Now that content has initialized gfxVars, we can start listening for
|
|
|
|
// updates.
|
|
|
|
gfxVars::AddReceiver(this);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-08-04 21:33:42 +03:00
|
|
|
}
|
|
|
|
|
2016-09-20 11:18:50 +03:00
|
|
|
void
|
|
|
|
ContentParent::OnCompositorUnexpectedShutdown()
|
|
|
|
{
|
|
|
|
GPUProcessManager* gpm = GPUProcessManager::Get();
|
|
|
|
|
2017-06-14 18:39:59 +03:00
|
|
|
Endpoint<PCompositorManagerChild> compositor;
|
2016-09-20 11:18:50 +03:00
|
|
|
Endpoint<PImageBridgeChild> imageBridge;
|
|
|
|
Endpoint<PVRManagerChild> vrBridge;
|
2016-11-08 05:21:35 +03:00
|
|
|
Endpoint<PVideoDecoderManagerChild> videoManager;
|
2017-06-14 18:39:59 +03:00
|
|
|
AutoTArray<uint32_t, 3> namespaces;
|
2016-09-20 11:18:50 +03:00
|
|
|
|
|
|
|
DebugOnly<bool> opened = gpm->CreateContentBridges(
|
|
|
|
OtherPid(),
|
|
|
|
&compositor,
|
|
|
|
&imageBridge,
|
2016-11-08 05:21:35 +03:00
|
|
|
&vrBridge,
|
2017-04-14 11:06:09 +03:00
|
|
|
&videoManager,
|
|
|
|
&namespaces);
|
2016-09-20 11:18:50 +03:00
|
|
|
MOZ_ASSERT(opened);
|
|
|
|
|
|
|
|
Unused << SendReinitRendering(
|
2018-05-30 22:15:35 +03:00
|
|
|
std::move(compositor),
|
|
|
|
std::move(imageBridge),
|
|
|
|
std::move(vrBridge),
|
|
|
|
std::move(videoManager),
|
2017-06-14 18:39:59 +03:00
|
|
|
namespaces);
|
2016-09-20 11:18:50 +03:00
|
|
|
}
|
|
|
|
|
2017-05-12 08:44:27 +03:00
|
|
|
void
|
|
|
|
ContentParent::OnCompositorDeviceReset()
|
|
|
|
{
|
|
|
|
Unused << SendReinitRenderingForDeviceReset();
|
|
|
|
}
|
|
|
|
|
2017-11-01 20:19:38 +03:00
|
|
|
PClientOpenWindowOpParent*
|
|
|
|
ContentParent::AllocPClientOpenWindowOpParent(const ClientOpenWindowArgs& aArgs)
|
|
|
|
{
|
|
|
|
return AllocClientOpenWindowOpParent(aArgs);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPClientOpenWindowOpParent(PClientOpenWindowOpParent* aActor)
|
|
|
|
{
|
|
|
|
return DeallocClientOpenWindowOpParent(aActor);
|
|
|
|
}
|
|
|
|
|
2017-07-28 10:14:54 +03:00
|
|
|
void
|
|
|
|
ContentParent::MaybeEnableRemoteInputEventQueue()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(!mIsRemoteInputEventQueueEnabled);
|
|
|
|
if (!IsInputEventQueueSupported()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mIsRemoteInputEventQueueEnabled = true;
|
|
|
|
Unused << SendSetInputEventQueueEnabled();
|
|
|
|
SetInputPriorityEventEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ContentParent::SetInputPriorityEventEnabled(bool aEnabled)
|
|
|
|
{
|
|
|
|
if (!IsInputEventQueueSupported() ||
|
|
|
|
!mIsRemoteInputEventQueueEnabled ||
|
|
|
|
mIsInputPriorityEventEnabled == aEnabled) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mIsInputPriorityEventEnabled = aEnabled;
|
|
|
|
// Send IPC messages to flush the pending events in the input event queue and
|
|
|
|
// the normal event queue. See PContent.ipdl for more details.
|
|
|
|
Unused << SendSuspendInputEventQueue();
|
|
|
|
Unused << SendFlushInputEventQueue();
|
|
|
|
Unused << SendResumeInputEventQueue();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ bool
|
|
|
|
ContentParent::IsInputEventQueueSupported()
|
|
|
|
{
|
|
|
|
static bool sSupported = false;
|
|
|
|
static bool sInitialized = false;
|
|
|
|
if (!sInitialized) {
|
|
|
|
MOZ_ASSERT(Preferences::IsServiceAvailable());
|
|
|
|
sSupported = Preferences::GetBool("input_event_queue.supported", false);
|
|
|
|
sInitialized = true;
|
|
|
|
}
|
|
|
|
return sSupported;
|
|
|
|
}
|
|
|
|
|
2016-08-04 21:33:42 +03:00
|
|
|
void
|
|
|
|
ContentParent::OnVarChanged(const GfxVarUpdate& aVar)
|
|
|
|
{
|
|
|
|
if (!mIPCOpen) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Unused << SendVarUpdate(aVar);
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2011-01-13 07:04:42 +03:00
|
|
|
ContentParent::RecvReadFontList(InfallibleTArray<FontListEntry>* retValue)
|
|
|
|
{
|
|
|
|
#ifdef ANDROID
|
2016-01-05 12:59:30 +03:00
|
|
|
gfxAndroidPlatform::GetPlatform()->GetSystemFontList(retValue);
|
2011-01-13 07:04:42 +03:00
|
|
|
#endif
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-01-13 07:04:42 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-04-16 22:38:12 +03:00
|
|
|
ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer,
|
|
|
|
const bool& aIsPrivateData,
|
2016-06-30 10:12:56 +03:00
|
|
|
const IPC::Principal& aRequestingPrincipal,
|
2018-03-14 11:44:36 +03:00
|
|
|
const uint32_t& aContentPolicyType,
|
2015-04-16 22:38:12 +03:00
|
|
|
const int32_t& aWhichClipboard)
|
2011-03-01 08:36:43 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2016-01-05 12:59:30 +03:00
|
|
|
|
2016-02-24 03:31:29 +03:00
|
|
|
nsCOMPtr<nsITransferable> trans =
|
|
|
|
do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2016-01-05 12:59:30 +03:00
|
|
|
trans->Init(nullptr);
|
|
|
|
|
2016-08-31 04:30:45 +03:00
|
|
|
rv = nsContentUtils::IPCTransferableToTransferable(aDataTransfer,
|
|
|
|
aIsPrivateData,
|
|
|
|
aRequestingPrincipal,
|
2018-03-14 11:44:36 +03:00
|
|
|
aContentPolicyType,
|
2016-08-31 04:30:45 +03:00
|
|
|
trans, this, nullptr);
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2015-04-16 22:38:12 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
clipboard->SetData(trans, nullptr, aWhichClipboard);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-03-01 08:36:43 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-04-16 22:38:12 +03:00
|
|
|
ContentParent::RecvGetClipboard(nsTArray<nsCString>&& aTypes,
|
|
|
|
const int32_t& aWhichClipboard,
|
|
|
|
IPCDataTransfer* aDataTransfer)
|
2011-03-01 08:36:43 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2011-03-01 08:36:43 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2016-01-05 12:59:30 +03:00
|
|
|
trans->Init(nullptr);
|
2014-02-10 04:13:10 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
for (uint32_t t = 0; t < aTypes.Length(); t++) {
|
|
|
|
trans->AddDataFlavor(aTypes[t].get());
|
|
|
|
}
|
2011-03-01 08:36:43 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
clipboard->GetData(trans, aWhichClipboard);
|
|
|
|
nsContentUtils::TransferableToIPCTransferable(trans, aDataTransfer,
|
|
|
|
true, nullptr, this);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-03-01 08:36:43 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-04-16 22:38:12 +03:00
|
|
|
ContentParent::RecvEmptyClipboard(const int32_t& aWhichClipboard)
|
2011-03-01 08:36:43 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2011-03-01 08:36:43 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
clipboard->EmptyClipboard(aWhichClipboard);
|
2011-03-01 08:36:43 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-03-01 08:36:43 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-04-16 22:38:12 +03:00
|
|
|
ContentParent::RecvClipboardHasType(nsTArray<nsCString>&& aTypes,
|
|
|
|
const int32_t& aWhichClipboard,
|
|
|
|
bool* aHasType)
|
2011-03-01 08:36:43 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2011-03-01 08:36:43 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
const char** typesChrs = new const char *[aTypes.Length()];
|
|
|
|
for (uint32_t t = 0; t < aTypes.Length(); t++) {
|
|
|
|
typesChrs[t] = aTypes[t].get();
|
|
|
|
}
|
2015-04-16 22:38:12 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
clipboard->HasDataMatchingFlavors(typesChrs, aTypes.Length(),
|
|
|
|
aWhichClipboard, aHasType);
|
2015-04-16 22:38:12 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
delete [] typesChrs;
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-03-01 08:36:43 +03:00
|
|
|
}
|
|
|
|
|
2018-01-16 15:24:51 +03:00
|
|
|
mozilla::ipc::IPCResult
|
Bug 1470540 - Improve performance of DataTransfer::CacheExternalClipboardFormats, r=baku,mccr8
Currently, in order to retrieve supported clipboard formats
DataTransfer::CacheExternalClipboardFormats repeatedly makes the same calls to
clipboard->HasDataMatchingFlavors.
In the case when aPlainTextOnly == true only 1 call is made -
clipboard->HasDataMatchingFlavors(kUnicodeMime, ...), and when
aPlainTextOnly == false we have 1 call made for every member of the list
{ kCustomTypesMime, kFileMime, kHTMLMime, kRTFMime, kURLMime, kURLDataMime,
kUnicodeMime, kPNGImageMime } - a total of 8 calls.
We can see that in nsClipboardProxy::HasDataMatchingFlavors, there is a call to
ContentChild::GetSingleton()->SendClipboardHasType.
So when aPlainTextOnly == true, we will have 1 sync message, and when
aPlainTextOnly == false, we will have 8 sync messages.
With the proposed solution, in DataTransfer::CacheExternalClipboardFormats
we will only have 1 sync message regardless of the case because
GetExternalClipboardFormats() will retrieve all supported clipboard
formats at once.
MozReview-Commit-ID: CAmBfqB459v
--HG--
extra : rebase_source : 27f1b420f2613e6a747ed63762f1583ab71ba3e0
2018-06-22 21:28:27 +03:00
|
|
|
ContentParent::RecvGetExternalClipboardFormats(const int32_t& aWhichClipboard,
|
|
|
|
const bool& aPlainTextOnly,
|
|
|
|
nsTArray<nsCString>* aTypes)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aTypes);
|
|
|
|
DataTransfer::GetExternalClipboardFormats(aWhichClipboard, aPlainTextOnly, aTypes);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
2018-01-16 15:24:51 +03:00
|
|
|
ContentParent::RecvPlaySound(const URIParams& aURI)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIURI> soundURI = DeserializeURI(aURI);
|
|
|
|
bool isChrome = false;
|
|
|
|
// If the check here fails, it can only mean that this message was spoofed.
|
|
|
|
if (!soundURI || NS_FAILED(soundURI->SchemeIs("chrome", &isChrome)) || !isChrome) {
|
2018-04-26 16:35:18 +03:00
|
|
|
// PlaySound only accepts a valid chrome URI.
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2018-01-16 15:24:51 +03:00
|
|
|
}
|
|
|
|
nsCOMPtr<nsIURL> soundURL(do_QueryInterface(soundURI));
|
|
|
|
if (!soundURL) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsISound> sound(do_GetService(NS_SOUND_CID, &rv));
|
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
|
|
|
|
|
|
|
sound->Play(soundURL);
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvBeep()
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsISound> sound(do_GetService(NS_SOUND_CID, &rv));
|
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
|
|
|
|
|
|
|
sound->Beep();
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvPlayEventSound(const uint32_t& aEventId)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsISound> sound(do_GetService(NS_SOUND_CID, &rv));
|
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
|
|
|
|
|
|
|
sound->PlayEventSound(aEventId);
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentParent::RecvGetSystemColors(const uint32_t& colorsCount,
|
|
|
|
InfallibleTArray<uint32_t>* colors)
|
2011-03-30 22:04:41 +04:00
|
|
|
{
|
2011-11-11 04:17:46 +04:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available");
|
|
|
|
if (AndroidBridge::Bridge() == nullptr) {
|
|
|
|
// Do not fail - the colors won't be right, but it's not critical
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2011-03-30 22:04:41 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
colors->AppendElements(colorsCount);
|
2011-03-30 22:04:41 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// The array elements correspond to the members of AndroidSystemColors structure,
|
|
|
|
// so just pass the pointer to the elements buffer
|
|
|
|
AndroidBridge::Bridge()->GetSystemColors((AndroidSystemColors*)colors->Elements());
|
2011-03-30 22:04:41 +04:00
|
|
|
#endif
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-03-30 22:04:41 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentParent::RecvGetIconForExtension(const nsCString& aFileExt,
|
|
|
|
const uint32_t& aIconSize,
|
|
|
|
InfallibleTArray<uint8_t>* bits)
|
2011-06-14 01:02:13 +04:00
|
|
|
{
|
2011-11-11 04:17:46 +04:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available");
|
|
|
|
if (AndroidBridge::Bridge() == nullptr) {
|
|
|
|
// Do not fail - just no icon will be shown
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2011-06-14 01:02:13 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
bits->AppendElements(aIconSize * aIconSize * 4);
|
2011-06-14 01:02:13 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
AndroidBridge::Bridge()->GetIconForExtension(aFileExt, aIconSize, bits->Elements());
|
2011-06-14 01:02:13 +04:00
|
|
|
#endif
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-06-14 01:02:13 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2011-09-29 10:19:26 +04:00
|
|
|
ContentParent::RecvGetShowPasswordSetting(bool* showPassword)
|
2011-07-27 05:14:52 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// default behavior is to show the last password character
|
|
|
|
*showPassword = true;
|
2011-11-11 04:17:46 +04:00
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available");
|
2013-11-12 22:41:01 +04:00
|
|
|
|
2016-07-21 20:49:04 +03:00
|
|
|
*showPassword = java::GeckoAppShell::GetShowPasswordSetting();
|
2011-07-27 05:14:52 +04:00
|
|
|
#endif
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2011-07-27 05:14:52 +04:00
|
|
|
}
|
|
|
|
|
2017-02-01 15:34:24 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvFirstIdle()
|
|
|
|
{
|
|
|
|
// When the ContentChild goes idle, it sends us a FirstIdle message
|
2017-07-11 18:30:08 +03:00
|
|
|
// which we use as a good time to signal the PreallocatedProcessManager
|
|
|
|
// that it can start allocating processes from now on.
|
|
|
|
PreallocatedProcessManager::RemoveBlocker(this);
|
2017-02-01 15:34:24 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2014-03-20 04:22:25 +04:00
|
|
|
// We want ContentParent to show up in CC logs for debugging purposes, but we
|
|
|
|
// don't actually cycle collect it.
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_0(ContentParent)
|
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(ContentParent)
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(ContentParent)
|
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ContentParent)
|
2014-06-11 09:44:03 +04:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIContentParent)
|
2014-03-20 04:22:25 +04:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionCallback)
|
2014-10-23 22:31:00 +04:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionErrorCallback)
|
2017-08-14 05:00:49 +03:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
2014-03-20 04:22:25 +04:00
|
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
|
|
|
|
NS_INTERFACE_MAP_END
|
2009-09-03 04:18:27 +04:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2010-07-19 22:33:33 +04:00
|
|
|
ContentParent::Observe(nsISupports* aSubject,
|
|
|
|
const char* aTopic,
|
2014-01-04 19:02:17 +04:00
|
|
|
const char16_t* aData)
|
2009-09-03 04:18:27 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (mSubprocess && (!strcmp(aTopic, "profile-before-change") ||
|
|
|
|
!strcmp(aTopic, "xpcom-shutdown"))) {
|
2018-01-18 04:37:20 +03:00
|
|
|
// Make sure that our process will get scheduled.
|
|
|
|
ProcessPriorityManager::SetProcessPriority(this,
|
|
|
|
PROCESS_PRIORITY_FOREGROUND);
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Okay to call ShutDownProcess multiple times.
|
|
|
|
ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
|
2018-06-23 06:35:49 +03:00
|
|
|
MarkAsDead();
|
2015-01-10 21:39:33 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// Wait for shutdown to complete, so that we receive any shutdown
|
|
|
|
// data (e.g. telemetry) from the child before we quit.
|
|
|
|
// This loop terminate prematurely based on mForceKillTimer.
|
2017-05-15 16:34:19 +03:00
|
|
|
SpinEventLoopUntil([&]() { return !mIPCOpen || mCalledKillHard; });
|
2016-01-05 12:59:30 +03:00
|
|
|
NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
|
|
|
|
}
|
2010-05-11 16:44:12 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!mIsAlive || !mSubprocess)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// listening for memory pressure event
|
2018-05-12 02:21:13 +03:00
|
|
|
if (!strcmp(aTopic, "memory-pressure")) {
|
2016-01-05 12:59:30 +03:00
|
|
|
Unused << SendFlushMemory(nsDependentString(aData));
|
|
|
|
}
|
|
|
|
else if (!strcmp(aTopic, "nsPref:changed")) {
|
2017-11-13 01:19:43 +03:00
|
|
|
// A pref changed. If it's not on the blacklist, inform child processes.
|
2017-08-11 20:18:22 +03:00
|
|
|
#define BLACKLIST_ENTRY(s) { s, (sizeof(s)/sizeof(char16_t)) - 1 }
|
|
|
|
struct BlacklistEntry {
|
|
|
|
const char16_t* mPrefBranch;
|
|
|
|
size_t mLen;
|
|
|
|
};
|
2017-11-13 01:19:43 +03:00
|
|
|
// These prefs are not useful in child processes.
|
2017-08-11 20:18:22 +03:00
|
|
|
static const BlacklistEntry sContentPrefBranchBlacklist[] = {
|
|
|
|
BLACKLIST_ENTRY(u"app.update.lastUpdateTime."),
|
|
|
|
BLACKLIST_ENTRY(u"datareporting.policy."),
|
|
|
|
BLACKLIST_ENTRY(u"browser.safebrowsing.provider."),
|
2018-07-07 22:45:57 +03:00
|
|
|
BLACKLIST_ENTRY(u"browser.shell."),
|
|
|
|
BLACKLIST_ENTRY(u"browser.slowstartup."),
|
2017-08-11 20:18:22 +03:00
|
|
|
BLACKLIST_ENTRY(u"extensions.getAddons.cache."),
|
|
|
|
BLACKLIST_ENTRY(u"media.gmp-manager."),
|
|
|
|
BLACKLIST_ENTRY(u"media.gmp-gmpopenh264."),
|
2018-07-07 22:45:57 +03:00
|
|
|
BLACKLIST_ENTRY(u"privacy.sanitize."),
|
2017-08-11 20:18:22 +03:00
|
|
|
};
|
|
|
|
#undef BLACKLIST_ENTRY
|
|
|
|
|
|
|
|
for (const auto& entry : sContentPrefBranchBlacklist) {
|
|
|
|
if (NS_strncmp(entry.mPrefBranch, aData, entry.mLen) == 0) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// We know prefs are ASCII here.
|
|
|
|
NS_LossyConvertUTF16toASCII strData(aData);
|
2010-10-20 00:35:08 +04:00
|
|
|
|
2017-11-29 01:29:07 +03:00
|
|
|
Pref pref(strData, /* isLocked */ false, null_t(), null_t());
|
2016-01-05 12:59:30 +03:00
|
|
|
Preferences::GetPreference(&pref);
|
|
|
|
if (!SendPreferenceUpdate(pref)) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
2013-12-03 08:07:02 +04:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
|
|
|
|
NS_ConvertUTF16toUTF8 dataStr(aData);
|
|
|
|
const char *offline = dataStr.get();
|
|
|
|
if (!SendSetOffline(!strcmp(offline, "true") ? true : false)) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
2012-04-20 04:13:20 +04:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC)) {
|
|
|
|
if (!SendSetConnectivity(NS_LITERAL_STRING("true").Equals(aData))) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
2012-08-18 06:43:00 +04:00
|
|
|
}
|
2016-11-17 19:35:24 +03:00
|
|
|
} else if (!strcmp(aTopic, NS_IPC_CAPTIVE_PORTAL_SET_STATE)) {
|
|
|
|
nsCOMPtr<nsICaptivePortalService> cps = do_QueryInterface(aSubject);
|
|
|
|
MOZ_ASSERT(cps, "Should QI to a captive portal service");
|
|
|
|
if (!cps) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
int32_t state;
|
|
|
|
cps->GetState(&state);
|
|
|
|
if (!SendSetCaptivePortalState(state)) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
// listening for alert notifications
|
|
|
|
else if (!strcmp(aTopic, "alertfinished") ||
|
|
|
|
!strcmp(aTopic, "alertclickcallback") ||
|
|
|
|
!strcmp(aTopic, "alertshow") ||
|
|
|
|
!strcmp(aTopic, "alertdisablecallback") ||
|
|
|
|
!strcmp(aTopic, "alertsettingscallback")) {
|
|
|
|
if (!SendNotifyAlertsObserver(nsDependentCString(aTopic),
|
|
|
|
nsDependentString(aData)))
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
else if (!strcmp(aTopic, "child-gc-request")){
|
|
|
|
Unused << SendGarbageCollect();
|
|
|
|
}
|
|
|
|
else if (!strcmp(aTopic, "child-cc-request")){
|
|
|
|
Unused << SendCycleCollect();
|
|
|
|
}
|
|
|
|
else if (!strcmp(aTopic, "child-mmu-request")){
|
|
|
|
Unused << SendMinimizeMemoryUsage();
|
|
|
|
}
|
2018-01-12 01:14:09 +03:00
|
|
|
else if (!strcmp(aTopic, "child-ghost-request")){
|
|
|
|
Unused << SendUnlinkGhosts();
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
else if (!strcmp(aTopic, "last-pb-context-exited")) {
|
|
|
|
Unused << SendLastPrivateDocShellDestroyed();
|
|
|
|
}
|
2011-07-21 08:37:32 +04:00
|
|
|
#ifdef ACCESSIBILITY
|
2016-08-29 18:06:48 +03:00
|
|
|
else if (aData && !strcmp(aTopic, "a11y-init-or-shutdown")) {
|
|
|
|
if (*aData == '1') {
|
|
|
|
// Make sure accessibility is running in content process when
|
|
|
|
// accessibility gets initiated in chrome process.
|
2016-10-17 22:08:21 +03:00
|
|
|
#if defined(XP_WIN)
|
2017-09-09 00:05:06 +03:00
|
|
|
// Don't init content a11y if we detect an incompat version of JAWS in use.
|
|
|
|
if (!mozilla::a11y::Compatibility::IsOldJAWS()) {
|
|
|
|
Unused << SendActivateA11y(::GetCurrentThreadId(),
|
|
|
|
a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
|
|
|
|
}
|
2016-10-17 22:08:21 +03:00
|
|
|
#else
|
2017-06-07 02:35:51 +03:00
|
|
|
Unused << SendActivateA11y(0, 0);
|
2011-07-21 08:37:32 +04:00
|
|
|
#endif
|
2016-08-29 18:06:48 +03:00
|
|
|
} else {
|
|
|
|
// If possible, shut down accessibility in content process when
|
|
|
|
// accessibility gets shutdown in chrome process.
|
|
|
|
Unused << SendShutdownA11y();
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-11-18 20:50:25 +03:00
|
|
|
#endif
|
2016-08-08 06:04:55 +03:00
|
|
|
else if (!strcmp(aTopic, "cacheservice:empty-cache")) {
|
|
|
|
Unused << SendNotifyEmptyHTTPCache();
|
|
|
|
}
|
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
|
|
|
else if (!strcmp(aTopic, "intl:app-locales-changed")) {
|
|
|
|
nsTArray<nsCString> appLocales;
|
2018-08-01 00:42:37 +03:00
|
|
|
LocaleService::GetInstance()->GetAppLocalesAsBCP47(appLocales);
|
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
|
|
|
Unused << SendUpdateAppLocales(appLocales);
|
|
|
|
}
|
|
|
|
else if (!strcmp(aTopic, "intl:requested-locales-changed")) {
|
|
|
|
nsTArray<nsCString> requestedLocales;
|
|
|
|
LocaleService::GetInstance()->GetRequestedLocales(requestedLocales);
|
|
|
|
Unused << SendUpdateRequestedLocales(requestedLocales);
|
|
|
|
}
|
2018-04-19 14:18:50 +03:00
|
|
|
else if (!strcmp(aTopic, "cookie-changed") ||
|
|
|
|
!strcmp(aTopic, "private-cookie-changed")) {
|
2017-08-03 13:00:12 +03:00
|
|
|
if (!aData) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
PNeckoParent *neckoParent = LoneManagedOrNullAsserts(ManagedPNeckoParent());
|
|
|
|
if (!neckoParent) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
PCookieServiceParent *csParent = LoneManagedOrNullAsserts(neckoParent->ManagedPCookieServiceParent());
|
|
|
|
if (!csParent) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
auto *cs = static_cast<CookieServiceParent*>(csParent);
|
2018-04-19 14:18:50 +03:00
|
|
|
// Do not push these cookie updates to the same process they originated from.
|
|
|
|
if (cs->ProcessingCookie()) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2017-08-03 13:00:12 +03:00
|
|
|
if (!nsCRT::strcmp(aData, u"batch-deleted")) {
|
|
|
|
nsCOMPtr<nsIArray> cookieList = do_QueryInterface(aSubject);
|
|
|
|
NS_ASSERTION(cookieList, "couldn't get cookie list");
|
|
|
|
cs->RemoveBatchDeletedCookies(cookieList);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!nsCRT::strcmp(aData, u"cleared")) {
|
|
|
|
cs->RemoveAll();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsICookie> xpcCookie = do_QueryInterface(aSubject);
|
|
|
|
NS_ASSERTION(xpcCookie, "couldn't get cookie");
|
|
|
|
if (!nsCRT::strcmp(aData, u"deleted")) {
|
|
|
|
cs->RemoveCookie(xpcCookie);
|
|
|
|
} else if ((!nsCRT::strcmp(aData, u"added")) ||
|
|
|
|
(!nsCRT::strcmp(aData, u"changed"))) {
|
|
|
|
cs->AddCookie(xpcCookie);
|
|
|
|
}
|
2018-06-20 18:57:50 +03:00
|
|
|
} else if (!strcmp(aTopic, "clear-site-data-reload-needed")) {
|
|
|
|
// Rebroadcast "clear-site-data-reload-needed".
|
|
|
|
Unused << SendClearSiteDataReloadNeeded(nsString(aData));
|
2017-08-03 13:00:12 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
return NS_OK;
|
2009-09-03 04:18:27 +04:00
|
|
|
}
|
|
|
|
|
2017-08-14 05:00:49 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
ContentParent::GetInterface(const nsIID& aIID, void** aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
|
|
|
|
if (aIID.Equals(NS_GET_IID(nsIMessageSender))) {
|
|
|
|
nsCOMPtr<nsIMessageSender> mm = GetMessageManager();
|
|
|
|
mm.forget(aResult);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
2017-01-24 22:49:13 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvInitBackground(Endpoint<PBackgroundParent>&& aEndpoint)
|
2013-11-27 11:59:41 +04:00
|
|
|
{
|
2018-05-30 22:15:35 +03:00
|
|
|
if (!BackgroundParent::Alloc(this, std::move(aEndpoint))) {
|
2017-01-24 22:49:13 +03:00
|
|
|
return IPC_FAIL(this, "BackgroundParent::Alloc failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
2014-05-01 05:52:00 +04:00
|
|
|
}
|
|
|
|
|
2013-07-03 11:24:32 +04:00
|
|
|
mozilla::jsipc::PJavaScriptParent *
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::AllocPJavaScriptParent()
|
2013-07-03 11:24:32 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(ManagedPJavaScriptParent().IsEmpty());
|
|
|
|
return nsIContentParent::AllocPJavaScriptParent();
|
2013-07-03 11:24:32 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
|
2013-07-03 11:24:32 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return nsIContentParent::DeallocPJavaScriptParent(parent);
|
2013-07-03 11:24:32 +04:00
|
|
|
}
|
|
|
|
|
2010-07-19 22:33:33 +04:00
|
|
|
PBrowserParent*
|
2014-10-29 21:11:00 +03:00
|
|
|
ContentParent::AllocPBrowserParent(const TabId& aTabId,
|
2017-04-07 02:46:18 +03:00
|
|
|
const TabId& aSameTabGroupAs,
|
2014-10-29 21:11:00 +03:00
|
|
|
const IPCTabContext& aContext,
|
2014-06-04 01:15:27 +04:00
|
|
|
const uint32_t& aChromeFlags,
|
2014-10-24 04:28:00 +04:00
|
|
|
const ContentParentId& aCpId,
|
2014-06-04 01:15:27 +04:00
|
|
|
const bool& aIsForBrowser)
|
2009-08-12 20:18:08 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return nsIContentParent::AllocPBrowserParent(aTabId,
|
2017-04-07 02:46:18 +03:00
|
|
|
aSameTabGroupAs,
|
2016-01-05 12:59:30 +03:00
|
|
|
aContext,
|
|
|
|
aChromeFlags,
|
|
|
|
aCpId,
|
|
|
|
aIsForBrowser);
|
2009-08-12 20:18:08 +04:00
|
|
|
}
|
|
|
|
|
2009-09-18 03:09:20 +04:00
|
|
|
bool
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::DeallocPBrowserParent(PBrowserParent* frame)
|
2009-08-12 20:18:08 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return nsIContentParent::DeallocPBrowserParent(frame);
|
2009-08-12 20:18:08 +04:00
|
|
|
}
|
|
|
|
|
2017-03-21 10:44:12 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvPBrowserConstructor(PBrowserParent* actor,
|
|
|
|
const TabId& tabId,
|
|
|
|
const TabId& sameTabGroupAs,
|
|
|
|
const IPCTabContext& context,
|
|
|
|
const uint32_t& chromeFlags,
|
|
|
|
const ContentParentId& cpId,
|
|
|
|
const bool& isForBrowser)
|
|
|
|
{
|
|
|
|
return nsIContentParent::RecvPBrowserConstructor(actor,
|
|
|
|
tabId,
|
|
|
|
sameTabGroupAs,
|
|
|
|
context,
|
|
|
|
chromeFlags,
|
|
|
|
cpId,
|
|
|
|
isForBrowser);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
PIPCBlobInputStreamParent*
|
|
|
|
ContentParent::AllocPIPCBlobInputStreamParent(const nsID& aID,
|
|
|
|
const uint64_t& aSize)
|
|
|
|
{
|
|
|
|
return nsIContentParent::AllocPIPCBlobInputStreamParent(aID, aSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPIPCBlobInputStreamParent(PIPCBlobInputStreamParent* aActor)
|
|
|
|
{
|
|
|
|
return nsIContentParent::DeallocPIPCBlobInputStreamParent(aActor);
|
|
|
|
}
|
|
|
|
|
2014-07-02 02:24:27 +04:00
|
|
|
mozilla::PRemoteSpellcheckEngineParent *
|
|
|
|
ContentParent::AllocPRemoteSpellcheckEngineParent()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
mozilla::RemoteSpellcheckEngineParent *parent = new mozilla::RemoteSpellcheckEngineParent();
|
|
|
|
return parent;
|
2014-07-02 02:24:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent *parent)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
delete parent;
|
|
|
|
return true;
|
2014-07-02 02:24:27 +04:00
|
|
|
}
|
|
|
|
|
2015-01-07 08:42:23 +03:00
|
|
|
/* static */ void
|
|
|
|
ContentParent::ForceKillTimerCallback(nsITimer* aTimer, void* aClosure)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// We don't want to time out the content process during XPCShell tests. This
|
|
|
|
// is the easiest way to ensure that.
|
|
|
|
if (PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR")) {
|
|
|
|
return;
|
|
|
|
}
|
2015-09-09 03:12:27 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
auto self = static_cast<ContentParent*>(aClosure);
|
|
|
|
self->KillHard("ShutDownKill");
|
2015-01-07 08:42:23 +03:00
|
|
|
}
|
|
|
|
|
2016-05-04 06:08:41 +03:00
|
|
|
// WARNING: aReason appears in telemetry, so any new value passed in requires
|
|
|
|
// data review.
|
2012-09-06 02:18:48 +04:00
|
|
|
void
|
2015-02-03 20:09:27 +03:00
|
|
|
ContentParent::KillHard(const char* aReason)
|
2012-09-06 02:18:48 +04:00
|
|
|
{
|
Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange.
This patch makes the following changes to the macros.
- Removes PROFILER_LABEL_FUNC. It's only suitable for use in functions outside
classes, due to PROFILER_FUNCTION_NAME not getting class names, and it was
mostly misused.
- Removes PROFILER_FUNCTION_NAME. It's no longer used, and __func__ is
universally available now anyway.
- Combines the first two string literal arguments of PROFILER_LABEL and
PROFILER_LABEL_DYNAMIC into a single argument. There was no good reason for
them to be separate, and it forced a '::' in the label, which isn't always
appropriate. Also, the meaning of the "name_space" argument was interpreted
in an interesting variety of ways.
- Adds an "AUTO_" prefix to PROFILER_LABEL and PROFILER_LABEL_DYNAMIC, to make
it clearer they construct RAII objects rather than just being function calls.
(I myself have screwed up the scoping because of this in the past.)
- Fills in the 'js::ProfileEntry::Category::' qualifier within the macro, so
the caller doesn't need to. This makes a *lot* more of the uses fit onto a
single line.
The patch also makes the following changes to the macro uses (beyond those
required by the changes described above).
- Fixes a bunch of labels that had gotten out of sync with the name of the
class and/or function that encloses them.
- Removes a useless PROFILER_LABEL use within a trivial scope in
EventStateManager::DispatchMouseOrPointerEvent(). It clearly wasn't serving
any useful purpose. It also serves as extra evidence that the AUTO_ prefix is
a good idea.
- Tweaks DecodePool::SyncRunIf{Preferred,Possible} so that the labelling is
done within them, instead of at their callsites, because that's a more
standard way of doing things.
--HG--
extra : rebase_source : 318d1bc6fc1425a94aacbf489dd46e4f83211de4
2017-06-22 10:08:53 +03:00
|
|
|
AUTO_PROFILER_LABEL("ContentParent::KillHard", OTHER);
|
2016-01-15 01:03:11 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// On Windows, calling KillHard multiple times causes problems - the
|
|
|
|
// process handle becomes invalid on the first call, causing a second call
|
|
|
|
// to crash our process - more details in bug 890840.
|
|
|
|
if (mCalledKillHard) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mCalledKillHard = true;
|
|
|
|
mForceKillTimer = nullptr;
|
2014-11-24 23:05:45 +03:00
|
|
|
|
2018-04-18 04:38:22 +03:00
|
|
|
MessageChannel* channel = GetIPCChannel();
|
|
|
|
if (channel) {
|
|
|
|
channel->SetInKillHardShutdown();
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// We're about to kill the child process associated with this content.
|
|
|
|
// Something has gone wrong to get us here, so we generate a minidump
|
|
|
|
// of the parent and child for submission to the crash server.
|
2017-02-17 05:44:16 +03:00
|
|
|
if (mCrashReporter) {
|
2016-01-05 12:59:30 +03:00
|
|
|
// GeneratePairedMinidump creates two minidumps for us - the main
|
|
|
|
// one is for the content process we're about to kill, and the other
|
|
|
|
// one is for the main browser process. That second one is the extra
|
|
|
|
// minidump tagging along, so we have to tell the crash reporter that
|
|
|
|
// it exists and is being appended.
|
|
|
|
nsAutoCString additionalDumps("browser");
|
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
|
|
|
mCrashReporter->AddAnnotation(
|
|
|
|
CrashReporter::Annotation::additional_minidumps, additionalDumps);
|
2016-01-05 12:59:30 +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
|
|
|
mCrashReporter->AddAnnotation(CrashReporter::Annotation::ipc_channel_error,
|
|
|
|
reason);
|
2016-01-05 12:59:30 +03:00
|
|
|
|
2017-06-22 13:52:58 +03:00
|
|
|
Telemetry::Accumulate(Telemetry::SUBPROCESS_KILL_HARD, reason, 1);
|
|
|
|
|
|
|
|
RefPtr<ContentParent> self = this;
|
|
|
|
std::function<void(bool)> callback = [self](bool aResult) {
|
|
|
|
self->OnGenerateMinidumpComplete(aResult);
|
|
|
|
};
|
2016-01-05 12:59:30 +03:00
|
|
|
// Generate the report and insert into the queue for submittal.
|
2017-06-22 13:52:58 +03:00
|
|
|
mCrashReporter->GenerateMinidumpAndPair(Process(),
|
|
|
|
nullptr,
|
|
|
|
NS_LITERAL_CSTRING("browser"),
|
2018-05-30 22:15:35 +03:00
|
|
|
std::move(callback),
|
2017-06-22 13:52:58 +03:00
|
|
|
true);
|
|
|
|
return;
|
|
|
|
}
|
2017-10-10 13:43:09 +03:00
|
|
|
|
2017-06-22 13:52:58 +03:00
|
|
|
OnGenerateMinidumpComplete(false);
|
|
|
|
}
|
2016-05-04 06:08:41 +03:00
|
|
|
|
2017-06-22 13:52:58 +03:00
|
|
|
void
|
|
|
|
ContentParent::OnGenerateMinidumpComplete(bool aDumpResult)
|
|
|
|
{
|
|
|
|
if (mCrashReporter && aDumpResult) {
|
|
|
|
// CrashReporterHost::GenerateMinidumpAndPair() is successful.
|
|
|
|
mCreatedPairedMinidumps = mCrashReporter->FinalizeCrashReport();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2017-06-22 13:52:58 +03:00
|
|
|
|
|
|
|
Unused << aDumpResult; // Don't care about result if no minidump was requested.
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
ProcessHandle otherProcessHandle;
|
|
|
|
if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle)) {
|
|
|
|
NS_ERROR("Failed to open child process when attempting kill.");
|
|
|
|
return;
|
|
|
|
}
|
2015-04-01 11:40:35 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!KillProcess(otherProcessHandle, base::PROCESS_END_KILLED_BY_USER,
|
|
|
|
false)) {
|
|
|
|
NS_WARNING("failed to kill subprocess!");
|
|
|
|
}
|
2015-04-01 11:40:35 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
if (mSubprocess) {
|
|
|
|
mSubprocess->SetAlreadyDead();
|
|
|
|
}
|
2015-04-01 11:40:35 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// EnsureProcessTerminated has responsibilty for closing otherProcessHandle.
|
|
|
|
XRE_GetIOMessageLoop()->PostTask(
|
2017-10-27 23:39:28 +03:00
|
|
|
NewRunnableFunction("EnsureProcessTerminatedRunnable",
|
|
|
|
&ProcessWatcher::EnsureProcessTerminated,
|
2016-01-05 12:59:30 +03:00
|
|
|
otherProcessHandle, /*force=*/true));
|
2012-09-06 02:18:48 +04:00
|
|
|
}
|
|
|
|
|
2013-04-26 04:53:26 +04:00
|
|
|
void
|
2014-05-21 10:06:54 +04:00
|
|
|
ContentParent::FriendlyName(nsAString& aName, bool aAnonymize)
|
2013-04-26 04:53:26 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
aName.Truncate();
|
2016-10-19 04:54:12 +03:00
|
|
|
if (mIsForBrowser) {
|
2016-01-05 12:59:30 +03:00
|
|
|
aName.AssignLiteral("Browser");
|
|
|
|
} else if (aAnonymize) {
|
|
|
|
aName.AssignLiteral("<anonymized-name>");
|
|
|
|
} else {
|
|
|
|
aName.AssignLiteral("???");
|
|
|
|
}
|
2013-04-26 04:53:26 +04:00
|
|
|
}
|
|
|
|
|
2017-02-17 05:44:16 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvInitCrashReporter(Shmem&& aShmem, const NativeThreadId& aThreadId)
|
2010-11-24 17:15:03 +03:00
|
|
|
{
|
2017-02-17 05:44:16 +03:00
|
|
|
mCrashReporter = MakeUnique<CrashReporterHost>(
|
|
|
|
GeckoProcessType_Content,
|
|
|
|
aShmem,
|
|
|
|
aThreadId);
|
2017-10-10 13:43:09 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-11-24 17:15:03 +03:00
|
|
|
}
|
|
|
|
|
2013-01-27 01:14:01 +04:00
|
|
|
hal_sandbox::PHalParent*
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::AllocPHalParent()
|
2011-10-06 02:15:45 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return hal_sandbox::CreateHalParent();
|
2011-10-06 02:15:45 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::DeallocPHalParent(hal_sandbox::PHalParent* aHal)
|
2011-10-06 02:15:45 +04:00
|
|
|
{
|
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::PHeapSnapshotTempFileHelperParent*
|
|
|
|
ContentParent::AllocPHeapSnapshotTempFileHelperParent()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return devtools::HeapSnapshotTempFileHelperParent::Create();
|
2015-09-22 22:09:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPHeapSnapshotTempFileHelperParent(
|
2016-01-05 12:59:30 +03:00
|
|
|
devtools::PHeapSnapshotTempFileHelperParent* aHeapSnapshotHelper)
|
2015-09-22 22:09:42 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
delete aHeapSnapshotHelper;
|
|
|
|
return true;
|
2015-09-22 22:09:42 +03:00
|
|
|
}
|
|
|
|
|
2017-01-27 03:35:54 +03:00
|
|
|
bool
|
|
|
|
ContentParent::SendRequestMemoryReport(const uint32_t& aGeneration,
|
|
|
|
const bool& aAnonymize,
|
|
|
|
const bool& aMinimizeMemoryUsage,
|
|
|
|
const MaybeFileDesc& aDMDFile)
|
|
|
|
{
|
|
|
|
// This automatically cancels the previous request.
|
|
|
|
mMemoryReportRequest = MakeUnique<MemoryReportRequestHost>(aGeneration);
|
|
|
|
Unused << PContentParent::SendRequestMemoryReport(
|
|
|
|
aGeneration,
|
|
|
|
aAnonymize,
|
|
|
|
aMinimizeMemoryUsage,
|
|
|
|
aDMDFile);
|
|
|
|
return IPC_OK();
|
2011-02-16 21:43:23 +03:00
|
|
|
}
|
|
|
|
|
2017-01-27 03:35:54 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvAddMemoryReport(const MemoryReport& aReport)
|
2011-02-16 21:43:23 +03:00
|
|
|
{
|
2017-01-27 03:35:54 +03:00
|
|
|
if (mMemoryReportRequest) {
|
|
|
|
mMemoryReportRequest->RecvReport(aReport);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvFinishMemoryReport(const uint32_t& aGeneration)
|
|
|
|
{
|
|
|
|
if (mMemoryReportRequest) {
|
|
|
|
mMemoryReportRequest->Finish(aGeneration);
|
|
|
|
mMemoryReportRequest = nullptr;
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
2011-02-16 21:43:23 +03:00
|
|
|
}
|
|
|
|
|
2018-03-20 22:07:41 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2018-07-05 17:32:03 +03:00
|
|
|
ContentParent::RecvAddPerformanceMetrics(const nsID& aID,
|
|
|
|
nsTArray<PerformanceInfo>&& aMetrics)
|
2018-03-20 22:07:41 +03:00
|
|
|
{
|
2018-06-19 17:14:06 +03:00
|
|
|
if (!mozilla::StaticPrefs::dom_performance_enable_scheduler_timing()) {
|
2018-04-24 23:03:06 +03:00
|
|
|
// The pref is off, we should not get a performance metrics from the content
|
|
|
|
// child
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2018-07-05 17:32:03 +03:00
|
|
|
nsresult rv = PerformanceMetricsCollector::DataReceived(aID, aMetrics);
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(rv));
|
2018-03-20 22:07:41 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2014-05-13 21:13:00 +04:00
|
|
|
PCycleCollectWithLogsParent*
|
|
|
|
ContentParent::AllocPCycleCollectWithLogsParent(const bool& aDumpAllTraces,
|
|
|
|
const FileDescriptor& aGCLog,
|
|
|
|
const FileDescriptor& aCCLog)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_CRASH("Don't call this; use ContentParent::CycleCollectWithLogs");
|
2014-05-13 21:13:00 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPCycleCollectWithLogsParent(PCycleCollectWithLogsParent* aActor)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
delete aActor;
|
|
|
|
return true;
|
2014-05-13 21:13:00 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::CycleCollectWithLogs(bool aDumpAllTraces,
|
|
|
|
nsICycleCollectorLogSink* aSink,
|
|
|
|
nsIDumpGCAndCCLogsCallback* aCallback)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return CycleCollectWithLogsParent::AllocAndSendConstructor(this,
|
|
|
|
aDumpAllTraces,
|
|
|
|
aSink,
|
|
|
|
aCallback);
|
2014-05-13 21:13:00 +04:00
|
|
|
}
|
|
|
|
|
2009-09-10 02:59:06 +04:00
|
|
|
PTestShellParent*
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::AllocPTestShellParent()
|
2009-08-12 22:31:48 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return new TestShellParent();
|
2009-08-12 22:31:48 +04:00
|
|
|
}
|
|
|
|
|
2009-09-18 03:09:20 +04:00
|
|
|
bool
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::DeallocPTestShellParent(PTestShellParent* shell)
|
2009-08-12 22:31:48 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
delete shell;
|
|
|
|
return true;
|
2017-05-03 03:17:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
PScriptCacheParent*
|
|
|
|
ContentParent::AllocPScriptCacheParent(const FileDescOrError& cacheFile, const bool& wantCacheData)
|
|
|
|
{
|
|
|
|
return new loader::ScriptCacheParent(wantCacheData);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPScriptCacheParent(PScriptCacheParent* cache)
|
|
|
|
{
|
|
|
|
delete static_cast<loader::ScriptCacheParent*>(cache);
|
|
|
|
return true;
|
2009-08-12 22:31:48 +04:00
|
|
|
}
|
2013-07-08 19:48:39 +04:00
|
|
|
|
|
|
|
PNeckoParent*
|
|
|
|
ContentParent::AllocPNeckoParent()
|
2009-08-18 23:05:15 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return new NeckoParent();
|
2009-08-18 23:05:15 +04:00
|
|
|
}
|
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
bool
|
|
|
|
ContentParent::DeallocPNeckoParent(PNeckoParent* necko)
|
2009-08-18 23:05:15 +04:00
|
|
|
{
|
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
|
|
|
PPrintingParent*
|
|
|
|
ContentParent::AllocPPrintingParent()
|
|
|
|
{
|
2014-11-22 14:15:00 +03:00
|
|
|
#ifdef NS_PRINTING
|
2018-04-19 17:28:20 +03:00
|
|
|
if (mPrintingParent) {
|
|
|
|
// Only one PrintingParent should be created per process.
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-05-16 12:40:54 +03:00
|
|
|
|
|
|
|
// Create the printing singleton for this process.
|
|
|
|
mPrintingParent = new PrintingParent();
|
2018-04-10 17:36:26 +03:00
|
|
|
|
|
|
|
// Take another reference for IPDL code.
|
|
|
|
mPrintingParent.get()->AddRef();
|
|
|
|
|
2016-05-16 12:40:54 +03:00
|
|
|
return mPrintingParent.get();
|
2014-11-22 14:15:00 +03:00
|
|
|
#else
|
2016-05-16 12:40:54 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("Should never be created if no printing.");
|
2016-01-05 12:59:30 +03:00
|
|
|
return nullptr;
|
2014-11-22 14:15:00 +03:00
|
|
|
#endif
|
2014-10-28 18:59:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPPrintingParent(PPrintingParent* printing)
|
|
|
|
{
|
2016-05-16 12:40:54 +03:00
|
|
|
#ifdef NS_PRINTING
|
2018-04-10 17:36:26 +03:00
|
|
|
MOZ_RELEASE_ASSERT(mPrintingParent == printing,
|
|
|
|
"Only one PrintingParent should have been created per process.");
|
|
|
|
|
|
|
|
// Release reference taken for IPDL code.
|
|
|
|
static_cast<PrintingParent*>(printing)->Release();
|
2016-05-16 12:40:54 +03:00
|
|
|
|
|
|
|
mPrintingParent = nullptr;
|
|
|
|
#else
|
|
|
|
MOZ_ASSERT_UNREACHABLE("Should never have been created if no printing.");
|
|
|
|
#endif
|
2016-01-05 12:59:30 +03:00
|
|
|
return true;
|
2014-10-28 18:59:08 +03:00
|
|
|
}
|
|
|
|
|
2016-05-16 12:40:54 +03:00
|
|
|
#ifdef NS_PRINTING
|
|
|
|
already_AddRefed<embedding::PrintingParent>
|
|
|
|
ContentParent::GetPrintingParent()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mPrintingParent);
|
|
|
|
|
|
|
|
RefPtr<embedding::PrintingParent> printingParent = mPrintingParent;
|
|
|
|
return printingParent.forget();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-09-08 03:28:27 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvInitStreamFilter(const uint64_t& aChannelId,
|
|
|
|
const nsString& aAddonId,
|
|
|
|
InitStreamFilterResolver&& aResolver)
|
|
|
|
{
|
|
|
|
Endpoint<PStreamFilterChild> endpoint;
|
|
|
|
Unused << extensions::StreamFilterParent::Create(this, aChannelId, aAddonId, &endpoint);
|
|
|
|
|
2018-05-30 22:15:35 +03:00
|
|
|
aResolver(std::move(endpoint));
|
2017-09-08 03:28:27 +03:00
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-03-14 14:28:58 +03:00
|
|
|
PChildToParentStreamParent*
|
|
|
|
ContentParent::AllocPChildToParentStreamParent()
|
2016-05-15 20:32:09 +03:00
|
|
|
{
|
2017-03-14 14:28:58 +03:00
|
|
|
return nsIContentParent::AllocPChildToParentStreamParent();
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2017-03-14 14:28:58 +03:00
|
|
|
ContentParent::DeallocPChildToParentStreamParent(PChildToParentStreamParent* aActor)
|
2016-05-15 20:32:09 +03:00
|
|
|
{
|
2017-03-14 14:28:58 +03:00
|
|
|
return nsIContentParent::DeallocPChildToParentStreamParent(aActor);
|
2016-05-15 20:32:09 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
PParentToChildStreamParent*
|
|
|
|
ContentParent::SendPParentToChildStreamConstructor(PParentToChildStreamParent* aActor)
|
|
|
|
{
|
|
|
|
return PContentParent::SendPParentToChildStreamConstructor(aActor);
|
|
|
|
}
|
|
|
|
|
|
|
|
PParentToChildStreamParent*
|
|
|
|
ContentParent::AllocPParentToChildStreamParent()
|
|
|
|
{
|
|
|
|
return nsIContentParent::AllocPParentToChildStreamParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPParentToChildStreamParent(PParentToChildStreamParent* aActor)
|
|
|
|
{
|
|
|
|
return nsIContentParent::DeallocPParentToChildStreamParent(aActor);
|
|
|
|
}
|
|
|
|
|
2015-04-22 22:55:23 +03:00
|
|
|
PPSMContentDownloaderParent*
|
|
|
|
ContentParent::AllocPPSMContentDownloaderParent(const uint32_t& aCertType)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<PSMContentDownloaderParent> downloader =
|
|
|
|
new PSMContentDownloaderParent(aCertType);
|
|
|
|
return downloader.forget().take();
|
2015-04-22 22:55:23 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aListener)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
auto* listener = static_cast<PSMContentDownloaderParent*>(aListener);
|
|
|
|
RefPtr<PSMContentDownloaderParent> downloader = dont_AddRef(listener);
|
|
|
|
return true;
|
2015-04-22 22:55:23 +03:00
|
|
|
}
|
|
|
|
|
2010-09-16 02:55:08 +04:00
|
|
|
PExternalHelperAppParent*
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::AllocPExternalHelperAppParent(const OptionalURIParams& uri,
|
|
|
|
const nsCString& aMimeContentType,
|
|
|
|
const nsCString& aContentDisposition,
|
2014-02-14 02:43:58 +04:00
|
|
|
const uint32_t& aContentDispositionHint,
|
|
|
|
const nsString& aContentDispositionFilename,
|
2013-07-08 19:48:39 +04:00
|
|
|
const bool& aForceSave,
|
|
|
|
const int64_t& aContentLength,
|
2017-01-11 04:49:16 +03:00
|
|
|
const bool& aWasFileChannel,
|
2013-09-12 23:24:10 +04:00
|
|
|
const OptionalURIParams& aReferrer,
|
|
|
|
PBrowserParent* aBrowser)
|
2010-09-16 02:55:08 +04:00
|
|
|
{
|
2018-06-18 10:23:57 +03:00
|
|
|
ExternalHelperAppParent* parent =
|
|
|
|
new ExternalHelperAppParent(uri,
|
|
|
|
aContentLength,
|
|
|
|
aWasFileChannel,
|
|
|
|
aContentDisposition,
|
|
|
|
aContentDispositionHint,
|
|
|
|
aContentDispositionFilename);
|
2016-01-05 12:59:30 +03:00
|
|
|
parent->AddRef();
|
|
|
|
parent->Init(this,
|
|
|
|
aMimeContentType,
|
|
|
|
aForceSave,
|
|
|
|
aReferrer,
|
|
|
|
aBrowser);
|
|
|
|
return parent;
|
2010-09-16 02:55:08 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::DeallocPExternalHelperAppParent(PExternalHelperAppParent* aService)
|
2010-09-16 02:55:08 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
ExternalHelperAppParent *parent = static_cast<ExternalHelperAppParent *>(aService);
|
|
|
|
parent->Release();
|
|
|
|
return true;
|
2010-09-16 02:55:08 +04:00
|
|
|
}
|
|
|
|
|
2015-08-26 02:42:21 +03:00
|
|
|
PHandlerServiceParent*
|
|
|
|
ContentParent::AllocPHandlerServiceParent()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
HandlerServiceParent* actor = new HandlerServiceParent();
|
|
|
|
actor->AddRef();
|
|
|
|
return actor;
|
2015-08-26 02:42:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPHandlerServiceParent(PHandlerServiceParent* aHandlerServiceParent)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
static_cast<HandlerServiceParent*>(aHandlerServiceParent)->Release();
|
|
|
|
return true;
|
2015-08-26 02:42:21 +03:00
|
|
|
}
|
|
|
|
|
2015-06-18 18:46:36 +03:00
|
|
|
media::PMediaParent*
|
|
|
|
ContentParent::AllocPMediaParent()
|
|
|
|
{
|
|
|
|
return media::AllocPMediaParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPMediaParent(media::PMediaParent *aActor)
|
|
|
|
{
|
|
|
|
return media::DeallocPMediaParent(aActor);
|
|
|
|
}
|
|
|
|
|
2015-03-26 06:16:21 +03:00
|
|
|
PPresentationParent*
|
|
|
|
ContentParent::AllocPPresentationParent()
|
|
|
|
{
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<PresentationParent> actor = new PresentationParent();
|
2015-03-26 06:16:21 +03:00
|
|
|
return actor.forget().take();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPPresentationParent(PPresentationParent* aActor)
|
|
|
|
{
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<PresentationParent> actor =
|
2016-01-05 12:59:30 +03:00
|
|
|
dont_AddRef(static_cast<PresentationParent*>(aActor));
|
2015-03-26 06:16:21 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-03-26 06:16:21 +03:00
|
|
|
ContentParent::RecvPPresentationConstructor(PPresentationParent* aActor)
|
|
|
|
{
|
2016-11-15 06:26:00 +03:00
|
|
|
if (!static_cast<PresentationParent*>(aActor)->Init(mChildID)) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
2015-03-26 06:16:21 +03:00
|
|
|
}
|
|
|
|
|
2013-04-04 02:13:17 +04:00
|
|
|
PSpeechSynthesisParent*
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::AllocPSpeechSynthesisParent()
|
2013-04-04 02:13:17 +04:00
|
|
|
{
|
|
|
|
#ifdef MOZ_WEBSPEECH
|
2016-01-05 12:59:30 +03:00
|
|
|
return new mozilla::dom::SpeechSynthesisParent();
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2013-07-08 19:48:39 +04:00
|
|
|
ContentParent::DeallocPSpeechSynthesisParent(PSpeechSynthesisParent* 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
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2013-04-04 02:13:17 +04:00
|
|
|
ContentParent::RecvPSpeechSynthesisConstructor(PSpeechSynthesisParent* aActor)
|
|
|
|
{
|
|
|
|
#ifdef MOZ_WEBSPEECH
|
2017-02-23 18:18:21 +03:00
|
|
|
if (!static_cast<SpeechSynthesisParent*>(aActor)->SendInit()) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-04-04 02:13:17 +04:00
|
|
|
#else
|
2016-11-21 09:04:20 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2013-04-04 02:13:17 +04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2012-08-23 23:33:46 +04:00
|
|
|
ContentParent::RecvStartVisitedQuery(const URIParams& aURI)
|
2010-07-02 19:50:41 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIURI> newURI = DeserializeURI(aURI);
|
|
|
|
if (!newURI) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
nsCOMPtr<IHistory> history = services::GetHistoryService();
|
|
|
|
if (history) {
|
|
|
|
history->RegisterVisitedCallback(newURI, nullptr);
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-07-02 19:50:41 +04:00
|
|
|
}
|
|
|
|
|
2010-07-02 19:50:24 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2012-08-23 23:33:46 +04:00
|
|
|
ContentParent::RecvVisitURI(const URIParams& uri,
|
|
|
|
const OptionalURIParams& referrer,
|
|
|
|
const uint32_t& flags)
|
2010-07-02 19:50:24 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
|
|
|
|
if (!ourURI) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
nsCOMPtr<nsIURI> ourReferrer = DeserializeURI(referrer);
|
|
|
|
nsCOMPtr<IHistory> history = services::GetHistoryService();
|
|
|
|
if (history) {
|
|
|
|
history->VisitURI(ourURI, ourReferrer, flags);
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-07-02 19:50:24 +04:00
|
|
|
}
|
|
|
|
|
2010-07-02 19:53:42 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2012-08-23 23:33:46 +04:00
|
|
|
ContentParent::RecvSetURITitle(const URIParams& uri,
|
|
|
|
const nsString& title)
|
2010-07-02 19:53:42 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
|
|
|
|
if (!ourURI) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
nsCOMPtr<IHistory> history = services::GetHistoryService();
|
|
|
|
if (history) {
|
|
|
|
history->SetURITitle(ourURI, title);
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-07-02 19:53:42 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-02-14 05:29:24 +03:00
|
|
|
ContentParent::RecvIsSecureURI(const uint32_t& aType,
|
|
|
|
const URIParams& aURI,
|
|
|
|
const uint32_t& aFlags,
|
|
|
|
const OriginAttributes& aOriginAttributes,
|
|
|
|
bool* aIsSecureURI)
|
2014-07-22 16:17:45 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsISiteSecurityService> sss(do_GetService(NS_SSSERVICE_CONTRACTID));
|
|
|
|
if (!sss) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2017-02-14 05:29:24 +03:00
|
|
|
nsCOMPtr<nsIURI> ourURI = DeserializeURI(aURI);
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!ourURI) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2017-02-14 05:29:24 +03:00
|
|
|
nsresult rv = sss->IsSecureURI(aType, ourURI, aFlags, aOriginAttributes, nullptr,
|
2017-05-24 01:31:37 +03:00
|
|
|
nullptr, aIsSecureURI);
|
2016-11-15 06:26:00 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
2014-07-22 16:17:45 +04:00
|
|
|
}
|
2014-05-21 09:49:36 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2018-01-10 19:07:00 +03:00
|
|
|
ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive,
|
2017-02-14 05:29:24 +03:00
|
|
|
const OriginAttributes& aOriginAttributes)
|
2015-09-09 22:14:27 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIURI> ourURI = DeserializeURI(aURI);
|
|
|
|
if (!ourURI) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2018-01-10 19:07:00 +03:00
|
|
|
nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive, aOriginAttributes);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-09-09 22:14:27 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-12-04 02:04:28 +03:00
|
|
|
ContentParent::RecvLoadURIExternal(const URIParams& uri,
|
|
|
|
PBrowserParent* windowContext)
|
2010-08-10 21:14:45 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIExternalProtocolService> extProtService(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
|
|
|
|
if (!extProtService) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
|
|
|
|
if (!ourURI) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<RemoteWindowContext> context =
|
|
|
|
new RemoteWindowContext(static_cast<TabParent*>(windowContext));
|
|
|
|
extProtService->LoadURI(ourURI, context);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-08-10 21:14:45 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-07-01 06:16:00 +03:00
|
|
|
ContentParent::RecvExtProtocolChannelConnectParent(const uint32_t& registrarId)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// First get the real channel created before redirect on the parent.
|
|
|
|
nsCOMPtr<nsIChannel> channel;
|
|
|
|
rv = NS_LinkRedirectChannels(registrarId, nullptr, getter_AddRefs(channel));
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2016-07-01 06:16:00 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIParentChannel> parent = do_QueryInterface(channel, &rv);
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2016-07-01 06:16:00 +03:00
|
|
|
|
|
|
|
// The channel itself is its own (faked) parent, link it.
|
|
|
|
rv = NS_LinkRedirectChannels(registrarId, parent, getter_AddRefs(channel));
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
2016-07-01 06:16:00 +03:00
|
|
|
|
|
|
|
// Signal the parent channel that it's a redirect-to parent. This will
|
|
|
|
// make AsyncOpen on it do nothing (what we want).
|
|
|
|
// Yes, this is a bit of a hack, but I don't think it's necessary to invent
|
|
|
|
// a new interface just to set this flag on the channel.
|
|
|
|
parent->SetParentListener(nullptr);
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-01 06:16:00 +03:00
|
|
|
}
|
|
|
|
|
2015-10-23 00:20:51 +03:00
|
|
|
bool
|
|
|
|
ContentParent::HasNotificationPermission(const IPC::Principal& aPrincipal)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return true;
|
2015-10-23 00:20:51 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
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
|
|
|
ContentParent::RecvShowAlert(nsIAlertNotification* aAlert)
|
2010-09-15 20:44:57 +04:00
|
|
|
{
|
2018-04-18 21:53:43 +03:00
|
|
|
if (!aAlert) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
2016-01-06 03:34:06 +03:00
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
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
|
|
|
nsresult rv = aAlert->GetPrincipal(getter_AddRefs(principal));
|
2016-01-06 03:34:06 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv)) ||
|
|
|
|
!HasNotificationPermission(IPC::Principal(principal))) {
|
2015-12-31 22:04:24 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-06 03:34:06 +03:00
|
|
|
}
|
2013-11-12 03:56:21 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
|
|
|
|
if (sysAlerts) {
|
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
|
|
|
sysAlerts->ShowAlert(aAlert, this);
|
2016-01-06 03:34:06 +03:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-03-18 17:24:53 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2013-11-12 03:56:21 +04:00
|
|
|
ContentParent::RecvCloseAlert(const nsString& aName,
|
|
|
|
const IPC::Principal& aPrincipal)
|
2013-03-18 17:24:53 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!HasNotificationPermission(aPrincipal)) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2013-11-12 03:56:21 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
|
|
|
|
if (sysAlerts) {
|
|
|
|
sysAlerts->CloseAlert(aName, aPrincipal);
|
|
|
|
}
|
2010-09-15 20:44:57 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-09-15 20:44:57 +04:00
|
|
|
}
|
2010-08-31 22:58:35 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-10-23 00:10:14 +03:00
|
|
|
ContentParent::RecvDisableNotifications(const IPC::Principal& aPrincipal)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (HasNotificationPermission(aPrincipal)) {
|
|
|
|
Unused << Notification::RemovePermission(aPrincipal);
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-10-23 00:20:51 +03:00
|
|
|
}
|
2015-10-23 00:10:14 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-10-23 00:20:51 +03:00
|
|
|
ContentParent::RecvOpenNotificationSettings(const IPC::Principal& aPrincipal)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (HasNotificationPermission(aPrincipal)) {
|
|
|
|
Unused << Notification::OpenSettings(aPrincipal);
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-10-23 00:10:14 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2012-08-02 10:02:29 +04:00
|
|
|
ContentParent::RecvSyncMessage(const nsString& aMsg,
|
|
|
|
const ClonedMessageData& aData,
|
2015-01-16 22:58:52 +03:00
|
|
|
InfallibleTArray<CpowEntry>&& aCpows,
|
2013-11-06 21:21:15 +04:00
|
|
|
const IPC::Principal& aPrincipal,
|
2015-09-10 23:50:58 +03:00
|
|
|
nsTArray<StructuredCloneData>* aRetvals)
|
2010-08-31 22:58:35 +04:00
|
|
|
{
|
2018-05-30 22:15:35 +03:00
|
|
|
return nsIContentParent::RecvSyncMessage(aMsg, aData, std::move(aCpows),
|
2016-01-05 12:59:30 +03:00
|
|
|
aPrincipal, aRetvals);
|
2010-08-31 22:58:35 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2014-10-08 08:32:45 +04:00
|
|
|
ContentParent::RecvRpcMessage(const nsString& aMsg,
|
|
|
|
const ClonedMessageData& aData,
|
2015-01-16 22:58:52 +03:00
|
|
|
InfallibleTArray<CpowEntry>&& aCpows,
|
2014-10-08 08:32:45 +04:00
|
|
|
const IPC::Principal& aPrincipal,
|
2015-09-10 23:50:58 +03:00
|
|
|
nsTArray<StructuredCloneData>* aRetvals)
|
2014-10-08 08:32:45 +04:00
|
|
|
{
|
2018-05-30 22:15:35 +03:00
|
|
|
return nsIContentParent::RecvRpcMessage(aMsg, aData, std::move(aCpows), aPrincipal,
|
2016-01-05 12:59:30 +03:00
|
|
|
aRetvals);
|
2013-10-01 20:15:06 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2012-08-02 10:02:29 +04:00
|
|
|
ContentParent::RecvAsyncMessage(const nsString& aMsg,
|
2015-01-16 22:58:52 +03:00
|
|
|
InfallibleTArray<CpowEntry>&& aCpows,
|
2016-04-09 16:50:59 +03:00
|
|
|
const IPC::Principal& aPrincipal,
|
|
|
|
const ClonedMessageData& aData)
|
2010-08-31 22:58:35 +04:00
|
|
|
{
|
2018-05-30 22:15:35 +03:00
|
|
|
return nsIContentParent::RecvAsyncMessage(aMsg, std::move(aCpows), aPrincipal,
|
2016-04-09 16:50:59 +03:00
|
|
|
aData);
|
2010-08-31 22:58:35 +04:00
|
|
|
}
|
2010-09-21 08:16:37 +04:00
|
|
|
|
2013-02-26 21:27:31 +04:00
|
|
|
static int32_t
|
2016-01-05 12:59:30 +03:00
|
|
|
AddGeolocationListener(nsIDOMGeoPositionCallback* watcher,
|
|
|
|
nsIDOMGeoPositionErrorCallback* errorCallBack,
|
|
|
|
bool highAccuracy)
|
2013-02-26 21:27:31 +04:00
|
|
|
{
|
2018-06-04 19:41:04 +03:00
|
|
|
RefPtr<Geolocation> geo = Geolocation::NonWindowSingleton();
|
2013-02-26 21:27:31 +04:00
|
|
|
|
2016-10-24 09:40:18 +03:00
|
|
|
UniquePtr<PositionOptions> options = MakeUnique<PositionOptions>();
|
2016-01-05 12:59:30 +03:00
|
|
|
options->mTimeout = 0;
|
|
|
|
options->mMaximumAge = 0;
|
|
|
|
options->mEnableHighAccuracy = highAccuracy;
|
2018-06-04 19:41:09 +03:00
|
|
|
return geo->WatchPosition(watcher, errorCallBack, std::move(options));
|
2013-02-26 21:27:31 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2013-02-26 21:27:31 +04:00
|
|
|
ContentParent::RecvAddGeolocationListener(const IPC::Principal& aPrincipal,
|
|
|
|
const bool& aHighAccuracy)
|
2010-09-21 08:16:37 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// To ensure no geolocation updates are skipped, we always force the
|
|
|
|
// creation of a new listener.
|
|
|
|
RecvRemoveGeolocationListener();
|
|
|
|
mGeolocationWatchID = AddGeolocationListener(this, this, aHighAccuracy);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-09-21 08:16:37 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2010-11-05 20:43:13 +03:00
|
|
|
ContentParent::RecvRemoveGeolocationListener()
|
2010-09-21 08:16:37 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (mGeolocationWatchID != -1) {
|
2018-06-04 19:41:04 +03:00
|
|
|
RefPtr<Geolocation> geo = Geolocation::NonWindowSingleton();
|
2016-01-05 12:59:30 +03:00
|
|
|
geo->ClearWatch(mGeolocationWatchID);
|
|
|
|
mGeolocationWatchID = -1;
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-09-21 08:16:37 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2012-12-31 20:36:46 +04:00
|
|
|
ContentParent::RecvSetGeolocationHigherAccuracy(const bool& aEnable)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// This should never be called without a listener already present,
|
|
|
|
// so this check allows us to forgo securing privileges.
|
|
|
|
if (mGeolocationWatchID != -1) {
|
|
|
|
RecvRemoveGeolocationListener();
|
|
|
|
mGeolocationWatchID = AddGeolocationListener(this, this, aEnable);
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2012-12-31 20:36:46 +04:00
|
|
|
}
|
|
|
|
|
2010-09-21 08:16:37 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
ContentParent::HandleEvent(nsIDOMGeoPosition* postion)
|
|
|
|
{
|
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
|
|
|
Unused << SendGeolocationUpdate(postion);
|
2016-01-05 12:59:30 +03:00
|
|
|
return NS_OK;
|
2010-09-21 08:16:37 +04:00
|
|
|
}
|
|
|
|
|
2014-10-23 22:31:00 +04:00
|
|
|
NS_IMETHODIMP
|
2018-06-02 05:35:44 +03:00
|
|
|
ContentParent::HandleEvent(PositionError* positionError)
|
2014-10-23 22:31:00 +04:00
|
|
|
{
|
2018-06-02 05:35:44 +03:00
|
|
|
Unused << SendGeolocationError(positionError->Code());
|
2016-01-05 12:59:30 +03:00
|
|
|
return NS_OK;
|
2014-10-23 22:31:00 +04:00
|
|
|
}
|
|
|
|
|
2012-11-09 21:52:09 +04:00
|
|
|
nsConsoleService *
|
|
|
|
ContentParent::GetConsoleService()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (mConsoleService) {
|
2012-11-09 21:52:09 +04:00
|
|
|
return mConsoleService.get();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// XXXkhuey everything about this is terrible.
|
|
|
|
// Get the ConsoleService by CID rather than ContractID, so that we
|
|
|
|
// can cast the returned pointer to an nsConsoleService (rather than
|
|
|
|
// just an nsIConsoleService). This allows us to call the non-idl function
|
|
|
|
// nsConsoleService::LogMessageWithMode.
|
|
|
|
NS_DEFINE_CID(consoleServiceCID, NS_CONSOLESERVICE_CID);
|
|
|
|
nsCOMPtr<nsIConsoleService> consoleService(do_GetService(consoleServiceCID));
|
|
|
|
mConsoleService = static_cast<nsConsoleService*>(consoleService.get());
|
|
|
|
return mConsoleService.get();
|
2012-11-09 21:52:09 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2010-09-24 05:39:32 +04:00
|
|
|
ContentParent::RecvConsoleMessage(const nsString& aMessage)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<nsConsoleService> consoleService = GetConsoleService();
|
|
|
|
if (!consoleService) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<nsConsoleMessage> msg(new nsConsoleMessage(aMessage.get()));
|
|
|
|
consoleService->LogMessageWithMode(msg, nsConsoleService::SuppressLog);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-09-24 05:39:32 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2010-09-24 05:39:32 +04:00
|
|
|
ContentParent::RecvScriptError(const nsString& aMessage,
|
2016-01-05 12:59:30 +03:00
|
|
|
const nsString& aSourceName,
|
|
|
|
const nsString& aSourceLine,
|
|
|
|
const uint32_t& aLineNumber,
|
|
|
|
const uint32_t& aColNumber,
|
|
|
|
const uint32_t& aFlags,
|
2018-03-13 08:40:38 +03:00
|
|
|
const nsCString& aCategory,
|
|
|
|
const bool& aFromPrivateWindow)
|
2018-02-24 04:21:49 +03:00
|
|
|
{
|
|
|
|
return RecvScriptErrorInternal(aMessage, aSourceName, aSourceLine,
|
|
|
|
aLineNumber, aColNumber, aFlags,
|
2018-03-13 08:40:38 +03:00
|
|
|
aCategory, aFromPrivateWindow);
|
2018-02-24 04:21:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvScriptErrorWithStack(const nsString& aMessage,
|
|
|
|
const nsString& aSourceName,
|
|
|
|
const nsString& aSourceLine,
|
|
|
|
const uint32_t& aLineNumber,
|
|
|
|
const uint32_t& aColNumber,
|
|
|
|
const uint32_t& aFlags,
|
|
|
|
const nsCString& aCategory,
|
2018-03-13 08:40:38 +03:00
|
|
|
const bool& aFromPrivateWindow,
|
2018-02-24 04:21:49 +03:00
|
|
|
const ClonedMessageData& aFrame)
|
|
|
|
{
|
|
|
|
return RecvScriptErrorInternal(aMessage, aSourceName, aSourceLine,
|
|
|
|
aLineNumber, aColNumber, aFlags,
|
2018-03-13 08:40:38 +03:00
|
|
|
aCategory, aFromPrivateWindow, &aFrame);
|
2018-02-24 04:21:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvScriptErrorInternal(const nsString& aMessage,
|
|
|
|
const nsString& aSourceName,
|
|
|
|
const nsString& aSourceLine,
|
|
|
|
const uint32_t& aLineNumber,
|
|
|
|
const uint32_t& aColNumber,
|
|
|
|
const uint32_t& aFlags,
|
|
|
|
const nsCString& aCategory,
|
2018-03-13 08:40:38 +03:00
|
|
|
const bool& aFromPrivateWindow,
|
2018-02-24 04:21:49 +03:00
|
|
|
const ClonedMessageData* aStack)
|
2016-01-05 12:59:30 +03:00
|
|
|
{
|
|
|
|
RefPtr<nsConsoleService> consoleService = GetConsoleService();
|
|
|
|
if (!consoleService) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2010-09-24 05:39:32 +04:00
|
|
|
|
2018-02-24 04:21:49 +03:00
|
|
|
nsCOMPtr<nsIScriptError> msg;
|
|
|
|
|
|
|
|
if (aStack) {
|
|
|
|
StructuredCloneData data;
|
|
|
|
UnpackClonedMessageDataForParent(*aStack, data);
|
|
|
|
|
|
|
|
AutoJSAPI jsapi;
|
|
|
|
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
|
|
|
|
MOZ_CRASH();
|
|
|
|
}
|
|
|
|
JSContext* cx = jsapi.cx();
|
|
|
|
|
|
|
|
JS::RootedValue stack(cx);
|
|
|
|
ErrorResult rv;
|
|
|
|
data.Read(cx, &stack, rv);
|
|
|
|
if (rv.Failed() || !stack.isObject()) {
|
|
|
|
rv.SuppressException();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
JS::RootedObject stackObj(cx, &stack.toObject());
|
2018-07-21 15:34:37 +03:00
|
|
|
MOZ_ASSERT(JS::IsUnwrappedSavedFrame(stackObj));
|
|
|
|
|
|
|
|
JS::RootedObject stackGlobal(cx, JS::GetNonCCWObjectGlobal(stackObj));
|
|
|
|
msg = new nsScriptErrorWithStack(stackObj, stackGlobal);
|
2018-02-24 04:21:49 +03:00
|
|
|
} else {
|
|
|
|
msg = new nsScriptError();
|
|
|
|
}
|
|
|
|
|
2018-03-13 08:40:38 +03:00
|
|
|
nsresult rv = msg->Init(aMessage, aSourceName, aSourceLine,
|
|
|
|
aLineNumber, aColNumber, aFlags,
|
|
|
|
aCategory.get(), aFromPrivateWindow);
|
2016-01-05 12:59:30 +03:00
|
|
|
if (NS_FAILED(rv))
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
|
|
|
|
consoleService->LogMessageWithMode(msg, nsConsoleService::SuppressLog);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-09-24 05:39:32 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2012-04-20 04:13:20 +04:00
|
|
|
ContentParent::RecvPrivateDocShellsExist(const bool& aExist)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (!sPrivateContent)
|
|
|
|
sPrivateContent = new nsTArray<ContentParent*>();
|
|
|
|
if (aExist) {
|
|
|
|
sPrivateContent->AppendElement(this);
|
|
|
|
} else {
|
|
|
|
sPrivateContent->RemoveElement(this);
|
|
|
|
|
|
|
|
// Only fire the notification if we have private and non-private
|
|
|
|
// windows: if privatebrowsing.autostart is true, all windows are
|
|
|
|
// private.
|
|
|
|
if (!sPrivateContent->Length() &&
|
|
|
|
!Preferences::GetBool("browser.privatebrowsing.autostart")) {
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
obs->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
|
|
|
|
delete sPrivateContent;
|
|
|
|
sPrivateContent = nullptr;
|
2012-04-20 04:13:20 +04:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2012-04-20 04:13:20 +04:00
|
|
|
}
|
|
|
|
|
2015-02-20 04:13:02 +03:00
|
|
|
bool
|
|
|
|
ContentParent::DoLoadMessageManagerScript(const nsAString& aURL,
|
|
|
|
bool aRunInGlobalScope)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(!aRunInGlobalScope);
|
|
|
|
return SendLoadProcessScript(nsString(aURL));
|
2015-02-20 04:13:02 +03:00
|
|
|
}
|
|
|
|
|
2015-10-07 13:42:43 +03:00
|
|
|
nsresult
|
2013-07-11 02:05:39 +04:00
|
|
|
ContentParent::DoSendAsyncMessage(JSContext* aCx,
|
|
|
|
const nsAString& aMessage,
|
2015-09-10 23:50:58 +03:00
|
|
|
StructuredCloneData& aHelper,
|
2013-11-06 21:21:15 +04:00
|
|
|
JS::Handle<JSObject *> aCpows,
|
|
|
|
nsIPrincipal* aPrincipal)
|
2012-09-28 09:43:12 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
ClonedMessageData data;
|
|
|
|
if (!BuildClonedMessageDataForParent(this, aHelper, data)) {
|
|
|
|
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
|
|
|
}
|
|
|
|
InfallibleTArray<CpowEntry> cpows;
|
|
|
|
jsipc::CPOWManager* mgr = GetCPOWManager();
|
|
|
|
if (aCpows && (!mgr || !mgr->Wrap(aCx, aCpows, &cpows))) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
2016-04-09 16:50:59 +03:00
|
|
|
if (!SendAsyncMessage(nsString(aMessage), cpows, Principal(aPrincipal), data)) {
|
2016-01-05 12:59:30 +03:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
2012-09-28 09:43:12 +04:00
|
|
|
}
|
|
|
|
|
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
|
|
|
PIPCBlobInputStreamParent*
|
|
|
|
ContentParent::SendPIPCBlobInputStreamConstructor(PIPCBlobInputStreamParent* aActor,
|
|
|
|
const nsID& aID,
|
|
|
|
const uint64_t& aSize)
|
|
|
|
{
|
|
|
|
return PContentParent::SendPIPCBlobInputStreamConstructor(aActor, aID, aSize);
|
|
|
|
}
|
|
|
|
|
2014-06-11 09:44:13 +04:00
|
|
|
PBrowserParent*
|
|
|
|
ContentParent::SendPBrowserConstructor(PBrowserParent* aActor,
|
2014-10-29 21:11:00 +03:00
|
|
|
const TabId& aTabId,
|
2017-04-07 02:46:18 +03:00
|
|
|
const TabId& aSameTabGroupAs,
|
2014-06-11 09:44:13 +04:00
|
|
|
const IPCTabContext& aContext,
|
|
|
|
const uint32_t& aChromeFlags,
|
2014-10-24 04:28:00 +04:00
|
|
|
const ContentParentId& aCpId,
|
2014-06-11 09:44:13 +04:00
|
|
|
const bool& aIsForBrowser)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
return PContentParent::SendPBrowserConstructor(aActor,
|
|
|
|
aTabId,
|
2017-04-07 02:46:18 +03:00
|
|
|
aSameTabGroupAs,
|
2016-01-05 12:59:30 +03:00
|
|
|
aContext,
|
|
|
|
aChromeFlags,
|
|
|
|
aCpId,
|
|
|
|
aIsForBrowser);
|
2014-06-11 09:44:13 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2014-09-11 17:50:55 +04:00
|
|
|
ContentParent::RecvKeywordToURI(const nsCString& aKeyword,
|
|
|
|
nsString* aProviderName,
|
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
|
|
|
RefPtr<nsIInputStream>* aPostData,
|
2013-08-16 21:59:31 +04:00
|
|
|
OptionalURIParams* aURI)
|
|
|
|
{
|
2018-02-23 23:29:22 +03:00
|
|
|
*aPostData = nullptr;
|
2016-08-24 06:23:56 +03:00
|
|
|
*aURI = void_t();
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIURIFixup> fixup = do_GetService(NS_URIFIXUP_CONTRACTID);
|
|
|
|
if (!fixup) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2013-08-16 21:59:31 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIURIFixupInfo> info;
|
2014-09-11 17:50:55 +04:00
|
|
|
|
2018-02-23 23:29:22 +03:00
|
|
|
if (NS_FAILED(fixup->KeywordToURI(aKeyword, getter_AddRefs(*aPostData),
|
2016-01-05 12:59:30 +03:00
|
|
|
getter_AddRefs(info)))) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
info->GetKeywordProviderName(*aProviderName);
|
2013-08-16 21:59:31 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
info->GetPreferredURI(getter_AddRefs(uri));
|
|
|
|
SerializeURI(uri, *aURI);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-08-16 21:59:31 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2014-09-11 17:50:55 +04:00
|
|
|
ContentParent::RecvNotifyKeywordSearchLoading(const nsString &aProvider,
|
2016-01-05 12:59:30 +03:00
|
|
|
const nsString &aKeyword)
|
|
|
|
{
|
2014-09-11 17:50:55 +04:00
|
|
|
#ifdef MOZ_TOOLKIT_SEARCH
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIBrowserSearchService> searchSvc = do_GetService("@mozilla.org/browser/search-service;1");
|
|
|
|
if (searchSvc) {
|
|
|
|
nsCOMPtr<nsISearchEngine> searchEngine;
|
|
|
|
searchSvc->GetEngineByName(aProvider, getter_AddRefs(searchEngine));
|
|
|
|
if (searchEngine) {
|
|
|
|
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
|
|
|
|
if (obsSvc) {
|
|
|
|
// Note that "keyword-search" refers to a search via the url
|
|
|
|
// bar, not a bookmarks keyword search.
|
|
|
|
obsSvc->NotifyObservers(searchEngine, "keyword-search", aKeyword.get());
|
|
|
|
}
|
2014-09-11 17:50:55 +04:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-09-11 17:50:55 +04:00
|
|
|
#endif
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-09-11 17:50:55 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-04-29 11:57:24 +03:00
|
|
|
ContentParent::RecvCopyFavicon(const URIParams& aOldURI,
|
|
|
|
const URIParams& aNewURI,
|
2015-11-25 00:31:57 +03:00
|
|
|
const IPC::Principal& aLoadingPrincipal,
|
2015-04-29 11:57:24 +03:00
|
|
|
const bool& aInPrivateBrowsing)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIURI> oldURI = DeserializeURI(aOldURI);
|
|
|
|
if (!oldURI) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
nsCOMPtr<nsIURI> newURI = DeserializeURI(aNewURI);
|
|
|
|
if (!newURI) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsDocShell::CopyFavicon(oldURI, newURI, aLoadingPrincipal, aInPrivateBrowsing);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-04-29 11:57:24 +03:00
|
|
|
}
|
|
|
|
|
2013-08-27 08:56:57 +04:00
|
|
|
bool
|
|
|
|
ContentParent::ShouldContinueFromReplyTimeout()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<ProcessHangMonitor> monitor = ProcessHangMonitor::Get();
|
|
|
|
return !monitor || !monitor->ShouldTimeOutCPOWs();
|
2013-08-27 08:56:57 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2013-11-24 13:06:27 +04:00
|
|
|
ContentParent::RecvRecordingDeviceEvents(const nsString& aRecordingStatus,
|
|
|
|
const nsString& aPageURL,
|
|
|
|
const bool& aIsAudio,
|
|
|
|
const bool& aIsVideo)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
if (obs) {
|
|
|
|
// recording-device-ipc-events needs to gather more information from content process
|
|
|
|
RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
|
|
|
|
props->SetPropertyAsUint64(NS_LITERAL_STRING("childID"), ChildID());
|
|
|
|
props->SetPropertyAsBool(NS_LITERAL_STRING("isAudio"), aIsAudio);
|
|
|
|
props->SetPropertyAsBool(NS_LITERAL_STRING("isVideo"), aIsVideo);
|
2016-10-15 04:46:26 +03:00
|
|
|
props->SetPropertyAsAString(NS_LITERAL_STRING("requestURL"), aPageURL);
|
2016-01-05 12:59:30 +03:00
|
|
|
|
|
|
|
obs->NotifyObservers((nsIPropertyBag2*) props,
|
|
|
|
"recording-device-ipc-events",
|
|
|
|
aRecordingStatus.get());
|
|
|
|
} else {
|
|
|
|
NS_WARNING("Could not get the Observer service for ContentParent::RecvRecordingDeviceEvents.");
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-11-24 13:06:27 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentParent::RecvAddIdleObserver(const uint64_t& aObserver,
|
|
|
|
const uint32_t& aIdleTimeInS)
|
2013-12-13 20:28:46 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIIdleService> idleService =
|
|
|
|
do_GetService("@mozilla.org/widget/idleservice;1", &rv);
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this));
|
2013-12-13 20:28:46 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<ParentIdleListener> listener =
|
|
|
|
new ParentIdleListener(this, aObserver, aIdleTimeInS);
|
|
|
|
rv = idleService->AddIdleObserver(listener, aIdleTimeInS);
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this));
|
2016-01-05 12:59:30 +03:00
|
|
|
mIdleListeners.AppendElement(listener);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-12-13 20:28:46 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentParent::RecvRemoveIdleObserver(const uint64_t& aObserver,
|
|
|
|
const uint32_t& aIdleTimeInS)
|
2013-12-13 20:28:46 +04:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<ParentIdleListener> listener;
|
|
|
|
for (int32_t i = mIdleListeners.Length() - 1; i >= 0; --i) {
|
|
|
|
listener = static_cast<ParentIdleListener*>(mIdleListeners[i].get());
|
|
|
|
if (listener->mObserver == aObserver &&
|
|
|
|
listener->mTime == aIdleTimeInS) {
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIIdleService> idleService =
|
|
|
|
do_GetService("@mozilla.org/widget/idleservice;1", &rv);
|
2016-11-15 06:26:00 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this));
|
2016-01-05 12:59:30 +03:00
|
|
|
idleService->RemoveIdleObserver(listener, aIdleTimeInS);
|
|
|
|
mIdleListeners.RemoveElementAt(i);
|
|
|
|
break;
|
2014-05-28 07:04:23 +04:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2013-12-13 20:28:46 +04:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2014-02-05 20:37:26 +04:00
|
|
|
ContentParent::RecvBackUpXResources(const FileDescriptor& aXSocketFd)
|
|
|
|
{
|
|
|
|
#ifndef MOZ_X11
|
2016-12-03 00:46:53 +03:00
|
|
|
MOZ_CRASH("This message only makes sense on X11 platforms");
|
2014-02-05 20:37:26 +04:00
|
|
|
#else
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(0 > mChildXSocketFdDup.get(),
|
|
|
|
"Already backed up X resources??");
|
|
|
|
if (aXSocketFd.IsValid()) {
|
2016-05-27 11:12:51 +03:00
|
|
|
auto rawFD = aXSocketFd.ClonePlatformHandle();
|
|
|
|
mChildXSocketFdDup.reset(rawFD.release());
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-02-05 20:37:26 +04:00
|
|
|
#endif
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-02-05 20:37:26 +04:00
|
|
|
}
|
|
|
|
|
2017-03-14 02:06:04 +03:00
|
|
|
class AnonymousTemporaryFileRequestor final : public Runnable
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
AnonymousTemporaryFileRequestor(ContentParent* aCP, const uint64_t& aID)
|
2017-06-12 22:34:10 +03:00
|
|
|
: Runnable("dom::AnonymousTemporaryFileRequestor")
|
|
|
|
, mCP(aCP)
|
2017-03-14 02:06:04 +03:00
|
|
|
, mID(aID)
|
|
|
|
, mRv(NS_OK)
|
|
|
|
, mPRFD(nullptr)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHOD Run() override
|
|
|
|
{
|
|
|
|
if (NS_IsMainThread()) {
|
|
|
|
FileDescOrError result;
|
|
|
|
if (NS_WARN_IF(NS_FAILED(mRv))) {
|
|
|
|
// Returning false will kill the child process; instead
|
|
|
|
// propagate the error and let the child handle it.
|
|
|
|
result = mRv;
|
|
|
|
} else {
|
|
|
|
result = FileDescriptor(FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mPRFD)));
|
|
|
|
// The FileDescriptor object owns a duplicate of the file handle; we
|
|
|
|
// must close the original (and clean up the NSPR descriptor).
|
|
|
|
PR_Close(mPRFD);
|
|
|
|
}
|
|
|
|
Unused << mCP->SendProvideAnonymousTemporaryFile(mID, result);
|
|
|
|
// It's important to release this reference while wr're on the main thread!
|
|
|
|
mCP = nullptr;
|
|
|
|
} else {
|
|
|
|
mRv = NS_OpenAnonymousTemporaryFile(&mPRFD);
|
|
|
|
NS_DispatchToMainThread(this);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
RefPtr<ContentParent> mCP;
|
|
|
|
uint64_t mID;
|
|
|
|
nsresult mRv;
|
|
|
|
PRFileDesc* mPRFD;
|
|
|
|
};
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvRequestAnonymousTemporaryFile(const uint64_t& aID)
|
|
|
|
{
|
|
|
|
// Make sure to send a callback to the child if we bail out early.
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
RefPtr<ContentParent> self(this);
|
2018-05-03 09:09:58 +03:00
|
|
|
auto autoNotifyChildOnError = MakeScopeExit([&, self]() {
|
2017-03-14 02:06:04 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
FileDescOrError result(rv);
|
|
|
|
Unused << self->SendProvideAnonymousTemporaryFile(aID, result);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// We use a helper runnable to open the anonymous temporary file on the IO
|
|
|
|
// thread. The same runnable will call us back on the main thread when the
|
|
|
|
// file has been opened.
|
|
|
|
nsCOMPtr<nsIEventTarget> target
|
|
|
|
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
|
|
|
|
if (!target) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = target->Dispatch(new AnonymousTemporaryFileRequestor(this, aID),
|
|
|
|
NS_DISPATCH_NORMAL);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = NS_OK;
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-12-20 04:51:11 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvCreateAudioIPCConnection(CreateAudioIPCConnectionResolver&& aResolver)
|
|
|
|
{
|
|
|
|
FileDescriptor fd = CubebUtils::CreateAudioIPCConnection();
|
|
|
|
if (!fd.IsValid()) {
|
|
|
|
return IPC_FAIL(this, "CubebUtils::CreateAudioIPCConnection failed");
|
|
|
|
}
|
2018-05-30 22:15:35 +03:00
|
|
|
aResolver(std::move(fd));
|
2017-12-20 04:51:11 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2014-11-27 01:28:28 +03:00
|
|
|
static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2014-12-19 20:07:04 +03:00
|
|
|
ContentParent::RecvKeygenProcessValue(const nsString& oldValue,
|
|
|
|
const nsString& challenge,
|
|
|
|
const nsString& keytype,
|
|
|
|
const nsString& keyparams,
|
|
|
|
nsString* newValue)
|
2014-11-27 01:28:28 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIFormProcessor> formProcessor =
|
|
|
|
do_GetService(kFormProcessorCID);
|
|
|
|
if (!formProcessor) {
|
|
|
|
newValue->Truncate();
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
formProcessor->ProcessValueIPC(oldValue, challenge, keytype, keyparams,
|
|
|
|
*newValue);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-11-27 01:28:28 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2014-12-19 20:07:04 +03:00
|
|
|
ContentParent::RecvKeygenProvideContent(nsString* aAttribute,
|
|
|
|
nsTArray<nsString>* aContent)
|
2014-11-27 01:28:28 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIFormProcessor> formProcessor =
|
|
|
|
do_GetService(kFormProcessorCID);
|
|
|
|
if (!formProcessor) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
formProcessor->ProvideContent(NS_LITERAL_STRING("SELECT"), *aContent,
|
|
|
|
*aAttribute);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-11-27 01:28:28 +03:00
|
|
|
}
|
|
|
|
|
2017-03-14 14:29:43 +03:00
|
|
|
PFileDescriptorSetParent*
|
|
|
|
ContentParent::SendPFileDescriptorSetConstructor(const FileDescriptor& aFD)
|
|
|
|
{
|
|
|
|
return PContentParent::SendPFileDescriptorSetConstructor(aFD);
|
|
|
|
}
|
|
|
|
|
2014-03-25 22:37:13 +04:00
|
|
|
PFileDescriptorSetParent*
|
2014-03-25 22:37:28 +04:00
|
|
|
ContentParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
|
2014-03-25 22:37:13 +04:00
|
|
|
{
|
2016-09-21 13:27:26 +03:00
|
|
|
return nsIContentParent::AllocPFileDescriptorSetParent(aFD);
|
2014-03-25 22:37:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
|
|
|
|
{
|
2016-09-21 13:27:26 +03:00
|
|
|
return nsIContentParent::DeallocPFileDescriptorSetParent(aActor);
|
2014-03-25 22:37:13 +04:00
|
|
|
}
|
|
|
|
|
2014-06-14 00:40:46 +04:00
|
|
|
bool
|
|
|
|
ContentParent::IgnoreIPCPrincipal()
|
|
|
|
{
|
|
|
|
static bool sDidAddVarCache = false;
|
|
|
|
static bool sIgnoreIPCPrincipal = false;
|
|
|
|
if (!sDidAddVarCache) {
|
|
|
|
sDidAddVarCache = true;
|
|
|
|
Preferences::AddBoolVarCache(&sIgnoreIPCPrincipal,
|
|
|
|
"dom.testing.ignore_ipc_principal", false);
|
|
|
|
}
|
|
|
|
return sIgnoreIPCPrincipal;
|
|
|
|
}
|
|
|
|
|
2014-10-03 18:52:37 +04:00
|
|
|
void
|
|
|
|
ContentParent::NotifyUpdatedDictionaries()
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID));
|
|
|
|
MOZ_ASSERT(spellChecker, "No spell checker?");
|
2014-10-03 18:52:37 +04:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
InfallibleTArray<nsString> dictionaries;
|
|
|
|
spellChecker->GetDictionaryList(&dictionaries);
|
2014-10-03 18:52:37 +04:00
|
|
|
|
2016-06-07 01:23:43 +03:00
|
|
|
for (auto* cp : AllProcesses(eLive)) {
|
|
|
|
Unused << cp->SendUpdateDictionaryList(dictionaries);
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2014-10-03 18:52:37 +04:00
|
|
|
}
|
|
|
|
|
2017-11-02 23:29:33 +03:00
|
|
|
void
|
|
|
|
ContentParent::NotifyUpdatedFonts()
|
|
|
|
{
|
|
|
|
InfallibleTArray<SystemFontListEntry> fontList;
|
|
|
|
gfxPlatform::GetPlatform()->ReadSystemFontList(&fontList);
|
|
|
|
|
|
|
|
for (auto* cp : AllProcesses(eLive)) {
|
|
|
|
Unused << cp->SendUpdateFontList(fontList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-29 21:11:00 +03:00
|
|
|
/*static*/ void
|
2017-04-05 13:42:00 +03:00
|
|
|
ContentParent::UnregisterRemoteFrame(const TabId& aTabId,
|
2015-08-28 10:18:00 +03:00
|
|
|
const ContentParentId& aCpId,
|
|
|
|
bool aMarkedDestroying)
|
2014-10-29 21:11:00 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
if (XRE_IsParentProcess()) {
|
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
|
|
|
ContentParent* cp = cpm->GetContentProcessById(aCpId);
|
2015-08-28 10:18:00 +03:00
|
|
|
|
2018-04-25 18:35:56 +03:00
|
|
|
if (!cp) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
cp->NotifyTabDestroyed(aTabId, aMarkedDestroying);
|
2015-08-28 10:18:00 +03:00
|
|
|
|
2017-04-05 13:42:00 +03:00
|
|
|
ContentProcessManager::GetSingleton()->UnregisterRemoteFrame(aCpId, aTabId);
|
2016-01-05 12:59:30 +03:00
|
|
|
} else {
|
2017-04-05 13:42:00 +03:00
|
|
|
ContentChild::GetSingleton()->SendUnregisterRemoteFrame(aTabId, aCpId,
|
2016-01-05 12:59:30 +03:00
|
|
|
aMarkedDestroying);
|
|
|
|
}
|
2014-10-29 21:11:00 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-04-05 13:42:00 +03:00
|
|
|
ContentParent::RecvUnregisterRemoteFrame(const TabId& aTabId,
|
2015-08-28 10:18:00 +03:00
|
|
|
const ContentParentId& aCpId,
|
|
|
|
const bool& aMarkedDestroying)
|
|
|
|
{
|
2017-04-05 13:42:00 +03:00
|
|
|
UnregisterRemoteFrame(aTabId, aCpId, aMarkedDestroying);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-08-28 10:18:00 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-08-28 10:18:00 +03:00
|
|
|
ContentParent::RecvNotifyTabDestroying(const TabId& aTabId,
|
|
|
|
const ContentParentId& aCpId)
|
2014-10-29 21:11:00 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
NotifyTabDestroying(aTabId, aCpId);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-10-29 21:11:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsTArray<TabContext>
|
|
|
|
ContentParent::GetManagedTabContext()
|
|
|
|
{
|
2018-06-01 18:59:07 +03:00
|
|
|
return ContentProcessManager::GetSingleton()->
|
|
|
|
GetTabContextByContentProcess(this->ChildID());
|
2014-10-29 21:11:00 +03:00
|
|
|
}
|
|
|
|
|
2014-11-13 03:31:00 +03:00
|
|
|
mozilla::docshell::POfflineCacheUpdateParent*
|
|
|
|
ContentParent::AllocPOfflineCacheUpdateParent(const URIParams& aManifestURI,
|
|
|
|
const URIParams& aDocumentURI,
|
2015-10-02 19:10:02 +03:00
|
|
|
const PrincipalInfo& aLoadingPrincipalInfo,
|
2016-01-18 22:20:08 +03:00
|
|
|
const bool& aStickDocument)
|
2014-11-13 03:31:00 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
|
2016-01-18 22:20:08 +03:00
|
|
|
new mozilla::docshell::OfflineCacheUpdateParent();
|
2016-01-05 12:59:30 +03:00
|
|
|
// Use this reference as the IPDL reference.
|
|
|
|
return update.forget().take();
|
2014-11-13 03:31:00 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2014-11-13 03:31:00 +03:00
|
|
|
ContentParent::RecvPOfflineCacheUpdateConstructor(POfflineCacheUpdateParent* aActor,
|
|
|
|
const URIParams& aManifestURI,
|
|
|
|
const URIParams& aDocumentURI,
|
2015-10-02 19:10:02 +03:00
|
|
|
const PrincipalInfo& aLoadingPrincipal,
|
2016-01-18 22:20:08 +03:00
|
|
|
const bool& aStickDocument)
|
2014-11-13 03:31:00 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(aActor);
|
2014-11-13 03:31:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
RefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
|
|
|
|
static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor);
|
2014-11-13 03:31:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsresult rv = update->Schedule(aManifestURI, aDocumentURI, aLoadingPrincipal, aStickDocument);
|
|
|
|
if (NS_FAILED(rv) && IsAlive()) {
|
|
|
|
// Inform the child of failure.
|
|
|
|
Unused << update->SendFinish(false, false);
|
|
|
|
}
|
2014-11-13 03:31:00 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-11-13 03:31:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActor)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// Reclaim the IPDL reference.
|
|
|
|
RefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
|
|
|
|
dont_AddRef(static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor));
|
|
|
|
return true;
|
2014-11-13 03:31:00 +03:00
|
|
|
}
|
|
|
|
|
2015-04-22 01:29:18 +03:00
|
|
|
PWebrtcGlobalParent *
|
|
|
|
ContentParent::AllocPWebrtcGlobalParent()
|
|
|
|
{
|
2015-05-06 19:29:33 +03:00
|
|
|
#ifdef MOZ_WEBRTC
|
2016-01-05 12:59:30 +03:00
|
|
|
return WebrtcGlobalParent::Alloc();
|
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
|
|
|
|
ContentParent::DeallocPWebrtcGlobalParent(PWebrtcGlobalParent *aActor)
|
|
|
|
{
|
2015-05-06 19:29:33 +03:00
|
|
|
#ifdef MOZ_WEBRTC
|
2016-01-05 12:59:30 +03:00
|
|
|
WebrtcGlobalParent::Dealloc(static_cast<WebrtcGlobalParent*>(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
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2014-11-13 03:31:00 +03:00
|
|
|
ContentParent::RecvSetOfflinePermission(const Principal& aPrincipal)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsIPrincipal* principal = aPrincipal;
|
2016-01-30 20:05:36 +03:00
|
|
|
nsContentUtils::MaybeAllowOfflineAppByDefault(principal);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-11-13 03:31:00 +03:00
|
|
|
}
|
2014-10-29 21:11:00 +03:00
|
|
|
|
2015-04-08 21:48:11 +03:00
|
|
|
void
|
|
|
|
ContentParent::MaybeInvokeDragSession(TabParent* aParent)
|
|
|
|
{
|
2017-08-02 10:23:35 +03:00
|
|
|
// dnd uses IPCBlob to transfer data to the content process and the IPC
|
|
|
|
// message is sent as normal priority. When sending input events with input
|
|
|
|
// priority, the message may be preempted by the later dnd events. To make
|
|
|
|
// sure the input events and the blob message are processed in time order
|
|
|
|
// on the content process, we temporarily send the input events with normal
|
|
|
|
// priority when there is an active dnd session.
|
|
|
|
SetInputPriorityEventEnabled(false);
|
|
|
|
|
2015-04-08 21:48:11 +03:00
|
|
|
nsCOMPtr<nsIDragService> dragService =
|
|
|
|
do_GetService("@mozilla.org/widget/dragservice;1");
|
|
|
|
if (dragService && dragService->MaybeAddChildProcess(this)) {
|
|
|
|
// We need to send transferable data to child process.
|
|
|
|
nsCOMPtr<nsIDragSession> session;
|
|
|
|
dragService->GetCurrentSession(getter_AddRefs(session));
|
|
|
|
if (session) {
|
|
|
|
nsTArray<IPCDataTransfer> dataTransfers;
|
2018-03-13 23:23:59 +03:00
|
|
|
RefPtr<DataTransfer> transfer = session->GetDataTransfer();
|
2015-04-08 21:48:11 +03:00
|
|
|
if (!transfer) {
|
2015-09-02 09:08:01 +03:00
|
|
|
// Pass eDrop to get DataTransfer with external
|
2015-04-08 21:48:11 +03:00
|
|
|
// drag formats cached.
|
2015-09-02 09:08:01 +03:00
|
|
|
transfer = new DataTransfer(nullptr, eDrop, true, -1);
|
2015-04-08 21:48:11 +03:00
|
|
|
session->SetDataTransfer(transfer);
|
|
|
|
}
|
|
|
|
// Note, even though this fills the DataTransfer object with
|
|
|
|
// external data, the data is usually transfered over IPC lazily when
|
|
|
|
// needed.
|
|
|
|
transfer->FillAllExternalData();
|
|
|
|
nsCOMPtr<nsILoadContext> lc = aParent ?
|
|
|
|
aParent->GetLoadContext() : nullptr;
|
2016-10-18 21:56:20 +03:00
|
|
|
nsCOMPtr<nsIArray> transferables =
|
2015-04-08 21:48:11 +03:00
|
|
|
transfer->GetTransferables(lc);
|
|
|
|
nsContentUtils::TransferablesToIPCTransferables(transferables,
|
|
|
|
dataTransfers,
|
2015-10-28 00:41:58 +03:00
|
|
|
false,
|
2015-04-08 21:48:11 +03:00
|
|
|
nullptr,
|
|
|
|
this);
|
|
|
|
uint32_t action;
|
|
|
|
session->GetDragAction(&action);
|
2015-11-02 08:53:26 +03:00
|
|
|
mozilla::Unused << SendInvokeDragSession(dataTransfers, action);
|
2015-04-08 21:48:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-04-08 21:48:11 +03:00
|
|
|
ContentParent::RecvUpdateDropEffect(const uint32_t& aDragAction,
|
|
|
|
const uint32_t& aDropEffect)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
|
|
|
|
if (dragSession) {
|
|
|
|
dragSession->SetDragAction(aDragAction);
|
2018-03-13 23:23:59 +03:00
|
|
|
RefPtr<DataTransfer> dt = dragSession->GetDataTransfer();
|
2015-04-08 21:48:11 +03:00
|
|
|
if (dt) {
|
|
|
|
dt->SetDropEffectInt(aDropEffect);
|
|
|
|
}
|
|
|
|
dragSession->UpdateDragEffect();
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-04-08 21:48:11 +03:00
|
|
|
}
|
|
|
|
|
2015-04-14 04:08:00 +03:00
|
|
|
PContentPermissionRequestParent*
|
|
|
|
ContentParent::AllocPContentPermissionRequestParent(const InfallibleTArray<PermissionRequest>& aRequests,
|
|
|
|
const IPC::Principal& aPrincipal,
|
2017-02-20 22:46:39 +03:00
|
|
|
const bool& aIsHandlingUserInput,
|
2015-04-14 04:08:00 +03:00
|
|
|
const TabId& aTabId)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
|
|
|
RefPtr<TabParent> tp =
|
|
|
|
cpm->GetTopLevelTabParentByProcessAndTabId(this->ChildID(), aTabId);
|
|
|
|
if (!tp) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-04-14 04:08:00 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
return nsContentPermissionUtils::CreateContentPermissionRequestParent(aRequests,
|
|
|
|
tp->GetOwnerElement(),
|
|
|
|
aPrincipal,
|
2017-02-20 22:46:39 +03:00
|
|
|
aIsHandlingUserInput,
|
2016-01-05 12:59:30 +03:00
|
|
|
aTabId);
|
2015-04-14 04:08:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor)
|
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
nsContentPermissionUtils::NotifyRemoveContentPermissionRequestParent(actor);
|
|
|
|
delete actor;
|
|
|
|
return true;
|
2015-04-14 04:08:00 +03:00
|
|
|
}
|
|
|
|
|
2015-09-21 15:54:00 +03:00
|
|
|
PWebBrowserPersistDocumentParent*
|
|
|
|
ContentParent::AllocPWebBrowserPersistDocumentParent(PBrowserParent* aBrowser,
|
|
|
|
const uint64_t& aOuterWindowID)
|
|
|
|
{
|
|
|
|
return new WebBrowserPersistDocumentParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPWebBrowserPersistDocumentParent(PWebBrowserPersistDocumentParent* aActor)
|
|
|
|
{
|
|
|
|
delete aActor;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-11-24 18:08:31 +03:00
|
|
|
ContentParent::CommonCreateWindow(PBrowserParent* aThisTab,
|
|
|
|
bool aSetOpener,
|
|
|
|
const uint32_t& aChromeFlags,
|
|
|
|
const bool& aCalledFromJS,
|
|
|
|
const bool& aPositionSpecified,
|
|
|
|
const bool& aSizeSpecified,
|
|
|
|
nsIURI* aURIToLoad,
|
|
|
|
const nsCString& aFeatures,
|
|
|
|
const nsCString& aBaseURI,
|
|
|
|
const float& aFullZoom,
|
2017-04-17 01:52:02 +03:00
|
|
|
uint64_t aNextTabParentId,
|
2017-06-05 20:33:11 +03:00
|
|
|
const nsString& aName,
|
2016-11-24 18:08:31 +03:00
|
|
|
nsresult& aResult,
|
|
|
|
nsCOMPtr<nsITabParent>& aNewTabParent,
|
2017-07-05 22:57:47 +03:00
|
|
|
bool* aWindowIsNew,
|
2018-07-19 21:05:35 +03:00
|
|
|
int32_t& aOpenLocation,
|
2017-08-24 16:43:28 +03:00
|
|
|
nsIPrincipal* aTriggeringPrincipal,
|
2017-11-30 16:42:05 +03:00
|
|
|
uint32_t aReferrerPolicy,
|
2017-08-24 16:43:28 +03:00
|
|
|
bool aLoadURI)
|
2016-11-23 20:32:50 +03:00
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
{
|
2016-01-05 12:59:30 +03:00
|
|
|
// The content process should never be in charge of computing whether or
|
|
|
|
// not a window should be private or remote - the parent will do that.
|
2016-11-24 18:08:31 +03:00
|
|
|
const uint32_t badFlags = nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW |
|
|
|
|
nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW |
|
|
|
|
nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME |
|
|
|
|
nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
|
2016-01-08 23:40:26 +03:00
|
|
|
if (!!(aChromeFlags & badFlags)) {
|
2016-11-24 18:08:31 +03:00
|
|
|
return IPC_FAIL(this, "Forbidden aChromeFlags passed");
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
TabParent* thisTabParent = TabParent::GetFrom(aThisTab);
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIContent> frame;
|
|
|
|
if (thisTabParent) {
|
|
|
|
frame = do_QueryInterface(thisTabParent->GetOwnerElement());
|
2016-11-24 18:08:31 +03:00
|
|
|
|
|
|
|
if (NS_WARN_IF(thisTabParent->IsMozBrowser())) {
|
|
|
|
return IPC_FAIL(this, "aThisTab is not a MozBrowser");
|
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> outerWin;
|
2016-01-05 12:59:30 +03:00
|
|
|
if (frame) {
|
2016-11-24 18:08:31 +03:00
|
|
|
outerWin = frame->OwnerDoc()->GetWindow();
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// If our chrome window is in the process of closing, don't try to open a
|
|
|
|
// new tab in it.
|
2016-11-24 18:08:31 +03:00
|
|
|
if (outerWin && outerWin->Closed()) {
|
|
|
|
outerWin = nullptr;
|
2015-10-30 02:30:57 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
|
|
|
|
if (thisTabParent) {
|
|
|
|
browserDOMWin = thisTabParent->GetBrowserDOMWindow();
|
|
|
|
}
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
// If we haven't found a chrome window to open in, just use the most recently
|
|
|
|
// opened one.
|
2016-11-24 18:08:31 +03:00
|
|
|
if (!outerWin) {
|
|
|
|
outerWin = nsContentUtils::GetMostRecentNonPBWindow();
|
|
|
|
if (NS_WARN_IF(!outerWin)) {
|
|
|
|
aResult = NS_ERROR_FAILURE;
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-10-30 02:30:57 +03:00
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(outerWin);
|
2016-01-05 12:59:30 +03:00
|
|
|
if (rootChromeWin) {
|
|
|
|
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
|
|
|
|
}
|
|
|
|
}
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2018-07-19 21:05:35 +03:00
|
|
|
aOpenLocation = nsWindowWatcher::GetWindowOpenLocation(
|
2016-11-24 18:08:31 +03:00
|
|
|
outerWin, aChromeFlags, aCalledFromJS, aPositionSpecified, aSizeSpecified);
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2018-07-19 21:05:35 +03:00
|
|
|
MOZ_ASSERT(aOpenLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
|
|
|
|
aOpenLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2017-06-06 21:22:17 +03:00
|
|
|
// Read the origin attributes for the tab from the opener tabParent.
|
|
|
|
OriginAttributes openerOriginAttributes;
|
|
|
|
if (thisTabParent) {
|
|
|
|
nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
|
|
|
|
loadContext->GetOriginAttributes(openerOriginAttributes);
|
|
|
|
} else if (Preferences::GetBool("browser.privatebrowsing.autostart")) {
|
|
|
|
openerOriginAttributes.mPrivateBrowsingId = 1;
|
|
|
|
}
|
|
|
|
|
2018-07-19 21:05:35 +03:00
|
|
|
if (aOpenLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
|
2016-01-05 12:59:30 +03:00
|
|
|
if (NS_WARN_IF(!browserDOMWin)) {
|
2016-11-24 18:08:31 +03:00
|
|
|
aResult = NS_ERROR_ABORT;
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2017-08-17 01:11:59 +03:00
|
|
|
nsCOMPtr<nsIFrameLoaderOwner> opener = do_QueryInterface(frame);
|
|
|
|
|
2016-02-18 11:33:07 +03:00
|
|
|
nsCOMPtr<nsIOpenURIInFrameParams> params =
|
2017-08-17 01:11:59 +03:00
|
|
|
new nsOpenURIInFrameParams(openerOriginAttributes, opener);
|
2016-01-05 12:59:30 +03:00
|
|
|
params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI));
|
2017-07-05 22:57:47 +03:00
|
|
|
MOZ_ASSERT(aTriggeringPrincipal, "need a valid triggeringPrincipal");
|
|
|
|
params->SetTriggeringPrincipal(aTriggeringPrincipal);
|
2017-11-30 16:42:05 +03:00
|
|
|
params->SetReferrerPolicy(aReferrerPolicy);
|
2015-10-30 02:30:57 +03:00
|
|
|
|
2016-01-05 12:59:30 +03:00
|
|
|
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
|
2017-08-24 16:43:28 +03:00
|
|
|
if (aLoadURI) {
|
|
|
|
aResult = browserDOMWin->OpenURIInFrame(aURIToLoad,
|
2018-07-19 21:05:35 +03:00
|
|
|
params, aOpenLocation,
|
2017-08-24 16:43:28 +03:00
|
|
|
nsIBrowserDOMWindow::OPEN_NEW,
|
|
|
|
aNextTabParentId, aName,
|
|
|
|
getter_AddRefs(frameLoaderOwner));
|
|
|
|
} else {
|
|
|
|
aResult = browserDOMWin->CreateContentWindowInFrame(aURIToLoad,
|
2018-07-19 21:05:35 +03:00
|
|
|
params, aOpenLocation,
|
2017-08-24 16:43:28 +03:00
|
|
|
nsIBrowserDOMWindow::OPEN_NEW,
|
|
|
|
aNextTabParentId, aName,
|
|
|
|
getter_AddRefs(frameLoaderOwner));
|
|
|
|
}
|
2016-11-24 18:08:31 +03:00
|
|
|
if (NS_SUCCEEDED(aResult) && frameLoaderOwner) {
|
|
|
|
RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
|
|
|
|
if (frameLoader) {
|
2018-03-22 05:43:16 +03:00
|
|
|
aNewTabParent = frameLoader->GetTabParent();
|
2018-04-20 00:26:56 +03:00
|
|
|
// At this point, it's possible the inserted frameloader hasn't gone through
|
|
|
|
// layout yet. To ensure that the dimensions that we send down when telling the
|
|
|
|
// frameloader to display will be correct (instead of falling back to a 10x10
|
|
|
|
// default), we force layout if necessary to get the most up-to-date dimensions.
|
|
|
|
// See bug 1358712 for details.
|
|
|
|
frameLoader->ForceLayoutIfNecessary();
|
2016-11-24 18:08:31 +03:00
|
|
|
}
|
2017-12-06 00:44:14 +03:00
|
|
|
} else if (NS_SUCCEEDED(aResult) && !frameLoaderOwner) {
|
|
|
|
// Fall through to the normal window opening code path when there is no
|
|
|
|
// window which we can open a new tab in.
|
2018-07-19 21:05:35 +03:00
|
|
|
aOpenLocation = nsIBrowserDOMWindow::OPEN_NEWWINDOW;
|
2016-11-24 18:08:31 +03:00
|
|
|
} else {
|
2016-01-05 12:59:30 +03:00
|
|
|
*aWindowIsNew = false;
|
2015-10-30 02:30:57 +03:00
|
|
|
}
|
|
|
|
|
2017-12-06 00:44:14 +03:00
|
|
|
// If we didn't retarget our window open into a new window, we should return now.
|
2018-07-19 21:05:35 +03:00
|
|
|
if (aOpenLocation != nsIBrowserDOMWindow::OPEN_NEWWINDOW) {
|
2017-12-06 00:44:14 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
2016-11-23 16:36:58 +03:00
|
|
|
}
|
|
|
|
|
2016-11-23 20:32:50 +03:00
|
|
|
nsCOMPtr<nsPIWindowWatcher> pwwatch =
|
2016-11-24 18:08:31 +03:00
|
|
|
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &aResult);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(aResult))) {
|
2016-11-23 20:32:50 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
2016-11-23 16:36:58 +03:00
|
|
|
|
2017-06-06 21:22:17 +03:00
|
|
|
aResult = pwwatch->OpenWindowWithTabParent(thisTabParent,
|
2017-02-28 10:28:36 +03:00
|
|
|
aFeatures, aCalledFromJS, aFullZoom,
|
2017-04-17 01:52:02 +03:00
|
|
|
aNextTabParentId,
|
2017-06-06 21:22:17 +03:00
|
|
|
!aSetOpener,
|
2017-02-28 10:28:36 +03:00
|
|
|
getter_AddRefs(aNewTabParent));
|
|
|
|
if (NS_WARN_IF(NS_FAILED(aResult))) {
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-06-05 20:33:11 +03:00
|
|
|
MOZ_ASSERT(aNewTabParent);
|
2018-04-20 00:26:56 +03:00
|
|
|
|
|
|
|
// At this point, it's possible the inserted frameloader hasn't gone through
|
|
|
|
// layout yet. To ensure that the dimensions that we send down when telling the
|
|
|
|
// frameloader to display will be correct (instead of falling back to a 10x10
|
|
|
|
// default), we force layout if necessary to get the most up-to-date dimensions.
|
|
|
|
// See bug 1358712 for details.
|
|
|
|
//
|
|
|
|
// This involves doing a bit of gymnastics in order to get at the FrameLoader,
|
|
|
|
// so we scope this to avoid polluting the main function scope.
|
|
|
|
{
|
|
|
|
nsCOMPtr<Element> frameElement =
|
|
|
|
TabParent::GetFrom(aNewTabParent)->GetOwnerElement();
|
|
|
|
MOZ_ASSERT(frameElement);
|
|
|
|
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner = do_QueryInterface(frameElement);
|
|
|
|
MOZ_ASSERT(frameLoaderOwner);
|
|
|
|
RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
|
|
|
|
MOZ_ASSERT(frameLoader);
|
|
|
|
frameLoader->ForceLayoutIfNecessary();
|
|
|
|
}
|
|
|
|
|
2017-06-05 20:33:11 +03:00
|
|
|
// If we were passed a name for the window which would override the default,
|
|
|
|
// we should send it down to the new tab.
|
|
|
|
if (nsContentUtils::IsOverridingWindowName(aName)) {
|
|
|
|
Unused << TabParent::GetFrom(aNewTabParent)->SendSetWindowName(aName);
|
|
|
|
}
|
|
|
|
|
2017-06-06 21:22:17 +03:00
|
|
|
// Don't send down the OriginAttributes if the content process is handling
|
|
|
|
// setting up the window for us. We only want to send them in the async case.
|
|
|
|
//
|
|
|
|
// If we send it down in the non-async case, then we might set the
|
|
|
|
// OriginAttributes after the document has already navigated.
|
|
|
|
if (!aSetOpener) {
|
|
|
|
Unused << TabParent::GetFrom(aNewTabParent)
|
|
|
|
->SendSetOriginAttributes(openerOriginAttributes);
|
|
|
|
}
|
|
|
|
|
2017-08-24 16:43:28 +03:00
|
|
|
if (aURIToLoad && aLoadURI) {
|
2017-02-28 10:28:36 +03:00
|
|
|
nsCOMPtr<mozIDOMWindowProxy> openerWindow;
|
|
|
|
if (aSetOpener && thisTabParent) {
|
|
|
|
openerWindow = thisTabParent->GetParentWindowOuter();
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIBrowserDOMWindow> newBrowserDOMWin =
|
|
|
|
TabParent::GetFrom(aNewTabParent)->GetBrowserDOMWindow();
|
|
|
|
if (NS_WARN_IF(!newBrowserDOMWin)) {
|
|
|
|
aResult = NS_ERROR_ABORT;
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
nsCOMPtr<mozIDOMWindowProxy> win;
|
|
|
|
aResult = newBrowserDOMWin->OpenURI(aURIToLoad, openerWindow,
|
|
|
|
nsIBrowserDOMWindow::OPEN_CURRENTWINDOW,
|
|
|
|
nsIBrowserDOMWindow::OPEN_NEW,
|
2017-07-05 22:58:21 +03:00
|
|
|
aTriggeringPrincipal,
|
2017-02-28 10:28:36 +03:00
|
|
|
getter_AddRefs(win));
|
2016-11-24 18:08:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
|
|
|
PBrowserParent* aNewTab,
|
|
|
|
PRenderFrameParent* aRenderFrame,
|
|
|
|
const uint32_t& aChromeFlags,
|
|
|
|
const bool& aCalledFromJS,
|
|
|
|
const bool& aPositionSpecified,
|
|
|
|
const bool& aSizeSpecified,
|
2017-08-24 16:43:28 +03:00
|
|
|
const OptionalURIParams& aURIToLoad,
|
2016-11-24 18:08:31 +03:00
|
|
|
const nsCString& aFeatures,
|
|
|
|
const nsCString& aBaseURI,
|
|
|
|
const float& aFullZoom,
|
2017-07-05 22:57:47 +03:00
|
|
|
const IPC::Principal& aTriggeringPrincipal,
|
2017-11-30 16:42:05 +03:00
|
|
|
const uint32_t& aReferrerPolicy,
|
2017-06-15 20:28:11 +03:00
|
|
|
CreateWindowResolver&& aResolve)
|
2016-11-24 18:08:31 +03:00
|
|
|
{
|
2017-06-15 20:28:11 +03:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
CreatedWindowInfo cwi;
|
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
// We always expect to open a new window here. If we don't, it's an error.
|
2017-06-15 20:28:11 +03:00
|
|
|
cwi.windowOpened() = true;
|
2018-03-25 02:06:01 +03:00
|
|
|
cwi.layersId() = LayersId{0};
|
2017-06-15 20:28:11 +03:00
|
|
|
cwi.maxTouchPoints() = 0;
|
2018-07-19 21:05:35 +03:00
|
|
|
cwi.hasSiblings() = false;
|
2017-06-15 20:28:11 +03:00
|
|
|
|
|
|
|
// Make sure to resolve the resolver when this function exits, even if we
|
|
|
|
// failed to generate a valid response.
|
|
|
|
auto resolveOnExit = MakeScopeExit([&] {
|
|
|
|
// Copy over the nsresult, and then resolve.
|
|
|
|
cwi.rv() = rv;
|
|
|
|
aResolve(cwi);
|
|
|
|
});
|
2016-11-24 18:08:31 +03:00
|
|
|
|
|
|
|
TabParent* newTab = TabParent::GetFrom(aNewTab);
|
|
|
|
MOZ_ASSERT(newTab);
|
|
|
|
|
|
|
|
auto destroyNewTabOnError = MakeScopeExit([&] {
|
2017-06-15 20:28:11 +03:00
|
|
|
// We always expect to open a new window here. If we don't, it's an error.
|
|
|
|
if (!cwi.windowOpened() || NS_FAILED(rv)) {
|
2016-11-24 18:08:31 +03:00
|
|
|
if (newTab) {
|
|
|
|
newTab->Destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Content has requested that we open this new content window, so
|
|
|
|
// we must have an opener.
|
|
|
|
newTab->SetHasContentOpener(true);
|
|
|
|
|
2017-06-15 20:28:11 +03:00
|
|
|
TabParent::AutoUseNewTab aunt(newTab, &cwi.urlToLoad());
|
2017-04-17 01:52:02 +03:00
|
|
|
const uint64_t nextTabParentId = ++sNextTabParentId;
|
|
|
|
sNextTabParents.Put(nextTabParentId, newTab);
|
2016-11-24 18:08:31 +03:00
|
|
|
|
2017-08-24 16:43:28 +03:00
|
|
|
const nsCOMPtr<nsIURI> uriToLoad = DeserializeURI(aURIToLoad);
|
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
nsCOMPtr<nsITabParent> newRemoteTab;
|
2018-07-19 21:05:35 +03:00
|
|
|
int32_t openLocation = nsIBrowserDOMWindow::OPEN_NEWWINDOW;
|
2016-11-24 18:08:31 +03:00
|
|
|
mozilla::ipc::IPCResult ipcResult =
|
|
|
|
CommonCreateWindow(aThisTab, /* aSetOpener = */ true, aChromeFlags,
|
|
|
|
aCalledFromJS, aPositionSpecified, aSizeSpecified,
|
2017-08-24 16:43:28 +03:00
|
|
|
uriToLoad, aFeatures, aBaseURI, aFullZoom,
|
2017-09-22 07:35:46 +03:00
|
|
|
nextTabParentId, VoidString(), rv,
|
2018-07-19 21:05:35 +03:00
|
|
|
newRemoteTab, &cwi.windowOpened(), openLocation,
|
2017-11-30 16:42:05 +03:00
|
|
|
aTriggeringPrincipal, aReferrerPolicy,
|
|
|
|
/* aLoadUri = */ false);
|
2016-11-24 18:08:31 +03:00
|
|
|
if (!ipcResult) {
|
|
|
|
return ipcResult;
|
2016-07-05 19:00:07 +03:00
|
|
|
}
|
2016-07-19 10:12:58 +03:00
|
|
|
|
2017-08-24 16:43:28 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv)) || !newRemoteTab) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-01-05 12:59:30 +03:00
|
|
|
}
|
|
|
|
|
2017-04-17 01:52:02 +03:00
|
|
|
if (sNextTabParents.GetAndRemove(nextTabParentId).valueOr(nullptr)) {
|
2017-06-15 20:28:11 +03:00
|
|
|
cwi.windowOpened() = false;
|
2017-04-17 01:52:02 +03:00
|
|
|
}
|
2016-01-05 12:59:30 +03:00
|
|
|
MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
|
|
|
|
|
2017-06-15 20:28:11 +03:00
|
|
|
newTab->SwapFrameScriptsFrom(cwi.frameScripts());
|
2016-03-29 21:32:41 +03:00
|
|
|
|
|
|
|
RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
|
|
|
|
if (!newTab->SetRenderFrame(rfp) ||
|
2017-06-15 20:28:11 +03:00
|
|
|
!newTab->GetRenderFrameInfo(&cwi.textureFactoryIdentifier(), &cwi.layersId())) {
|
|
|
|
rv = NS_ERROR_FAILURE;
|
2016-03-29 21:32:41 +03:00
|
|
|
}
|
2017-06-15 20:28:11 +03:00
|
|
|
cwi.compositorOptions() = rfp->GetCompositorOptions();
|
2016-03-29 21:32:41 +03:00
|
|
|
|
2017-03-15 02:48:41 +03:00
|
|
|
nsCOMPtr<nsIWidget> widget = newTab->GetWidget();
|
2017-06-15 20:28:11 +03:00
|
|
|
if (widget) {
|
|
|
|
cwi.maxTouchPoints() = widget->GetMaxTouchPoints();
|
|
|
|
cwi.dimensions() = newTab->GetDimensionInfo();
|
|
|
|
}
|
2017-06-07 21:36:46 +03:00
|
|
|
|
2018-07-19 21:05:35 +03:00
|
|
|
cwi.hasSiblings() = (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB);
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-10-30 02:30:57 +03:00
|
|
|
}
|
|
|
|
|
2016-11-24 18:08:31 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvCreateWindowInDifferentProcess(
|
|
|
|
PBrowserParent* aThisTab,
|
|
|
|
const uint32_t& aChromeFlags,
|
|
|
|
const bool& aCalledFromJS,
|
|
|
|
const bool& aPositionSpecified,
|
|
|
|
const bool& aSizeSpecified,
|
2017-08-29 18:19:48 +03:00
|
|
|
const OptionalURIParams& aURIToLoad,
|
2016-11-24 18:08:31 +03:00
|
|
|
const nsCString& aFeatures,
|
|
|
|
const nsCString& aBaseURI,
|
2017-06-05 20:33:11 +03:00
|
|
|
const float& aFullZoom,
|
2017-07-05 22:57:47 +03:00
|
|
|
const nsString& aName,
|
2017-11-30 16:42:05 +03:00
|
|
|
const IPC::Principal& aTriggeringPrincipal,
|
|
|
|
const uint32_t& aReferrerPolicy)
|
2016-11-24 18:08:31 +03:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsITabParent> newRemoteTab;
|
|
|
|
bool windowIsNew;
|
|
|
|
nsCOMPtr<nsIURI> uriToLoad = DeserializeURI(aURIToLoad);
|
2018-07-19 21:05:35 +03:00
|
|
|
int32_t openLocation = nsIBrowserDOMWindow::OPEN_NEWWINDOW;
|
2016-11-24 18:08:31 +03:00
|
|
|
nsresult rv;
|
|
|
|
mozilla::ipc::IPCResult ipcResult =
|
|
|
|
CommonCreateWindow(aThisTab, /* aSetOpener = */ false, aChromeFlags,
|
|
|
|
aCalledFromJS, aPositionSpecified, aSizeSpecified,
|
2017-06-06 21:22:17 +03:00
|
|
|
uriToLoad, aFeatures, aBaseURI, aFullZoom,
|
|
|
|
/* aNextTabParentId = */ 0, aName, rv,
|
2018-07-19 21:05:35 +03:00
|
|
|
newRemoteTab, &windowIsNew, openLocation,
|
|
|
|
aTriggeringPrincipal, aReferrerPolicy,
|
|
|
|
/* aLoadUri = */ true);
|
2016-11-24 18:08:31 +03:00
|
|
|
if (!ipcResult) {
|
|
|
|
return ipcResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_WARNING("Call to CommonCreateWindow failed.");
|
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-05-30 22:06:14 +03:00
|
|
|
ContentParent::RecvShutdownProfile(const nsCString& aProfile)
|
2015-06-11 00:58:30 +03:00
|
|
|
{
|
2017-01-24 06:15:12 +03:00
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
2017-05-30 22:06:14 +03:00
|
|
|
nsCOMPtr<nsIProfiler> profiler(do_GetService("@mozilla.org/tools/profiler;1"));
|
|
|
|
profiler->ReceiveShutdownProfile(aProfile);
|
2016-01-05 12:59:30 +03:00
|
|
|
#endif
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-06-11 00:58:30 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-08-21 06:59:11 +03:00
|
|
|
ContentParent::RecvGetGraphicsDeviceInitData(ContentDeviceData* aOut)
|
2015-08-02 23:59:33 +03:00
|
|
|
{
|
2016-08-21 06:59:11 +03:00
|
|
|
gfxPlatform::GetPlatform()->BuildContentDeviceData(aOut);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-08-02 23:59:33 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-02-17 02:07:37 +03:00
|
|
|
ContentParent::RecvGraphicsError(const nsCString& aError)
|
|
|
|
{
|
|
|
|
gfx::LogForwarder* lf = gfx::Factory::GetLogForwarder();
|
|
|
|
if (lf) {
|
|
|
|
std::stringstream message;
|
|
|
|
message << "CP+" << aError.get();
|
|
|
|
lf->UpdateStringsVector(message.str());
|
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-02-17 02:07:37 +03:00
|
|
|
}
|
|
|
|
|
2018-08-12 14:50:41 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvRecordReplayFatalError(const nsCString& aError)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPromptService> promptService(do_GetService(NS_PROMPTSERVICE_CONTRACTID));
|
|
|
|
MOZ_RELEASE_ASSERT(promptService);
|
|
|
|
|
|
|
|
nsAutoCString str(aError);
|
|
|
|
promptService->Alert(nullptr, u"Fatal Record/Replay Error", NS_ConvertUTF8toUTF16(str).get());
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-08-12 06:22:20 +03:00
|
|
|
ContentParent::RecvBeginDriverCrashGuard(const uint32_t& aGuardType, bool* aOutCrashed)
|
|
|
|
{
|
|
|
|
// Only one driver crash guard should be active at a time, per-process.
|
|
|
|
MOZ_ASSERT(!mDriverCrashGuard);
|
|
|
|
|
|
|
|
UniquePtr<gfx::DriverCrashGuard> guard;
|
|
|
|
switch (gfx::CrashGuardType(aGuardType)) {
|
2016-01-05 12:59:30 +03:00
|
|
|
case gfx::CrashGuardType::D3D11Layers:
|
|
|
|
guard = MakeUnique<gfx::D3D11LayersCrashGuard>(this);
|
|
|
|
break;
|
|
|
|
case gfx::CrashGuardType::D3D9Video:
|
|
|
|
guard = MakeUnique<gfx::D3D9VideoCrashGuard>(this);
|
|
|
|
break;
|
|
|
|
case gfx::CrashGuardType::GLContext:
|
|
|
|
guard = MakeUnique<gfx::GLContextCrashGuard>(this);
|
|
|
|
break;
|
2016-04-14 07:15:31 +03:00
|
|
|
case gfx::CrashGuardType::D3D11Video:
|
|
|
|
guard = MakeUnique<gfx::D3D11VideoCrashGuard>(this);
|
|
|
|
break;
|
2016-01-05 12:59:30 +03:00
|
|
|
default:
|
|
|
|
MOZ_ASSERT_UNREACHABLE("unknown crash guard type");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2015-08-12 06:22:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (guard->Crashed()) {
|
2016-04-14 07:15:31 +03:00
|
|
|
*aOutCrashed = true;
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-08-12 06:22:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
*aOutCrashed = false;
|
2018-05-30 22:15:35 +03:00
|
|
|
mDriverCrashGuard = std::move(guard);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-08-12 06:22:20 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-08-12 06:22:20 +03:00
|
|
|
ContentParent::RecvEndDriverCrashGuard(const uint32_t& aGuardType)
|
|
|
|
{
|
|
|
|
mDriverCrashGuard = nullptr;
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-08-12 06:22:20 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2015-11-04 22:08:14 +03:00
|
|
|
ContentParent::RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo)
|
|
|
|
{
|
|
|
|
#ifdef MOZ_WIDGET_ANDROID
|
|
|
|
nsSystemInfo::GetAndroidSystemInfo(aInfo);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2015-11-04 22:08:14 +03:00
|
|
|
#else
|
|
|
|
MOZ_CRASH("wrong platform!");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2015-11-04 22:08:14 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-03-17 09:18:35 +03:00
|
|
|
ContentParent::RecvNotifyBenchmarkResult(const nsString& aCodecName,
|
|
|
|
const uint32_t& aDecodeFPS)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (aCodecName.EqualsLiteral("VP9")) {
|
|
|
|
Preferences::SetUint(VP9Benchmark::sBenchmarkFpsPref, aDecodeFPS);
|
2016-04-13 05:44:29 +03:00
|
|
|
Preferences::SetUint(VP9Benchmark::sBenchmarkFpsVersionCheck,
|
|
|
|
VP9Benchmark::sBenchmarkVersionID);
|
2016-03-17 09:18:35 +03:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-03-17 09:18:35 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-04-21 21:11:03 +03:00
|
|
|
ContentParent::RecvNotifyPushObservers(const nsCString& aScope,
|
2016-05-02 19:38:47 +03:00
|
|
|
const IPC::Principal& aPrincipal,
|
2016-04-21 21:11:03 +03:00
|
|
|
const nsString& aMessageId)
|
|
|
|
{
|
2016-05-20 05:01:34 +03:00
|
|
|
PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Nothing());
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-04-21 21:11:03 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-04-21 21:11:03 +03:00
|
|
|
ContentParent::RecvNotifyPushObserversWithData(const nsCString& aScope,
|
2016-05-02 19:38:47 +03:00
|
|
|
const IPC::Principal& aPrincipal,
|
2016-04-21 21:11:03 +03:00
|
|
|
const nsString& aMessageId,
|
|
|
|
InfallibleTArray<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.NotifyObservers()));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-04-21 21:11:03 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-05-02 19:38:47 +03:00
|
|
|
ContentParent::RecvNotifyPushSubscriptionChangeObservers(const nsCString& aScope,
|
|
|
|
const IPC::Principal& aPrincipal)
|
2016-04-21 21:11:03 +03:00
|
|
|
{
|
2016-05-20 05:01:34 +03:00
|
|
|
PushSubscriptionChangeDispatcher dispatcher(aScope, aPrincipal);
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-04-21 21:11:03 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-05-02 18:20:14 +03:00
|
|
|
ContentParent::RecvNotifyPushSubscriptionModifiedObservers(const nsCString& aScope,
|
|
|
|
const IPC::Principal& aPrincipal)
|
2016-04-21 22:04:15 +03:00
|
|
|
{
|
2016-05-20 05:01:34 +03:00
|
|
|
PushSubscriptionModifiedDispatcher dispatcher(aScope, aPrincipal);
|
|
|
|
Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-04-21 22:04:15 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-06-21 21:45:25 +03:00
|
|
|
ContentParent::RecvNotifyLowMemory()
|
|
|
|
{
|
2017-02-07 19:46:44 +03:00
|
|
|
MarkAsTroubled();
|
|
|
|
|
|
|
|
Telemetry::ScalarAdd(Telemetry::ScalarID::DOM_CONTENTPROCESS_TROUBLED_DUE_TO_MEMORY, 1);
|
|
|
|
|
2016-06-21 21:45:25 +03:00
|
|
|
nsThread::SaveMemoryReportNearOOM(nsThread::ShouldSaveMemoryReport::kForceReport);
|
2017-02-07 19:46:44 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-21 21:45:25 +03:00
|
|
|
}
|
|
|
|
|
2016-07-17 17:50:50 +03:00
|
|
|
/* static */ void
|
|
|
|
ContentParent::BroadcastBlobURLRegistration(const nsACString& aURI,
|
|
|
|
BlobImpl* aBlobImpl,
|
|
|
|
nsIPrincipal* aPrincipal,
|
|
|
|
ContentParent* aIgnoreThisCP)
|
|
|
|
{
|
|
|
|
nsCString uri(aURI);
|
|
|
|
IPC::Principal principal(aPrincipal);
|
|
|
|
|
|
|
|
for (auto* cp : AllProcesses(eLive)) {
|
|
|
|
if (cp != aIgnoreThisCP) {
|
2018-05-17 14:36:50 +03:00
|
|
|
nsresult rv = cp->TransmitPermissionsForPrincipal(principal);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-04-24 13:16:49 +03:00
|
|
|
IPCBlob ipcBlob;
|
2018-05-17 14:36:50 +03:00
|
|
|
rv = IPCBlobUtils::Serialize(aBlobImpl, cp, ipcBlob);
|
2017-04-24 13:16:49 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
break;
|
2016-07-17 17:50:50 +03:00
|
|
|
}
|
2017-04-24 13:16:49 +03:00
|
|
|
|
|
|
|
Unused << cp->SendBlobURLRegistration(uri, ipcBlob, principal);
|
2016-07-17 17:50:50 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* static */ void
|
|
|
|
ContentParent::BroadcastBlobURLUnregistration(const nsACString& aURI,
|
|
|
|
ContentParent* aIgnoreThisCP)
|
|
|
|
{
|
|
|
|
nsCString uri(aURI);
|
|
|
|
|
|
|
|
for (auto* cp : AllProcesses(eLive)) {
|
|
|
|
if (cp != aIgnoreThisCP) {
|
|
|
|
Unused << cp->SendBlobURLUnregistration(uri);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-07-17 17:50:50 +03:00
|
|
|
ContentParent::RecvStoreAndBroadcastBlobURLRegistration(const nsCString& aURI,
|
2017-04-24 13:16:49 +03:00
|
|
|
const IPCBlob& aBlob,
|
2016-07-17 17:50:50 +03:00
|
|
|
const Principal& aPrincipal)
|
|
|
|
{
|
2017-04-24 13:16:49 +03:00
|
|
|
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(aBlob);
|
2016-07-17 17:50:50 +03:00
|
|
|
if (NS_WARN_IF(!blobImpl)) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-07-17 17:50:50 +03:00
|
|
|
}
|
|
|
|
|
2018-06-02 16:51:42 +03:00
|
|
|
if (NS_SUCCEEDED(BlobURLProtocolHandler::AddDataEntry(aURI, aPrincipal,
|
|
|
|
blobImpl))) {
|
2016-07-18 12:12:18 +03:00
|
|
|
BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, this);
|
|
|
|
|
|
|
|
// We want to store this blobURL, so we can unregister it if the child
|
|
|
|
// crashes.
|
|
|
|
mBlobURLs.AppendElement(aURI);
|
|
|
|
}
|
|
|
|
|
2016-07-17 17:50:50 +03:00
|
|
|
BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, this);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-17 17:50:50 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-07-17 17:50:50 +03:00
|
|
|
ContentParent::RecvUnstoreAndBroadcastBlobURLUnregistration(const nsCString& aURI)
|
|
|
|
{
|
2018-06-02 16:51:42 +03:00
|
|
|
BlobURLProtocolHandler::RemoveDataEntry(aURI, false /* Don't broadcast */);
|
2016-07-17 17:50:50 +03:00
|
|
|
BroadcastBlobURLUnregistration(aURI, this);
|
2016-07-18 12:12:18 +03:00
|
|
|
mBlobURLs.RemoveElement(aURI);
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-17 17:50:50 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-10-27 21:40:50 +03:00
|
|
|
ContentParent::RecvGetA11yContentId(uint32_t* aContentId)
|
|
|
|
{
|
|
|
|
#if defined(XP_WIN32) && defined(ACCESSIBILITY)
|
|
|
|
*aContentId = a11y::AccessibleWrap::GetContentProcessIdFor(ChildID());
|
|
|
|
MOZ_ASSERT(*aContentId);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-10-27 21:40:50 +03:00
|
|
|
#else
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
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
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvA11yHandlerControl(const uint32_t& aPid,
|
|
|
|
const IHandlerControlHolder& aHandlerControl)
|
|
|
|
{
|
|
|
|
#if defined(XP_WIN32) && defined(ACCESSIBILITY)
|
|
|
|
MOZ_ASSERT(!aHandlerControl.IsNull());
|
|
|
|
RefPtr<IHandlerControl> proxy(aHandlerControl.Get());
|
2018-05-30 22:15:35 +03:00
|
|
|
a11y::AccessibleWrap::SetHandlerControl(aPid, std::move(proxy));
|
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
|
|
|
return IPC_OK();
|
|
|
|
#else
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-10-27 21:40:50 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2009-08-12 20:18:08 +04:00
|
|
|
} // namespace dom
|
2013-02-15 00:41:30 +04:00
|
|
|
} // namespace mozilla
|
2013-12-13 20:28:46 +04:00
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS(ParentIdleListener, nsIObserver)
|
2013-12-13 20:28:46 +04:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2016-01-05 12:59:30 +03:00
|
|
|
ParentIdleListener::Observe(nsISupports*, const char* aTopic, const char16_t* aData)
|
|
|
|
{
|
|
|
|
mozilla::Unused << mParent->SendNotifyIdleObserver(mObserver,
|
|
|
|
nsDependentCString(aTopic),
|
|
|
|
nsDependentString(aData));
|
|
|
|
return NS_OK;
|
2013-12-13 20:28:46 +04:00
|
|
|
}
|
2015-10-08 00:38:08 +03:00
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::HandleWindowsMessages(const Message& aMsg) const
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aMsg.is_sync());
|
|
|
|
|
|
|
|
// a11y messages can be triggered by windows messages, which means if we
|
|
|
|
// allow handling windows messages while we wait for the response to a sync
|
|
|
|
// a11y message we can reenter the ipc message sending code.
|
|
|
|
if (a11y::PDocAccessible::PDocAccessibleStart < aMsg.type() &&
|
|
|
|
a11y::PDocAccessible::PDocAccessibleEnd > aMsg.type()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2016-07-14 10:04:21 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-07-14 10:04:21 +03:00
|
|
|
ContentParent::RecvGetFilesRequest(const nsID& aUUID,
|
|
|
|
const nsString& aDirectoryPath,
|
|
|
|
const bool& aRecursiveFlag)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(!mGetFilesPendingRequests.GetWeak(aUUID));
|
|
|
|
|
2018-05-10 12:24:25 +03:00
|
|
|
if (!mozilla::Preferences::GetBool("dom.filesystem.pathcheck.disabled", false)) {
|
|
|
|
RefPtr<FileSystemSecurity> fss = FileSystemSecurity::Get();
|
|
|
|
if (NS_WARN_IF(!fss ||
|
|
|
|
!fss->ContentProcessHasAccessTo(ChildID(), aDirectoryPath))) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-14 10:04:21 +03:00
|
|
|
ErrorResult rv;
|
|
|
|
RefPtr<GetFilesHelper> helper =
|
|
|
|
GetFilesHelperParent::Create(aUUID, aDirectoryPath, aRecursiveFlag, this,
|
|
|
|
rv);
|
|
|
|
|
|
|
|
if (NS_WARN_IF(rv.Failed())) {
|
2016-11-15 06:26:00 +03:00
|
|
|
if (!SendGetFilesResponse(aUUID,
|
|
|
|
GetFilesResponseFailure(rv.StealNSResult()))) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
2016-07-14 10:04:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mGetFilesPendingRequests.Put(aUUID, helper);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-14 10:04:21 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-07-14 10:04:21 +03:00
|
|
|
ContentParent::RecvDeleteGetFilesRequest(const nsID& aUUID)
|
|
|
|
{
|
2017-06-28 02:03:14 +03:00
|
|
|
mGetFilesPendingRequests.Remove(aUUID);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-07-14 10:04:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ContentParent::SendGetFilesResponseAndForget(const nsID& aUUID,
|
|
|
|
const GetFilesResponseResult& aResult)
|
|
|
|
{
|
2017-07-05 03:01:44 +03:00
|
|
|
if (mGetFilesPendingRequests.Remove(aUUID)) {
|
2016-07-14 10:04:21 +03:00
|
|
|
Unused << SendGetFilesResponse(aUUID, aResult);
|
|
|
|
}
|
|
|
|
}
|
2016-07-23 02:36:45 +03:00
|
|
|
|
|
|
|
void
|
2018-05-15 09:45:00 +03:00
|
|
|
ContentParent::PaintTabWhileInterruptingJS(TabParent* aTabParent,
|
|
|
|
bool aForceRepaint,
|
2018-07-30 16:24:50 +03:00
|
|
|
const layers::LayersObserverEpoch& aEpoch)
|
2016-07-23 02:36:45 +03:00
|
|
|
{
|
|
|
|
if (!mHangMonitorActor) {
|
|
|
|
return;
|
|
|
|
}
|
2018-05-15 09:45:00 +03:00
|
|
|
ProcessHangMonitor::PaintWhileInterruptingJS(mHangMonitorActor,
|
|
|
|
aTabParent,
|
|
|
|
aForceRepaint,
|
2018-07-30 16:24:50 +03:00
|
|
|
aEpoch);
|
2016-07-23 02:36:45 +03:00
|
|
|
}
|
2016-06-22 17:16:40 +03:00
|
|
|
|
2017-08-03 14:00:41 +03:00
|
|
|
void
|
|
|
|
ContentParent::UpdateCookieStatus(nsIChannel *aChannel)
|
|
|
|
{
|
|
|
|
PNeckoParent *neckoParent = LoneManagedOrNullAsserts(ManagedPNeckoParent());
|
|
|
|
PCookieServiceParent *csParent = LoneManagedOrNullAsserts(neckoParent->ManagedPCookieServiceParent());
|
|
|
|
if (csParent) {
|
|
|
|
auto *cs = static_cast<CookieServiceParent*>(csParent);
|
|
|
|
cs->TrackCookieLoad(aChannel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-03 00:55:09 +03:00
|
|
|
nsresult
|
2017-05-01 22:43:39 +03:00
|
|
|
ContentParent::AboutToLoadHttpFtpWyciwygDocumentForChild(nsIChannel* aChannel)
|
2017-03-03 00:55:09 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(aChannel);
|
2017-03-04 02:23:19 +03:00
|
|
|
|
2017-04-20 05:15:16 +03:00
|
|
|
nsresult rv;
|
2017-08-18 19:36:50 +03:00
|
|
|
bool isDocument = aChannel->IsDocument();
|
|
|
|
if (!isDocument) {
|
|
|
|
// We may be looking at a nsIHttpChannel which has isMainDocumentChannel set
|
|
|
|
// (e.g. the internal http channel for a view-source: load.).
|
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
|
|
|
|
if (httpChannel) {
|
|
|
|
rv = httpChannel->GetIsMainDocumentChannel(&isDocument);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!isDocument) {
|
2017-04-20 05:15:16 +03:00
|
|
|
return NS_OK;
|
2017-03-03 00:55:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get the principal for the channel result, so that we can get the permission
|
|
|
|
// key for the document which will be created from this response.
|
|
|
|
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
|
|
|
if (NS_WARN_IF(!ssm)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
rv = ssm->GetChannelResultPrincipal(aChannel, getter_AddRefs(principal));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2017-03-18 00:04:44 +03:00
|
|
|
rv = TransmitPermissionsForPrincipal(principal);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2017-08-03 14:00:41 +03:00
|
|
|
nsLoadFlags newLoadFlags;
|
|
|
|
aChannel->GetLoadFlags(&newLoadFlags);
|
2017-08-18 19:36:50 +03:00
|
|
|
if (newLoadFlags & nsIRequest::LOAD_DOCUMENT_NEEDS_COOKIE) {
|
2017-08-03 14:00:41 +03:00
|
|
|
UpdateCookieStatus(aChannel);
|
|
|
|
}
|
|
|
|
|
2017-03-18 00:04:44 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
ContentParent::TransmitPermissionsForPrincipal(nsIPrincipal* aPrincipal)
|
|
|
|
{
|
2017-03-03 00:55:09 +03:00
|
|
|
// Create the key, and send it down to the content process.
|
2017-03-08 22:28:04 +03:00
|
|
|
nsTArray<nsCString> keys =
|
2017-03-18 00:04:44 +03:00
|
|
|
nsPermissionManager::GetAllKeysForPrincipal(aPrincipal);
|
2017-03-08 22:28:04 +03:00
|
|
|
MOZ_ASSERT(keys.Length() >= 1);
|
|
|
|
for (auto& key : keys) {
|
|
|
|
EnsurePermissionsByKey(key);
|
|
|
|
}
|
2017-03-03 00:55:09 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ContentParent::EnsurePermissionsByKey(const nsCString& aKey)
|
|
|
|
{
|
2017-03-15 23:15:47 +03:00
|
|
|
// NOTE: Make sure to initialize the permission manager before updating the
|
|
|
|
// mActivePermissionKeys list. If the permission manager is being initialized
|
|
|
|
// by this call to GetPermissionManager, and we've added the key to
|
|
|
|
// mActivePermissionKeys, then the permission manager will send down a
|
|
|
|
// SendAddPermission before receiving the SendSetPermissionsWithKey message.
|
|
|
|
nsCOMPtr<nsIPermissionManager> permManager =
|
|
|
|
services::GetPermissionManager();
|
|
|
|
|
2017-03-03 00:55:09 +03:00
|
|
|
if (mActivePermissionKeys.Contains(aKey)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mActivePermissionKeys.PutEntry(aKey);
|
|
|
|
|
|
|
|
nsTArray<IPC::Permission> perms;
|
|
|
|
nsresult rv = permManager->GetPermissionsWithKey(aKey, perms);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Unused << SendSetPermissionsWithKey(aKey, perms);
|
|
|
|
}
|
|
|
|
|
2017-03-03 01:04:52 +03:00
|
|
|
bool
|
|
|
|
ContentParent::NeedsPermissionsUpdate(const nsACString& aPermissionKey) const
|
|
|
|
{
|
|
|
|
return mActivePermissionKeys.Contains(aPermissionKey);
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-02-15 18:25:40 +03:00
|
|
|
ContentParent::RecvAccumulateChildHistograms(
|
2017-09-13 12:20:36 +03:00
|
|
|
InfallibleTArray<HistogramAccumulation>&& aAccumulations)
|
2016-06-22 17:16:40 +03:00
|
|
|
{
|
2017-05-23 09:47:58 +03:00
|
|
|
TelemetryIPC::AccumulateChildHistograms(GetTelemetryProcessID(mRemoteType), aAccumulations);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-22 17:16:40 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2017-02-15 18:25:40 +03:00
|
|
|
ContentParent::RecvAccumulateChildKeyedHistograms(
|
2017-09-13 12:20:36 +03:00
|
|
|
InfallibleTArray<KeyedHistogramAccumulation>&& aAccumulations)
|
2016-06-22 17:16:40 +03:00
|
|
|
{
|
2017-05-23 09:47:58 +03:00
|
|
|
TelemetryIPC::AccumulateChildKeyedHistograms(GetTelemetryProcessID(mRemoteType), aAccumulations);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-22 17:16:40 +03:00
|
|
|
}
|
2016-11-19 00:54:57 +03:00
|
|
|
|
2017-01-16 07:12:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvUpdateChildScalars(
|
|
|
|
InfallibleTArray<ScalarAction>&& aScalarActions)
|
|
|
|
{
|
2017-05-23 09:47:58 +03:00
|
|
|
TelemetryIPC::UpdateChildScalars(GetTelemetryProcessID(mRemoteType), aScalarActions);
|
2017-01-16 07:12:00 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvUpdateChildKeyedScalars(
|
|
|
|
InfallibleTArray<KeyedScalarAction>&& aScalarActions)
|
|
|
|
{
|
2017-05-23 09:47:58 +03:00
|
|
|
TelemetryIPC::UpdateChildKeyedScalars(GetTelemetryProcessID(mRemoteType), aScalarActions);
|
2017-01-16 07:12:00 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-02-14 16:43:51 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvRecordChildEvents(nsTArray<mozilla::Telemetry::ChildEventData>&& aEvents)
|
|
|
|
{
|
2017-05-23 09:47:58 +03:00
|
|
|
TelemetryIPC::RecordChildEvents(GetTelemetryProcessID(mRemoteType), aEvents);
|
2017-02-14 16:43:51 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-06-09 16:53:42 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvRecordDiscardedData(
|
|
|
|
const mozilla::Telemetry::DiscardedData& aDiscardedData)
|
|
|
|
{
|
|
|
|
TelemetryIPC::RecordDiscardedData(GetTelemetryProcessID(mRemoteType),
|
|
|
|
aDiscardedData);
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2017-04-07 09:15:16 +03:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// PURLClassifierParent
|
|
|
|
|
2016-11-19 00:54:57 +03:00
|
|
|
PURLClassifierParent*
|
|
|
|
ContentParent::AllocPURLClassifierParent(const Principal& aPrincipal,
|
|
|
|
const bool& aUseTrackingProtection,
|
|
|
|
bool* aSuccess)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
*aSuccess = true;
|
|
|
|
RefPtr<URLClassifierParent> actor = new URLClassifierParent();
|
|
|
|
return actor.forget().take();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvPURLClassifierConstructor(PURLClassifierParent* aActor,
|
|
|
|
const Principal& aPrincipal,
|
|
|
|
const bool& aUseTrackingProtection,
|
|
|
|
bool* aSuccess)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aActor);
|
2016-12-24 02:28:39 +03:00
|
|
|
*aSuccess = false;
|
2016-11-19 00:54:57 +03:00
|
|
|
|
|
|
|
auto* actor = static_cast<URLClassifierParent*>(aActor);
|
|
|
|
nsCOMPtr<nsIPrincipal> principal(aPrincipal);
|
|
|
|
if (!principal) {
|
2016-12-22 23:04:05 +03:00
|
|
|
actor->ClassificationFailed();
|
|
|
|
return IPC_OK();
|
2016-11-19 00:54:57 +03:00
|
|
|
}
|
|
|
|
return actor->StartClassify(principal, aUseTrackingProtection, aSuccess);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPURLClassifierParent(PURLClassifierParent* aActor)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aActor);
|
|
|
|
|
|
|
|
RefPtr<URLClassifierParent> actor =
|
|
|
|
dont_AddRef(static_cast<URLClassifierParent*>(aActor));
|
|
|
|
return true;
|
|
|
|
}
|
2016-11-19 00:43:28 +03:00
|
|
|
|
2017-04-07 09:15:16 +03:00
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
// PURLClassifierLocalParent
|
|
|
|
|
|
|
|
PURLClassifierLocalParent*
|
|
|
|
ContentParent::AllocPURLClassifierLocalParent(const URIParams& aURI,
|
|
|
|
const nsCString& aTables)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
RefPtr<URLClassifierLocalParent> actor = new URLClassifierLocalParent();
|
|
|
|
return actor.forget().take();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvPURLClassifierLocalConstructor(PURLClassifierLocalParent* aActor,
|
|
|
|
const URIParams& aURI,
|
|
|
|
const nsCString& aTables)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aActor);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
|
|
|
if (!uri) {
|
|
|
|
NS_WARNING("Failed to DeserializeURI");
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto* actor = static_cast<URLClassifierLocalParent*>(aActor);
|
|
|
|
return actor->StartClassify(uri, aTables);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPURLClassifierLocalParent(PURLClassifierLocalParent* aActor)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aActor);
|
|
|
|
|
|
|
|
RefPtr<URLClassifierLocalParent> actor =
|
|
|
|
dont_AddRef(static_cast<URLClassifierLocalParent*>(aActor));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-12-07 11:32:52 +03:00
|
|
|
PLoginReputationParent*
|
|
|
|
ContentParent::AllocPLoginReputationParent(const URIParams& aURI)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
RefPtr<LoginReputationParent> actor = new LoginReputationParent();
|
|
|
|
return actor.forget().take();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvPLoginReputationConstructor(PLoginReputationParent* aActor,
|
|
|
|
const URIParams& aURI)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aActor);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
|
|
|
if (!uri) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto* actor = static_cast<LoginReputationParent*>(aActor);
|
|
|
|
return actor->QueryReputation(uri);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::DeallocPLoginReputationParent(PLoginReputationParent* aActor)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aActor);
|
|
|
|
|
|
|
|
RefPtr<LoginReputationParent> actor =
|
|
|
|
dont_AddRef(static_cast<LoginReputationParent*>(aActor));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-11-19 00:43:28 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables,
|
2016-11-30 21:57:48 +03:00
|
|
|
nsresult *aRv, nsTArray<nsCString>* aResults)
|
2016-11-19 00:43:28 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(aResults);
|
|
|
|
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
|
|
|
if (!uri) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIURIClassifier> uriClassifier =
|
|
|
|
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID);
|
|
|
|
if (!uriClassifier) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
2016-11-30 21:57:48 +03:00
|
|
|
*aRv = uriClassifier->ClassifyLocalWithTables(uri, aTables, *aResults);
|
2016-11-19 00:43:28 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-02-08 12:19:01 +03:00
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvFileCreationRequest(const nsID& aID,
|
|
|
|
const nsString& aFullPath,
|
|
|
|
const nsString& aType,
|
|
|
|
const nsString& aName,
|
|
|
|
const bool& aLastModifiedPassed,
|
|
|
|
const int64_t& aLastModified,
|
2017-03-03 11:42:54 +03:00
|
|
|
const bool& aExistenceCheck,
|
2017-02-08 12:19:01 +03:00
|
|
|
const bool& aIsFromNsIFile)
|
|
|
|
{
|
2017-03-21 13:11:06 +03:00
|
|
|
// We allow the creation of File via this IPC call only for the 'file' process
|
|
|
|
// or for testing.
|
|
|
|
if (!mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE) &&
|
|
|
|
!Preferences::GetBool("dom.file.createInChild", false)) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
2017-02-08 12:19:01 +03:00
|
|
|
RefPtr<BlobImpl> blobImpl;
|
|
|
|
nsresult rv =
|
|
|
|
FileCreatorHelper::CreateBlobImplForIPC(aFullPath, aType, aName,
|
|
|
|
aLastModifiedPassed,
|
2017-03-03 11:42:54 +03:00
|
|
|
aLastModified, aExistenceCheck,
|
|
|
|
aIsFromNsIFile,
|
2017-02-08 12:19:01 +03:00
|
|
|
getter_AddRefs(blobImpl));
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
if (!SendFileCreationResponse(aID, FileCreationErrorResult(rv))) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(blobImpl);
|
|
|
|
|
2017-04-24 13:16:50 +03:00
|
|
|
IPCBlob ipcBlob;
|
|
|
|
rv = IPCBlobUtils::Serialize(blobImpl, this, ipcBlob);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
if (!SendFileCreationResponse(aID, FileCreationErrorResult(rv))) {
|
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
2017-03-14 13:36:22 +03:00
|
|
|
}
|
|
|
|
|
2017-04-24 13:16:50 +03:00
|
|
|
if (!SendFileCreationResponse(aID, FileCreationSuccessResult(ipcBlob))) {
|
2017-02-08 12:19:01 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-05-29 13:38:46 +03:00
|
|
|
|
|
|
|
bool
|
|
|
|
ContentParent::CanCommunicateWith(ContentParentId aOtherProcess)
|
|
|
|
{
|
|
|
|
// Normally a process can only communicate with its parent, but a JS plugin process can
|
|
|
|
// communicate with any process.
|
|
|
|
ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
|
|
|
|
ContentParentId parentId;
|
|
|
|
if (!cpm->GetParentProcessId(ChildID(), &parentId)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (IsForJSPlugin()) {
|
|
|
|
return parentId == ContentParentId(0);
|
|
|
|
}
|
|
|
|
return parentId == aOtherProcess;
|
|
|
|
}
|
2017-06-06 20:39:46 +03:00
|
|
|
|
2018-07-22 14:52:42 +03:00
|
|
|
nsresult
|
|
|
|
ContentParent::SaveRecording(nsIFile* aFile, bool* aRetval)
|
|
|
|
{
|
|
|
|
if (mRecordReplayState != eRecording) {
|
|
|
|
*aRetval = false;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRFileDesc* prfd;
|
|
|
|
nsresult rv = aFile->OpenNSPRFileDesc(PR_WRONLY | PR_TRUNCATE | PR_CREATE_FILE, 0644, &prfd);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
FileDescriptor::PlatformHandleType handle =
|
|
|
|
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(prfd));
|
|
|
|
|
|
|
|
Unused << SendSaveRecording(FileDescriptor(handle));
|
|
|
|
|
|
|
|
PR_Close(prfd);
|
|
|
|
|
|
|
|
*aRetval = true;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-06-06 20:39:46 +03:00
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvMaybeReloadPlugins()
|
|
|
|
{
|
|
|
|
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
|
|
|
|
pluginHost->ReloadPlugins();
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-06-15 21:34:00 +03:00
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvDeviceReset()
|
|
|
|
{
|
|
|
|
GPUProcessManager* pm = GPUProcessManager::Get();
|
|
|
|
if (pm) {
|
2017-07-11 05:30:52 +03:00
|
|
|
pm->SimulateDeviceReset();
|
2017-06-15 21:34:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2017-07-20 19:49:28 +03:00
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvBHRThreadHang(const HangDetails& aDetails)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
|
|
|
if (obs) {
|
|
|
|
// Copy the HangDetails recieved over the network into a nsIHangDetails, and
|
|
|
|
// then fire our own observer notification.
|
|
|
|
// XXX: We should be able to avoid this potentially expensive copy here by
|
|
|
|
// moving our deserialized argument.
|
|
|
|
nsCOMPtr<nsIHangDetails> hangDetails =
|
|
|
|
new nsHangDetails(HangDetails(aDetails));
|
|
|
|
obs->NotifyObservers(hangDetails, "bhr-thread-hang", nullptr);
|
|
|
|
}
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
2018-07-10 11:09:59 +03:00
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
2018-07-13 13:02:19 +03:00
|
|
|
ContentParent::RecvFirstPartyStorageAccessGrantedForOrigin(const Principal& aParentPrincipal,
|
|
|
|
const nsCString& aTrackingOrigin,
|
2018-07-19 23:19:59 +03:00
|
|
|
const nsCString& aGrantedOrigin,
|
|
|
|
FirstPartyStorageAccessGrantedForOriginResolver&& aResolver)
|
2018-07-10 11:09:59 +03:00
|
|
|
{
|
2018-07-13 13:02:19 +03:00
|
|
|
AntiTrackingCommon::SaveFirstPartyStorageAccessGrantedForOriginOnParentProcess(aParentPrincipal,
|
|
|
|
aTrackingOrigin,
|
2018-07-19 23:19:59 +03:00
|
|
|
aGrantedOrigin,
|
|
|
|
std::move(aResolver));
|
2018-07-10 11:09:59 +03:00
|
|
|
return IPC_OK();
|
|
|
|
}
|
2018-07-26 10:31:00 +03:00
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvAttachBrowsingContext(
|
|
|
|
const BrowsingContextId& aParentId,
|
|
|
|
const BrowsingContextId& aChildId,
|
|
|
|
const nsString& aName)
|
|
|
|
{
|
|
|
|
RefPtr<BrowsingContext> parent = BrowsingContext::Get(aParentId);
|
|
|
|
if (aParentId && !parent) {
|
|
|
|
// Unless 'aParentId' is 0 (which it is when the child is a root
|
|
|
|
// BrowsingContext) there should always be a corresponding
|
|
|
|
// 'parent'. The only reason for there not beeing one is if the
|
|
|
|
// parent has already been detached, in which case the
|
|
|
|
// BrowsingContext that tries to attach itself to the context with
|
|
|
|
// 'aParentId' is surely doomed and we can safely do nothing.
|
|
|
|
|
|
|
|
// TODO(farre): When we start syncing/moving BrowsingContexts to
|
|
|
|
// other child processes is it possible to get into races where
|
|
|
|
// constructive operations on already detached BrowsingContexts
|
|
|
|
// are requested? This needs to be answered/handled, but for now
|
|
|
|
// return early. [Bug 1471598]
|
|
|
|
MOZ_LOG(
|
|
|
|
BrowsingContext::GetLog(),
|
|
|
|
LogLevel::Debug,
|
|
|
|
("ParentIPC: Trying to attach to already detached parent 0x%08" PRIx64,
|
|
|
|
(uint64_t)aParentId));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parent && parent->OwnerProcessId() != ChildID()) {
|
|
|
|
// Where trying attach a child BrowsingContext to a parent
|
|
|
|
// BrowsingContext in another process. This is illegal since the
|
|
|
|
// only thing that could create that child BrowsingContext is a
|
|
|
|
// parent docshell in the same process as that BrowsingContext.
|
|
|
|
|
|
|
|
// TODO(farre): We're doing nothing now, but is that exactly what
|
|
|
|
// we want? Maybe we want to crash the child currently calling
|
|
|
|
// SendAttachBrowsingContext and/or the child that originally
|
|
|
|
// called SendAttachBrowsingContext or possibly all children that
|
|
|
|
// has a BrowsingContext connected to the child that currently
|
|
|
|
// called SendAttachBrowsingContext? [Bug 1471598]
|
|
|
|
MOZ_LOG(BrowsingContext::GetLog(),
|
|
|
|
LogLevel::Warning,
|
|
|
|
("ParentIPC: Trying to attach to out of process parent context "
|
|
|
|
"0x%08" PRIx64,
|
|
|
|
parent->Id()));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<BrowsingContext> child = BrowsingContext::Get(aChildId);
|
2018-06-28 05:40:00 +03:00
|
|
|
if (child && !child->IsCached()) {
|
2018-07-26 10:31:00 +03:00
|
|
|
// This is highly suspicious. BrowsingContexts should only be
|
|
|
|
// attached at most once, but finding one indicates that someone
|
|
|
|
// is doing something they shouldn't.
|
|
|
|
|
|
|
|
// TODO(farre): To crash or not to crash. Same reasoning as in
|
|
|
|
// above TODO. [Bug 1471598]
|
|
|
|
MOZ_LOG(BrowsingContext::GetLog(),
|
|
|
|
LogLevel::Warning,
|
|
|
|
("ParentIPC: Trying to attach already attached 0x%08" PRIx64
|
|
|
|
" to 0x%08" PRIx64,
|
|
|
|
child->Id(),
|
|
|
|
(uint64_t)aParentId));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!child) {
|
|
|
|
child = new BrowsingContext(aChildId, aName, Some(ChildID()));
|
|
|
|
}
|
|
|
|
child->Attach(parent);
|
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::ipc::IPCResult
|
|
|
|
ContentParent::RecvDetachBrowsingContext(const BrowsingContextId& aContextId,
|
|
|
|
const bool& aMoveToBFCache)
|
|
|
|
{
|
|
|
|
RefPtr<BrowsingContext> context = BrowsingContext::Get(aContextId);
|
|
|
|
|
|
|
|
if (!context) {
|
|
|
|
MOZ_LOG(BrowsingContext::GetLog(),
|
|
|
|
LogLevel::Debug,
|
|
|
|
("ParentIPC: Trying to detach already detached 0x%08" PRIx64,
|
|
|
|
(uint64_t)aContextId));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (context->OwnerProcessId() != ChildID()) {
|
|
|
|
// Where trying to detach a child BrowsingContext in another child
|
|
|
|
// process. This is illegal since the owner of the BrowsingContext
|
|
|
|
// is the proccess with the in-process docshell, which is tracked
|
|
|
|
// by OwnerProcessId.
|
|
|
|
|
|
|
|
// TODO(farre): To crash or not to crash. Same reasoning as in
|
|
|
|
// above TODO. [Bug 1471598]
|
|
|
|
MOZ_LOG(BrowsingContext::GetLog(),
|
|
|
|
LogLevel::Warning,
|
|
|
|
("ParentIPC: Trying to detach out of process context 0x%08" PRIx64,
|
|
|
|
context->Id()));
|
|
|
|
return IPC_OK();
|
|
|
|
}
|
|
|
|
|
2018-06-28 05:40:00 +03:00
|
|
|
if (aMoveToBFCache) {
|
|
|
|
context->CacheChildren();
|
|
|
|
} else {
|
|
|
|
context->Detach();
|
|
|
|
}
|
2018-07-26 10:31:00 +03:00
|
|
|
|
|
|
|
return IPC_OK();
|
|
|
|
}
|