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
5 : *
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/
10 : *
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
14 : * License.
15 : *
16 : * The Original Code is Mozilla Content App.
17 : *
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.
22 : *
23 : * Contributor(s):
24 : * Frederic Plourde <frederic.plourde@collabora.co.uk>
25 : *
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.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifdef MOZ_WIDGET_GTK2
41 : #include <gtk/gtk.h>
42 : #endif
43 :
44 : #ifdef MOZ_WIDGET_QT
45 : #include "nsQAppInstance.h"
46 : #endif
47 :
48 : #include "ContentChild.h"
49 : #include "CrashReporterChild.h"
50 : #include "TabChild.h"
51 : #if defined(MOZ_SYDNEYAUDIO)
52 : #include "AudioChild.h"
53 : #endif
54 :
55 : #include "mozilla/dom/ExternalHelperAppChild.h"
56 : #include "mozilla/dom/PCrashReporterChild.h"
57 : #include "mozilla/dom/StorageChild.h"
58 : #include "mozilla/hal_sandbox/PHalChild.h"
59 : #include "mozilla/ipc/TestShellChild.h"
60 : #include "mozilla/ipc/XPCShellEnvironment.h"
61 : #include "mozilla/jsipc/PContextWrapperChild.h"
62 : #include "mozilla/net/NeckoChild.h"
63 : #include "mozilla/Preferences.h"
64 :
65 : #if defined(MOZ_SYDNEYAUDIO)
66 : #include "nsAudioStream.h"
67 : #endif
68 : #include "nsIMemoryReporter.h"
69 : #include "nsIObserverService.h"
70 : #include "nsTObserverArray.h"
71 : #include "nsIObserver.h"
72 : #include "nsServiceManagerUtils.h"
73 : #include "nsXULAppAPI.h"
74 : #include "nsWeakReference.h"
75 : #include "nsIScriptError.h"
76 : #include "nsIConsoleService.h"
77 : #include "nsJSEnvironment.h"
78 : #include "SandboxHal.h"
79 :
80 : #include "History.h"
81 : #include "nsDocShellCID.h"
82 : #include "nsNetUtil.h"
83 :
84 : #include "base/message_loop.h"
85 : #include "base/task.h"
86 :
87 : #include "nsChromeRegistryContent.h"
88 : #include "mozilla/chrome/RegistryMessageUtils.h"
89 : #include "nsFrameMessageManager.h"
90 :
91 : #include "nsIGeolocationProvider.h"
92 : #include "mozilla/dom/PMemoryReportRequestChild.h"
93 :
94 : #ifdef MOZ_PERMISSIONS
95 : #include "nsPermission.h"
96 : #include "nsPermissionManager.h"
97 : #endif
98 :
99 : #include "nsDeviceMotion.h"
100 :
101 : #if defined(MOZ_WIDGET_ANDROID)
102 : #include "APKOpen.h"
103 : #endif
104 :
105 : #ifdef XP_WIN
106 : #include <process.h>
107 : #define getpid _getpid
108 : #endif
109 :
110 : #ifdef ACCESSIBILITY
111 : #include "nsIAccessibilityService.h"
112 : #endif
113 :
114 : #include "mozilla/dom/sms/SmsChild.h"
115 :
116 : using namespace mozilla::hal_sandbox;
117 : using namespace mozilla::ipc;
118 : using namespace mozilla::net;
119 : using namespace mozilla::places;
120 : using namespace mozilla::docshell;
121 : using namespace mozilla::dom::sms;
122 :
123 : namespace mozilla {
124 : namespace dom {
125 :
126 : nsString* gIndexedDBPath = nsnull;
127 :
128 : class MemoryReportRequestChild : public PMemoryReportRequestChild
129 : {
130 : public:
131 : MemoryReportRequestChild();
132 : virtual ~MemoryReportRequestChild();
133 : };
134 :
135 0 : MemoryReportRequestChild::MemoryReportRequestChild()
136 : {
137 0 : MOZ_COUNT_CTOR(MemoryReportRequestChild);
138 0 : }
139 :
140 0 : MemoryReportRequestChild::~MemoryReportRequestChild()
141 : {
142 0 : MOZ_COUNT_DTOR(MemoryReportRequestChild);
143 0 : }
144 :
145 : class AlertObserver
146 : {
147 : public:
148 :
149 0 : AlertObserver(nsIObserver *aObserver, const nsString& aData)
150 : : mObserver(aObserver)
151 0 : , mData(aData)
152 : {
153 0 : }
154 :
155 0 : ~AlertObserver() {}
156 :
157 : bool ShouldRemoveFrom(nsIObserver* aObserver,
158 : const nsString& aData) const
159 : {
160 : return (mObserver == aObserver &&
161 : mData == aData);
162 : }
163 :
164 0 : bool Observes(const nsString& aData) const
165 : {
166 0 : return mData.Equals(aData);
167 : }
168 :
169 0 : bool Notify(const nsCString& aType) const
170 : {
171 0 : mObserver->Observe(nsnull, aType.get(), mData.get());
172 0 : return true;
173 : }
174 :
175 : private:
176 : nsCOMPtr<nsIObserver> mObserver;
177 : nsString mData;
178 : };
179 :
180 : class ConsoleListener : public nsIConsoleListener
181 : {
182 : public:
183 0 : ConsoleListener(ContentChild* aChild)
184 0 : : mChild(aChild) {}
185 :
186 : NS_DECL_ISUPPORTS
187 : NS_DECL_NSICONSOLELISTENER
188 :
189 : private:
190 : ContentChild* mChild;
191 : friend class ContentChild;
192 : };
193 :
194 0 : NS_IMPL_ISUPPORTS1(ConsoleListener, nsIConsoleListener)
195 :
196 : NS_IMETHODIMP
197 0 : ConsoleListener::Observe(nsIConsoleMessage* aMessage)
198 : {
199 0 : if (!mChild)
200 0 : return NS_OK;
201 :
202 0 : nsCOMPtr<nsIScriptError> scriptError = do_QueryInterface(aMessage);
203 0 : if (scriptError) {
204 0 : nsString msg, sourceName, sourceLine;
205 0 : nsXPIDLCString category;
206 : PRUint32 lineNum, colNum, flags;
207 :
208 0 : nsresult rv = scriptError->GetErrorMessage(msg);
209 0 : NS_ENSURE_SUCCESS(rv, rv);
210 0 : rv = scriptError->GetSourceName(sourceName);
211 0 : NS_ENSURE_SUCCESS(rv, rv);
212 0 : rv = scriptError->GetSourceLine(sourceLine);
213 0 : NS_ENSURE_SUCCESS(rv, rv);
214 0 : rv = scriptError->GetCategory(getter_Copies(category));
215 0 : NS_ENSURE_SUCCESS(rv, rv);
216 0 : rv = scriptError->GetLineNumber(&lineNum);
217 0 : NS_ENSURE_SUCCESS(rv, rv);
218 0 : rv = scriptError->GetColumnNumber(&colNum);
219 0 : NS_ENSURE_SUCCESS(rv, rv);
220 0 : rv = scriptError->GetFlags(&flags);
221 0 : NS_ENSURE_SUCCESS(rv, rv);
222 : mChild->SendScriptError(msg, sourceName, sourceLine,
223 0 : lineNum, colNum, flags, category);
224 0 : return NS_OK;
225 : }
226 :
227 0 : nsXPIDLString msg;
228 0 : nsresult rv = aMessage->GetMessageMoz(getter_Copies(msg));
229 0 : NS_ENSURE_SUCCESS(rv, rv);
230 0 : mChild->SendConsoleMessage(msg);
231 0 : return NS_OK;
232 : }
233 :
234 : ContentChild* ContentChild::sSingleton;
235 :
236 1 : ContentChild::ContentChild()
237 : #ifdef ANDROID
238 : : mScreenSize(0, 0)
239 : , mID(PRUint64(-1))
240 : #endif
241 : {
242 1 : }
243 :
244 0 : ContentChild::~ContentChild()
245 : {
246 0 : delete gIndexedDBPath;
247 0 : gIndexedDBPath = nsnull;
248 0 : }
249 :
250 : bool
251 1 : ContentChild::Init(MessageLoop* aIOLoop,
252 : base::ProcessHandle aParentHandle,
253 : IPC::Channel* aChannel)
254 : {
255 : #ifdef MOZ_WIDGET_GTK2
256 : // sigh
257 1 : gtk_init(NULL, NULL);
258 : #endif
259 :
260 : #ifdef MOZ_WIDGET_QT
261 : // sigh, seriously
262 : nsQAppInstance::AddRef();
263 : #endif
264 :
265 : #ifdef MOZ_X11
266 : // Do this after initializing GDK, or GDK will install its own handler.
267 0 : XRE_InstallX11ErrorHandler();
268 : #endif
269 :
270 0 : NS_ASSERTION(!sSingleton, "only one ContentChild per child");
271 :
272 0 : Open(aChannel, aParentHandle, aIOLoop);
273 0 : sSingleton = this;
274 :
275 : #ifdef MOZ_CRASHREPORTER
276 0 : SendPCrashReporterConstructor(CrashReporter::CurrentThreadId(),
277 0 : XRE_GetProcessType());
278 : #if defined(MOZ_WIDGET_ANDROID)
279 : PCrashReporterChild* crashreporter = ManagedPCrashReporterChild()[0];
280 :
281 : InfallibleTArray<Mapping> mappings;
282 : const struct mapping_info *info = getLibraryMapping();
283 : while (info && info->name) {
284 : mappings.AppendElement(Mapping(nsDependentCString(info->name),
285 : nsDependentCString(info->file_id),
286 : info->base,
287 : info->len,
288 : info->offset));
289 : info++;
290 : }
291 : crashreporter->SendAddLibraryMappings(mappings);
292 : #endif
293 : #endif
294 :
295 0 : return true;
296 : }
297 :
298 : void
299 0 : ContentChild::InitXPCOM()
300 : {
301 0 : nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
302 0 : if (!svc) {
303 0 : NS_WARNING("Couldn't acquire console service");
304 : return;
305 : }
306 :
307 0 : mConsoleListener = new ConsoleListener(this);
308 0 : if (NS_FAILED(svc->RegisterListener(mConsoleListener)))
309 0 : NS_WARNING("Couldn't register console listener for child process");
310 : }
311 :
312 : PMemoryReportRequestChild*
313 0 : ContentChild::AllocPMemoryReportRequest()
314 : {
315 0 : return new MemoryReportRequestChild();
316 : }
317 :
318 : // This is just a wrapper for InfallibleTArray<MemoryReport> that implements
319 : // nsISupports, so it can be passed to nsIMemoryMultiReporter::CollectReports.
320 : class MemoryReportsWrapper : public nsISupports {
321 : public:
322 : NS_DECL_ISUPPORTS
323 0 : MemoryReportsWrapper(InfallibleTArray<MemoryReport> *r) : mReports(r) { }
324 : InfallibleTArray<MemoryReport> *mReports;
325 : };
326 0 : NS_IMPL_ISUPPORTS0(MemoryReportsWrapper)
327 :
328 : class MemoryReportCallback : public nsIMemoryMultiReporterCallback
329 0 : {
330 : public:
331 : NS_DECL_ISUPPORTS
332 :
333 0 : MemoryReportCallback(const nsACString &aProcess)
334 0 : : mProcess(aProcess)
335 : {
336 0 : }
337 :
338 0 : NS_IMETHOD Callback(const nsACString &aProcess, const nsACString &aPath,
339 : PRInt32 aKind, PRInt32 aUnits, PRInt64 aAmount,
340 : const nsACString &aDescription,
341 : nsISupports *aiWrappedReports)
342 : {
343 : MemoryReportsWrapper *wrappedReports =
344 0 : static_cast<MemoryReportsWrapper *>(aiWrappedReports);
345 :
346 0 : MemoryReport memreport(mProcess, nsCString(aPath), aKind, aUnits,
347 0 : aAmount, nsCString(aDescription));
348 0 : wrappedReports->mReports->AppendElement(memreport);
349 0 : return NS_OK;
350 : }
351 : private:
352 : const nsCString mProcess;
353 : };
354 0 : NS_IMPL_ISUPPORTS1(
355 : MemoryReportCallback
356 : , nsIMemoryMultiReporterCallback
357 : )
358 :
359 : bool
360 0 : ContentChild::RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* child)
361 : {
362 :
363 0 : nsCOMPtr<nsIMemoryReporterManager> mgr = do_GetService("@mozilla.org/memory-reporter-manager;1");
364 :
365 0 : InfallibleTArray<MemoryReport> reports;
366 :
367 : static const int maxLength = 31; // big enough; pid is only a few chars
368 0 : nsPrintfCString process(maxLength, "Content (%d)", getpid());
369 :
370 : // First do the vanilla memory reporters.
371 0 : nsCOMPtr<nsISimpleEnumerator> e;
372 0 : mgr->EnumerateReporters(getter_AddRefs(e));
373 : bool more;
374 0 : while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
375 0 : nsCOMPtr<nsIMemoryReporter> r;
376 0 : e->GetNext(getter_AddRefs(r));
377 :
378 0 : nsCString path;
379 : PRInt32 kind;
380 : PRInt32 units;
381 : PRInt64 amount;
382 0 : nsCString desc;
383 0 : r->GetPath(path);
384 0 : r->GetKind(&kind);
385 0 : r->GetUnits(&units);
386 0 : r->GetAmount(&amount);
387 0 : r->GetDescription(desc);
388 :
389 0 : MemoryReport memreport(process, path, kind, units, amount, desc);
390 0 : reports.AppendElement(memreport);
391 : }
392 :
393 : // Then do the memory multi-reporters, by calling CollectReports on each
394 : // one, whereupon the callback will turn each measurement into a
395 : // MemoryReport.
396 0 : mgr->EnumerateMultiReporters(getter_AddRefs(e));
397 : nsRefPtr<MemoryReportsWrapper> wrappedReports =
398 0 : new MemoryReportsWrapper(&reports);
399 0 : nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process);
400 0 : while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
401 0 : nsCOMPtr<nsIMemoryMultiReporter> r;
402 0 : e->GetNext(getter_AddRefs(r));
403 0 : r->CollectReports(cb, wrappedReports);
404 : }
405 :
406 0 : child->Send__delete__(child, reports);
407 0 : return true;
408 : }
409 :
410 : bool
411 0 : ContentChild::DeallocPMemoryReportRequest(PMemoryReportRequestChild* actor)
412 : {
413 0 : delete actor;
414 0 : return true;
415 : }
416 :
417 : PBrowserChild*
418 0 : ContentChild::AllocPBrowser(const PRUint32& aChromeFlags)
419 : {
420 0 : nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags);
421 0 : return NS_SUCCEEDED(iframe->Init()) ? iframe.forget().get() : NULL;
422 : }
423 :
424 : bool
425 0 : ContentChild::DeallocPBrowser(PBrowserChild* iframe)
426 : {
427 0 : TabChild* child = static_cast<TabChild*>(iframe);
428 0 : NS_RELEASE(child);
429 0 : return true;
430 : }
431 :
432 : PCrashReporterChild*
433 0 : ContentChild::AllocPCrashReporter(const mozilla::dom::NativeThreadId& id,
434 : const PRUint32& processType)
435 : {
436 : #ifdef MOZ_CRASHREPORTER
437 0 : return new CrashReporterChild();
438 : #else
439 : return nsnull;
440 : #endif
441 : }
442 :
443 : bool
444 0 : ContentChild::DeallocPCrashReporter(PCrashReporterChild* crashreporter)
445 : {
446 0 : delete crashreporter;
447 0 : return true;
448 : }
449 :
450 : PHalChild*
451 0 : ContentChild::AllocPHal()
452 : {
453 0 : return CreateHalChild();
454 : }
455 :
456 : bool
457 0 : ContentChild::DeallocPHal(PHalChild* aHal)
458 : {
459 0 : delete aHal;
460 0 : return true;
461 : }
462 :
463 : PTestShellChild*
464 0 : ContentChild::AllocPTestShell()
465 : {
466 0 : return new TestShellChild();
467 : }
468 :
469 : bool
470 0 : ContentChild::DeallocPTestShell(PTestShellChild* shell)
471 : {
472 0 : delete shell;
473 0 : return true;
474 : }
475 :
476 : bool
477 0 : ContentChild::RecvPTestShellConstructor(PTestShellChild* actor)
478 : {
479 0 : actor->SendPContextWrapperConstructor()->SendPObjectWrapperConstructor(true);
480 0 : return true;
481 : }
482 :
483 : PAudioChild*
484 0 : ContentChild::AllocPAudio(const PRInt32& numChannels,
485 : const PRInt32& rate,
486 : const PRInt32& format)
487 : {
488 : #if defined(MOZ_SYDNEYAUDIO)
489 0 : AudioChild *child = new AudioChild();
490 0 : NS_ADDREF(child);
491 0 : return child;
492 : #else
493 : return nsnull;
494 : #endif
495 : }
496 :
497 : bool
498 0 : ContentChild::DeallocPAudio(PAudioChild* doomed)
499 : {
500 : #if defined(MOZ_SYDNEYAUDIO)
501 0 : AudioChild *child = static_cast<AudioChild*>(doomed);
502 0 : NS_RELEASE(child);
503 : #endif
504 0 : return true;
505 : }
506 :
507 : PNeckoChild*
508 0 : ContentChild::AllocPNecko()
509 : {
510 0 : return new NeckoChild();
511 : }
512 :
513 : bool
514 0 : ContentChild::DeallocPNecko(PNeckoChild* necko)
515 : {
516 0 : delete necko;
517 0 : return true;
518 : }
519 :
520 : PExternalHelperAppChild*
521 0 : ContentChild::AllocPExternalHelperApp(const IPC::URI& uri,
522 : const nsCString& aMimeContentType,
523 : const nsCString& aContentDisposition,
524 : const bool& aForceSave,
525 : const PRInt64& aContentLength,
526 : const IPC::URI& aReferrer)
527 : {
528 0 : ExternalHelperAppChild *child = new ExternalHelperAppChild();
529 0 : child->AddRef();
530 0 : return child;
531 : }
532 :
533 : bool
534 0 : ContentChild::DeallocPExternalHelperApp(PExternalHelperAppChild* aService)
535 : {
536 0 : ExternalHelperAppChild *child = static_cast<ExternalHelperAppChild*>(aService);
537 0 : child->Release();
538 0 : return true;
539 : }
540 :
541 : PSmsChild*
542 0 : ContentChild::AllocPSms()
543 : {
544 0 : return new SmsChild();
545 : }
546 :
547 : bool
548 0 : ContentChild::DeallocPSms(PSmsChild* aSms)
549 : {
550 0 : delete aSms;
551 0 : return true;
552 : }
553 :
554 : PStorageChild*
555 0 : ContentChild::AllocPStorage(const StorageConstructData& aData)
556 : {
557 0 : NS_NOTREACHED("We should never be manually allocating PStorageChild actors");
558 0 : return nsnull;
559 : }
560 :
561 : bool
562 0 : ContentChild::DeallocPStorage(PStorageChild* aActor)
563 : {
564 0 : StorageChild* child = static_cast<StorageChild*>(aActor);
565 0 : child->ReleaseIPDLReference();
566 0 : return true;
567 : }
568 :
569 : bool
570 0 : ContentChild::RecvRegisterChrome(const InfallibleTArray<ChromePackage>& packages,
571 : const InfallibleTArray<ResourceMapping>& resources,
572 : const InfallibleTArray<OverrideMapping>& overrides,
573 : const nsCString& locale)
574 : {
575 0 : nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
576 : nsChromeRegistryContent* chromeRegistry =
577 0 : static_cast<nsChromeRegistryContent*>(registrySvc.get());
578 0 : chromeRegistry->RegisterRemoteChrome(packages, resources, overrides, locale);
579 0 : return true;
580 : }
581 :
582 : bool
583 0 : ContentChild::RecvSetOffline(const bool& offline)
584 : {
585 0 : nsCOMPtr<nsIIOService> io (do_GetIOService());
586 0 : NS_ASSERTION(io, "IO Service can not be null");
587 :
588 0 : io->SetOffline(offline);
589 :
590 0 : return true;
591 : }
592 :
593 : void
594 0 : ContentChild::ActorDestroy(ActorDestroyReason why)
595 : {
596 0 : if (AbnormalShutdown == why) {
597 0 : NS_WARNING("shutting down early because of crash!");
598 0 : QuickExit();
599 : }
600 :
601 : #ifndef DEBUG
602 : // In release builds, there's no point in the content process
603 : // going through the full XPCOM shutdown path, because it doesn't
604 : // keep persistent state.
605 : QuickExit();
606 : #endif
607 :
608 0 : mAlertObservers.Clear();
609 :
610 0 : nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
611 0 : if (svc) {
612 0 : svc->UnregisterListener(mConsoleListener);
613 0 : mConsoleListener->mChild = nsnull;
614 : }
615 :
616 0 : XRE_ShutdownChildProcess();
617 0 : }
618 :
619 : void
620 0 : ContentChild::ProcessingError(Result what)
621 : {
622 0 : switch (what) {
623 : case MsgDropped:
624 0 : QuickExit();
625 :
626 : case MsgNotKnown:
627 : case MsgNotAllowed:
628 : case MsgPayloadError:
629 : case MsgProcessingError:
630 : case MsgRouteError:
631 : case MsgValueError:
632 0 : NS_RUNTIMEABORT("aborting because of fatal error");
633 :
634 : default:
635 0 : NS_RUNTIMEABORT("not reached");
636 : }
637 0 : }
638 :
639 : void
640 0 : ContentChild::QuickExit()
641 : {
642 0 : NS_WARNING("content process _exit()ing");
643 0 : _exit(0);
644 : }
645 :
646 : nsresult
647 0 : ContentChild::AddRemoteAlertObserver(const nsString& aData,
648 : nsIObserver* aObserver)
649 : {
650 0 : NS_ASSERTION(aObserver, "Adding a null observer?");
651 0 : mAlertObservers.AppendElement(new AlertObserver(aObserver, aData));
652 0 : return NS_OK;
653 : }
654 :
655 : bool
656 0 : ContentChild::RecvPreferenceUpdate(const PrefTuple& aPref)
657 : {
658 0 : Preferences::SetPreference(&aPref);
659 0 : return true;
660 : }
661 :
662 : bool
663 0 : ContentChild::RecvClearUserPreference(const nsCString& aPrefName)
664 : {
665 0 : Preferences::ClearContentPref(aPrefName.get());
666 0 : return true;
667 : }
668 :
669 : bool
670 0 : ContentChild::RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData)
671 : {
672 0 : for (PRUint32 i = 0; i < mAlertObservers.Length();
673 : /*we mutate the array during the loop; ++i iff no mutation*/) {
674 0 : AlertObserver* observer = mAlertObservers[i];
675 0 : if (observer->Observes(aData) && observer->Notify(aType)) {
676 : // if aType == alertfinished, this alert is done. we can
677 : // remove the observer.
678 0 : if (aType.Equals(nsDependentCString("alertfinished"))) {
679 0 : mAlertObservers.RemoveElementAt(i);
680 0 : continue;
681 : }
682 : }
683 0 : ++i;
684 : }
685 0 : return true;
686 : }
687 :
688 : bool
689 0 : ContentChild::RecvNotifyVisited(const IPC::URI& aURI)
690 : {
691 0 : nsCOMPtr<nsIURI> newURI(aURI);
692 0 : History::GetService()->NotifyVisited(newURI);
693 0 : return true;
694 : }
695 :
696 :
697 : bool
698 0 : ContentChild::RecvAsyncMessage(const nsString& aMsg, const nsString& aJSON)
699 : {
700 0 : nsRefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::sChildProcessManager;
701 0 : if (cpm) {
702 0 : cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
703 0 : aMsg, false, aJSON, nsnull, nsnull);
704 : }
705 0 : return true;
706 : }
707 :
708 : bool
709 0 : ContentChild::RecvGeolocationUpdate(const GeoPosition& somewhere)
710 : {
711 0 : nsCOMPtr<nsIGeolocationUpdate> gs = do_GetService("@mozilla.org/geolocation/service;1");
712 0 : if (!gs) {
713 0 : return true;
714 : }
715 0 : nsCOMPtr<nsIDOMGeoPosition> position = somewhere;
716 0 : gs->Update(position);
717 0 : return true;
718 : }
719 :
720 : bool
721 0 : ContentChild::RecvAddPermission(const IPC::Permission& permission)
722 : {
723 : #if MOZ_PERMISSIONS
724 : nsCOMPtr<nsIPermissionManager> permissionManagerIface =
725 0 : do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
726 : nsPermissionManager* permissionManager =
727 0 : static_cast<nsPermissionManager*>(permissionManagerIface.get());
728 0 : NS_ABORT_IF_FALSE(permissionManager,
729 : "We have no permissionManager in the Content process !");
730 :
731 0 : permissionManager->AddInternal(nsCString(permission.host),
732 0 : nsCString(permission.type),
733 : permission.capability,
734 : 0,
735 : permission.expireType,
736 : permission.expireTime,
737 : nsPermissionManager::eNotify,
738 0 : nsPermissionManager::eNoDBOperation);
739 : #endif
740 :
741 0 : return true;
742 : }
743 :
744 : bool
745 0 : ContentChild::RecvDeviceMotionChanged(const long int& type,
746 : const double& x, const double& y,
747 : const double& z)
748 : {
749 : nsCOMPtr<nsIDeviceMotionUpdate> dmu =
750 0 : do_GetService(NS_DEVICE_MOTION_CONTRACTID);
751 0 : if (dmu)
752 0 : dmu->DeviceMotionChanged(type, x, y, z);
753 0 : return true;
754 : }
755 :
756 : bool
757 0 : ContentChild::RecvScreenSizeChanged(const gfxIntSize& size)
758 : {
759 : #ifdef ANDROID
760 : mScreenSize = size;
761 : #else
762 0 : NS_RUNTIMEABORT("Message currently only expected on android");
763 : #endif
764 0 : return true;
765 : }
766 :
767 : bool
768 0 : ContentChild::RecvFlushMemory(const nsString& reason)
769 : {
770 : nsCOMPtr<nsIObserverService> os =
771 0 : mozilla::services::GetObserverService();
772 0 : if (os)
773 0 : os->NotifyObservers(nsnull, "memory-pressure", reason.get());
774 0 : return true;
775 : }
776 :
777 : bool
778 0 : ContentChild::RecvActivateA11y()
779 : {
780 : #ifdef ACCESSIBILITY
781 : // Start accessibility in content process if it's running in chrome
782 : // process.
783 : nsCOMPtr<nsIAccessibilityService> accService =
784 0 : do_GetService("@mozilla.org/accessibilityService;1");
785 : #endif
786 0 : return true;
787 : }
788 :
789 : nsString&
790 0 : ContentChild::GetIndexedDBPath()
791 : {
792 0 : if (!gIndexedDBPath) {
793 0 : gIndexedDBPath = new nsString(); // cleaned up in the destructor
794 0 : SendGetIndexedDBDirectory(gIndexedDBPath);
795 : }
796 :
797 0 : return *gIndexedDBPath;
798 : }
799 :
800 : bool
801 0 : ContentChild::RecvGarbageCollect()
802 : {
803 0 : nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
804 0 : return true;
805 : }
806 :
807 : bool
808 0 : ContentChild::RecvCycleCollect()
809 : {
810 0 : nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
811 0 : nsJSContext::CycleCollectNow();
812 0 : return true;
813 : }
814 :
815 : bool
816 0 : ContentChild::RecvAppInfo(const nsCString& version, const nsCString& buildID)
817 : {
818 0 : mAppInfo.version.Assign(version);
819 0 : mAppInfo.buildID.Assign(buildID);
820 0 : return true;
821 : }
822 :
823 : bool
824 0 : ContentChild::RecvSetID(const PRUint64 &id)
825 : {
826 0 : if (mID != PRUint64(-1)) {
827 0 : NS_WARNING("Setting content child's ID twice?");
828 : }
829 0 : mID = id;
830 0 : return true;
831 : }
832 :
833 : } // namespace dom
834 : } // namespace mozilla
|