1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set sw=4 ts=8 et tw=80 : */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is Mozilla Content App.
18 * The Initial Developer of the Original Code is
19 * The Mozilla Foundation.
20 * Portions created by the Initial Developer are Copyright (C) 2009
21 * the Initial Developer. All Rights Reserved.
24 * Frederic Plourde <frederic.plourde@collabora.co.uk>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #ifdef MOZ_WIDGET_GTK2
45 #include "nsQAppInstance.h"
48 #include "ContentChild.h"
49 #include "CrashReporterChild.h"
51 #include "AudioChild.h"
53 #include "mozilla/ipc/TestShellChild.h"
54 #include "mozilla/net/NeckoChild.h"
55 #include "mozilla/ipc/XPCShellEnvironment.h"
56 #include "mozilla/jsipc/PContextWrapperChild.h"
57 #include "mozilla/dom/ExternalHelperAppChild.h"
58 #include "mozilla/dom/StorageChild.h"
59 #include "mozilla/dom/PCrashReporterChild.h"
61 #include "nsAudioStream.h"
63 #include "nsIObserverService.h"
64 #include "nsTObserverArray.h"
65 #include "nsIObserver.h"
66 #include "nsIPrefService.h"
67 #include "nsServiceManagerUtils.h"
68 #include "nsXULAppAPI.h"
69 #include "nsWeakReference.h"
70 #include "nsIScriptError.h"
71 #include "nsIConsoleService.h"
74 #include "nsDocShellCID.h"
75 #include "nsNetUtil.h"
77 #include "base/message_loop.h"
78 #include "base/task.h"
80 #include "nsChromeRegistryContent.h"
81 #include "mozilla/chrome/RegistryMessageUtils.h"
82 #include "nsFrameMessageManager.h"
84 #include "nsIGeolocationProvider.h"
86 #ifdef MOZ_PERMISSIONS
87 #include "nsPermission.h"
88 #include "nsPermissionManager.h"
91 #include "nsAccelerometer.h"
97 using namespace mozilla::ipc
;
98 using namespace mozilla::net
;
99 using namespace mozilla::places
;
100 using namespace mozilla::docshell
;
108 AlertObserver(nsIObserver
*aObserver
, const nsString
& aData
)
109 : mObserver(aObserver
)
116 bool ShouldRemoveFrom(nsIObserver
* aObserver
,
117 const nsString
& aData
) const
119 return (mObserver
== aObserver
&&
123 bool Observes(const nsString
& aData
) const
125 return mData
.Equals(aData
);
128 bool Notify(const nsCString
& aType
) const
130 mObserver
->Observe(nsnull
, aType
.get(), mData
.get());
135 nsCOMPtr
<nsIObserver
> mObserver
;
139 class ConsoleListener
: public nsIConsoleListener
142 ConsoleListener(ContentChild
* aChild
)
146 NS_DECL_NSICONSOLELISTENER
149 ContentChild
* mChild
;
150 friend class ContentChild
;
153 NS_IMPL_ISUPPORTS1(ConsoleListener
, nsIConsoleListener
)
156 ConsoleListener::Observe(nsIConsoleMessage
* aMessage
)
161 nsCOMPtr
<nsIScriptError
> scriptError
= do_QueryInterface(aMessage
);
163 nsString msg
, sourceName
, sourceLine
;
164 nsXPIDLCString category
;
165 PRUint32 lineNum
, colNum
, flags
;
167 nsresult rv
= scriptError
->GetErrorMessage(msg
);
168 NS_ENSURE_SUCCESS(rv
, rv
);
169 rv
= scriptError
->GetSourceName(sourceName
);
170 NS_ENSURE_SUCCESS(rv
, rv
);
171 rv
= scriptError
->GetSourceLine(sourceLine
);
172 NS_ENSURE_SUCCESS(rv
, rv
);
173 rv
= scriptError
->GetCategory(getter_Copies(category
));
174 NS_ENSURE_SUCCESS(rv
, rv
);
175 rv
= scriptError
->GetLineNumber(&lineNum
);
176 NS_ENSURE_SUCCESS(rv
, rv
);
177 rv
= scriptError
->GetColumnNumber(&colNum
);
178 NS_ENSURE_SUCCESS(rv
, rv
);
179 rv
= scriptError
->GetFlags(&flags
);
180 NS_ENSURE_SUCCESS(rv
, rv
);
181 mChild
->SendScriptError(msg
, sourceName
, sourceLine
,
182 lineNum
, colNum
, flags
, category
);
187 nsresult rv
= aMessage
->GetMessageMoz(getter_Copies(msg
));
188 NS_ENSURE_SUCCESS(rv
, rv
);
189 mChild
->SendConsoleMessage(msg
);
193 ContentChild
* ContentChild::sSingleton
;
195 ContentChild::ContentChild()
202 ContentChild::~ContentChild()
207 ContentChild::Init(MessageLoop
* aIOLoop
,
208 base::ProcessHandle aParentHandle
,
209 IPC::Channel
* aChannel
)
211 #ifdef MOZ_WIDGET_GTK2
213 gtk_init(NULL
, NULL
);
218 nsQAppInstance::AddRef();
222 // Do this after initializing GDK, or GDK will install its own handler.
223 XRE_InstallX11ErrorHandler();
226 NS_ASSERTION(!sSingleton
, "only one ContentChild per child");
228 Open(aChannel
, aParentHandle
, aIOLoop
);
232 PCrashReporterChild
* crashreporter
= SendPCrashReporterConstructor();
233 InfallibleTArray
<Mapping
> mappings
;
234 const struct mapping_info
*info
= getLibraryMapping();
236 mappings
.AppendElement(Mapping(nsDependentCString(info
->name
),
237 nsDependentCString(info
->file_id
),
243 crashreporter
->SendAddLibraryMappings(mappings
);
250 ContentChild::InitXPCOM()
252 nsCOMPtr
<nsIConsoleService
> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID
));
254 NS_WARNING("Couldn't acquire console service");
258 mConsoleListener
= new ConsoleListener(this);
259 if (NS_FAILED(svc
->RegisterListener(mConsoleListener
)))
260 NS_WARNING("Couldn't register console listener for child process");
264 ContentChild::AllocPBrowser(const PRUint32
& aChromeFlags
)
266 nsRefPtr
<TabChild
> iframe
= new TabChild(aChromeFlags
);
267 return NS_SUCCEEDED(iframe
->Init()) ? iframe
.forget().get() : NULL
;
271 ContentChild::DeallocPBrowser(PBrowserChild
* iframe
)
273 TabChild
* child
= static_cast<TabChild
*>(iframe
);
279 ContentChild::AllocPCrashReporter()
281 return new CrashReporterChild();
285 ContentChild::DeallocPCrashReporter(PCrashReporterChild
* crashreporter
)
287 delete crashreporter
;
292 ContentChild::AllocPTestShell()
294 return new TestShellChild();
298 ContentChild::DeallocPTestShell(PTestShellChild
* shell
)
305 ContentChild::RecvPTestShellConstructor(PTestShellChild
* actor
)
307 actor
->SendPContextWrapperConstructor()->SendPObjectWrapperConstructor(true);
312 ContentChild::AllocPAudio(const PRInt32
& numChannels
,
314 const PRInt32
& format
)
316 AudioChild
*child
= new AudioChild();
322 ContentChild::DeallocPAudio(PAudioChild
* doomed
)
324 AudioChild
*child
= static_cast<AudioChild
*>(doomed
);
330 ContentChild::AllocPNecko()
332 return new NeckoChild();
336 ContentChild::DeallocPNecko(PNeckoChild
* necko
)
342 PExternalHelperAppChild
*
343 ContentChild::AllocPExternalHelperApp(const IPC::URI
& uri
,
344 const nsCString
& aMimeContentType
,
345 const nsCString
& aContentDisposition
,
346 const bool& aForceSave
,
347 const PRInt64
& aContentLength
,
348 const IPC::URI
& aReferrer
)
350 ExternalHelperAppChild
*child
= new ExternalHelperAppChild();
356 ContentChild::DeallocPExternalHelperApp(PExternalHelperAppChild
* aService
)
358 ExternalHelperAppChild
*child
= static_cast<ExternalHelperAppChild
*>(aService
);
364 ContentChild::AllocPStorage(const StorageConstructData
& aData
)
366 NS_NOTREACHED("We should never be manually allocating PStorageChild actors");
371 ContentChild::DeallocPStorage(PStorageChild
* aActor
)
373 StorageChild
* child
= static_cast<StorageChild
*>(aActor
);
374 child
->ReleaseIPDLReference();
379 ContentChild::RecvRegisterChrome(const InfallibleTArray
<ChromePackage
>& packages
,
380 const InfallibleTArray
<ResourceMapping
>& resources
,
381 const InfallibleTArray
<OverrideMapping
>& overrides
,
382 const nsCString
& locale
)
384 nsCOMPtr
<nsIChromeRegistry
> registrySvc
= nsChromeRegistry::GetService();
385 nsChromeRegistryContent
* chromeRegistry
=
386 static_cast<nsChromeRegistryContent
*>(registrySvc
.get());
387 chromeRegistry
->RegisterRemoteChrome(packages
, resources
, overrides
, locale
);
392 ContentChild::RecvSetOffline(const PRBool
& offline
)
394 nsCOMPtr
<nsIIOService
> io (do_GetIOService());
395 NS_ASSERTION(io
, "IO Service can not be null");
397 io
->SetOffline(offline
);
403 ContentChild::ActorDestroy(ActorDestroyReason why
)
405 if (AbnormalShutdown
== why
) {
406 NS_WARNING("shutting down early because of crash!");
411 // In release builds, there's no point in the content process
412 // going through the full XPCOM shutdown path, because it doesn't
413 // keep persistent state.
417 mAlertObservers
.Clear();
419 nsCOMPtr
<nsIConsoleService
> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID
));
421 svc
->UnregisterListener(mConsoleListener
);
422 mConsoleListener
->mChild
= nsnull
;
425 XRE_ShutdownChildProcess();
429 ContentChild::ProcessingError(Result what
)
437 case MsgPayloadError
:
438 case MsgProcessingError
:
441 NS_RUNTIMEABORT("aborting because of fatal error");
444 NS_RUNTIMEABORT("not reached");
449 ContentChild::QuickExit()
451 NS_WARNING("content process _exit()ing");
456 ContentChild::AddRemoteAlertObserver(const nsString
& aData
,
457 nsIObserver
* aObserver
)
459 NS_ASSERTION(aObserver
, "Adding a null observer?");
460 mAlertObservers
.AppendElement(new AlertObserver(aObserver
, aData
));
465 ContentChild::RecvPreferenceUpdate(const PrefTuple
& aPref
)
467 nsCOMPtr
<nsIPrefServiceInternal
> prefs
= do_GetService("@mozilla.org/preferences-service;1");
471 prefs
->SetPreference(&aPref
);
477 ContentChild::RecvClearUserPreference(const nsCString
& aPrefName
)
479 nsCOMPtr
<nsIPrefServiceInternal
> prefs
= do_GetService("@mozilla.org/preferences-service;1");
483 prefs
->ClearContentPref(aPrefName
);
489 ContentChild::RecvNotifyAlertsObserver(const nsCString
& aType
, const nsString
& aData
)
491 for (PRUint32 i
= 0; i
< mAlertObservers
.Length();
492 /*we mutate the array during the loop; ++i iff no mutation*/) {
493 AlertObserver
* observer
= mAlertObservers
[i
];
494 if (observer
->Observes(aData
) && observer
->Notify(aType
)) {
495 // if aType == alertfinished, this alert is done. we can
496 // remove the observer.
497 if (aType
.Equals(nsDependentCString("alertfinished"))) {
498 mAlertObservers
.RemoveElementAt(i
);
508 ContentChild::RecvNotifyVisited(const IPC::URI
& aURI
)
510 nsCOMPtr
<nsIURI
> newURI(aURI
);
511 History::GetService()->NotifyVisited(newURI
);
517 ContentChild::RecvAsyncMessage(const nsString
& aMsg
, const nsString
& aJSON
)
519 nsRefPtr
<nsFrameMessageManager
> cpm
= nsFrameMessageManager::sChildProcessManager
;
521 cpm
->ReceiveMessage(static_cast<nsIContentFrameMessageManager
*>(cpm
.get()),
522 aMsg
, PR_FALSE
, aJSON
, nsnull
, nsnull
);
528 ContentChild::RecvGeolocationUpdate(const GeoPosition
& somewhere
)
530 nsCOMPtr
<nsIGeolocationUpdate
> gs
= do_GetService("@mozilla.org/geolocation/service;1");
534 nsCOMPtr
<nsIDOMGeoPosition
> position
= somewhere
;
535 gs
->Update(position
);
540 ContentChild::RecvAddPermission(const IPC::Permission
& permission
)
543 nsRefPtr
<nsPermissionManager
> permissionManager
=
544 nsPermissionManager::GetSingleton();
545 NS_ABORT_IF_FALSE(permissionManager
,
546 "We have no permissionManager in the Content process !");
548 permissionManager
->AddInternal(nsCString(permission
.host
),
549 nsCString(permission
.type
),
550 permission
.capability
,
552 permission
.expireType
,
553 permission
.expireTime
,
554 nsPermissionManager::eNotify
,
555 nsPermissionManager::eNoDBOperation
);
561 ContentChild::RecvAccelerationChanged(const double& x
, const double& y
,
564 nsCOMPtr
<nsIAccelerometerUpdate
> acu
=
565 do_GetService(NS_ACCELEROMETER_CONTRACTID
);
567 acu
->AccelerationChanged(x
, y
, z
);
572 ContentChild::RecvScreenSizeChanged(const gfxIntSize
& size
)
577 NS_RUNTIMEABORT("Message currently only expected on android");
583 ContentChild::RecvFlushMemory(const nsString
& reason
)
585 nsCOMPtr
<nsIObserverService
> os
=
586 mozilla::services::GetObserverService();
588 os
->NotifyObservers(nsnull
, "memory-pressure", reason
.get());
593 } // namespace mozilla