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 : #include "ContentParent.h"
41 :
42 : #include "TabParent.h"
43 : #include "CrashReporterParent.h"
44 : #include "History.h"
45 : #include "mozilla/ipc/TestShellParent.h"
46 : #include "mozilla/net/NeckoParent.h"
47 : #include "mozilla/Preferences.h"
48 : #include "nsHashPropertyBag.h"
49 : #include "nsIFilePicker.h"
50 : #include "nsIWindowWatcher.h"
51 : #include "nsIDOMWindow.h"
52 : #include "nsIPrefBranch.h"
53 : #include "nsIPrefLocalizedString.h"
54 : #include "nsIObserverService.h"
55 : #include "nsContentUtils.h"
56 : #include "nsAutoPtr.h"
57 : #include "nsCOMPtr.h"
58 : #include "nsServiceManagerUtils.h"
59 : #include "nsThreadUtils.h"
60 : #include "nsChromeRegistryChrome.h"
61 : #include "nsExternalHelperAppService.h"
62 : #include "nsCExternalHandlerService.h"
63 : #include "nsFrameMessageManager.h"
64 : #include "nsIPresShell.h"
65 : #include "nsIAlertsService.h"
66 : #include "nsToolkitCompsCID.h"
67 : #include "nsIDOMGeoGeolocation.h"
68 : #include "nsIConsoleService.h"
69 : #include "nsIScriptError.h"
70 : #include "nsConsoleMessage.h"
71 : #include "nsAppDirectoryServiceDefs.h"
72 : #include "nsAppRunner.h"
73 : #include "IDBFactory.h"
74 : #if defined(MOZ_SYDNEYAUDIO)
75 : #include "AudioParent.h"
76 : #endif
77 : #include "SandboxHal.h"
78 :
79 : #if defined(ANDROID) || defined(LINUX)
80 : #include <sys/time.h>
81 : #include <sys/resource.h>
82 : #include "nsSystemInfo.h"
83 : #endif
84 :
85 : #ifdef MOZ_PERMISSIONS
86 : #include "nsPermissionManager.h"
87 : #endif
88 :
89 : #ifdef MOZ_CRASHREPORTER
90 : #include "nsICrashReporter.h"
91 : #include "nsExceptionHandler.h"
92 : #endif
93 :
94 : #include "mozilla/dom/ExternalHelperAppParent.h"
95 : #include "mozilla/dom/StorageParent.h"
96 : #include "mozilla/hal_sandbox/PHalParent.h"
97 : #include "mozilla/Services.h"
98 : #include "mozilla/unused.h"
99 : #include "nsDeviceMotion.h"
100 : #include "mozilla/Util.h"
101 :
102 : #include "nsIMemoryReporter.h"
103 : #include "nsMemoryReporterManager.h"
104 : #include "mozilla/dom/PMemoryReportRequestParent.h"
105 :
106 : #ifdef ANDROID
107 : #include "gfxAndroidPlatform.h"
108 : #endif
109 : #ifdef MOZ_WIDGET_ANDROID
110 : #include "AndroidBridge.h"
111 : #endif
112 :
113 : #include "nsIClipboard.h"
114 : #include "nsWidgetsCID.h"
115 : #include "nsISupportsPrimitives.h"
116 : #include "mozilla/dom/sms/SmsParent.h"
117 :
118 : static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
119 : static const char* sClipboardTextFlavors[] = { kUnicodeMime };
120 :
121 : using mozilla::Preferences;
122 : using namespace mozilla::ipc;
123 : using namespace mozilla::hal_sandbox;
124 : using namespace mozilla::net;
125 : using namespace mozilla::places;
126 : using mozilla::unused; // heh
127 : using base::KillProcess;
128 : using namespace mozilla::dom::sms;
129 :
130 : namespace mozilla {
131 : namespace dom {
132 :
133 : #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
134 :
135 : class MemoryReportRequestParent : public PMemoryReportRequestParent
136 : {
137 : public:
138 : MemoryReportRequestParent();
139 : virtual ~MemoryReportRequestParent();
140 :
141 : virtual bool Recv__delete__(const InfallibleTArray<MemoryReport>& report);
142 : private:
143 0 : ContentParent* Owner()
144 : {
145 0 : return static_cast<ContentParent*>(Manager());
146 : }
147 : };
148 :
149 :
150 0 : MemoryReportRequestParent::MemoryReportRequestParent()
151 : {
152 0 : MOZ_COUNT_CTOR(MemoryReportRequestParent);
153 0 : }
154 :
155 : bool
156 0 : MemoryReportRequestParent::Recv__delete__(const InfallibleTArray<MemoryReport>& report)
157 : {
158 0 : Owner()->SetChildMemoryReporters(report);
159 0 : return true;
160 : }
161 :
162 0 : MemoryReportRequestParent::~MemoryReportRequestParent()
163 : {
164 0 : MOZ_COUNT_DTOR(MemoryReportRequestParent);
165 0 : }
166 :
167 : nsTArray<ContentParent*>* ContentParent::gContentParents;
168 :
169 : // The first content child has ID 1, so the chrome process can have ID 0.
170 : static PRUint64 gContentChildID = 1;
171 :
172 : ContentParent*
173 0 : ContentParent::GetNewOrUsed()
174 : {
175 0 : if (!gContentParents)
176 0 : gContentParents = new nsTArray<ContentParent*>();
177 :
178 0 : PRInt32 maxContentProcesses = Preferences::GetInt("dom.ipc.processCount", 1);
179 0 : if (maxContentProcesses < 1)
180 0 : maxContentProcesses = 1;
181 :
182 0 : if (gContentParents->Length() >= PRUint32(maxContentProcesses)) {
183 0 : ContentParent* p = (*gContentParents)[rand() % gContentParents->Length()];
184 0 : NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in gContentParents?");
185 0 : return p;
186 : }
187 :
188 0 : nsRefPtr<ContentParent> p = new ContentParent();
189 0 : p->Init();
190 0 : gContentParents->AppendElement(p);
191 0 : return p;
192 : }
193 :
194 : void
195 2836 : ContentParent::GetAll(nsTArray<ContentParent*>& aArray)
196 : {
197 2836 : if (!gContentParents) {
198 2836 : aArray.Clear();
199 2836 : return;
200 : }
201 :
202 0 : aArray = *gContentParents;
203 : }
204 :
205 : void
206 0 : ContentParent::Init()
207 : {
208 0 : nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
209 0 : if (obs) {
210 0 : obs->AddObserver(this, "xpcom-shutdown", false);
211 0 : obs->AddObserver(this, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC, false);
212 0 : obs->AddObserver(this, "child-memory-reporter-request", false);
213 0 : obs->AddObserver(this, "memory-pressure", false);
214 0 : obs->AddObserver(this, "child-gc-request", false);
215 0 : obs->AddObserver(this, "child-cc-request", false);
216 : #ifdef ACCESSIBILITY
217 0 : obs->AddObserver(this, "a11y-init-or-shutdown", false);
218 : #endif
219 : }
220 0 : nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
221 0 : if (prefs) {
222 0 : prefs->AddObserver("", this, false);
223 : }
224 : nsCOMPtr<nsIThreadInternal>
225 0 : threadInt(do_QueryInterface(NS_GetCurrentThread()));
226 0 : if (threadInt) {
227 0 : threadInt->AddObserver(this);
228 : }
229 0 : if (obs) {
230 0 : obs->NotifyObservers(static_cast<nsIObserver*>(this), "ipc:content-created", nsnull);
231 : }
232 :
233 : #ifdef ACCESSIBILITY
234 : // If accessibility is running in chrome process then start it in content
235 : // process.
236 0 : if (nsIPresShell::IsAccessibilityActive()) {
237 0 : unused << SendActivateA11y();
238 : }
239 : #endif
240 0 : }
241 :
242 : void
243 0 : ContentParent::OnChannelConnected(int32 pid)
244 : {
245 : ProcessHandle handle;
246 0 : if (!base::OpenPrivilegedProcessHandle(pid, &handle)) {
247 0 : NS_WARNING("Can't open handle to child process.");
248 : }
249 : else {
250 0 : SetOtherProcess(handle);
251 :
252 : #if defined(ANDROID) || defined(LINUX)
253 0 : EnsurePrefService();
254 0 : nsCOMPtr<nsIPrefBranch> branch;
255 0 : branch = do_QueryInterface(mPrefService);
256 :
257 : // Check nice preference
258 0 : PRInt32 nice = 0;
259 0 : branch->GetIntPref("dom.ipc.content.nice", &nice);
260 :
261 : // Environment variable overrides preference
262 0 : char* relativeNicenessStr = getenv("MOZ_CHILD_PROCESS_RELATIVE_NICENESS");
263 0 : if (relativeNicenessStr) {
264 0 : nice = atoi(relativeNicenessStr);
265 : }
266 :
267 : /* make the GUI thread have higher priority on single-cpu devices */
268 0 : nsCOMPtr<nsIPropertyBag2> infoService = do_GetService(NS_SYSTEMINFO_CONTRACTID);
269 0 : if (infoService) {
270 : PRInt32 cpus;
271 0 : nsresult rv = infoService->GetPropertyAsInt32(NS_LITERAL_STRING("cpucount"), &cpus);
272 0 : if (NS_FAILED(rv)) {
273 0 : cpus = 1;
274 : }
275 0 : if (nice != 0 && cpus == 1) {
276 0 : setpriority(PRIO_PROCESS, pid, getpriority(PRIO_PROCESS, pid) + nice);
277 : }
278 : }
279 : #endif
280 : }
281 0 : }
282 :
283 : namespace {
284 :
285 : void
286 0 : DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
287 : {
288 : XRE_GetIOMessageLoop()
289 : ->PostTask(FROM_HERE,
290 0 : new DeleteTask<GeckoChildProcessHost>(aSubprocess));
291 0 : }
292 :
293 : // This runnable only exists to delegate ownership of the
294 : // ContentParent to this runnable, until it's deleted by the event
295 : // system.
296 : struct DelayedDeleteContentParentTask : public nsRunnable
297 0 : {
298 0 : DelayedDeleteContentParentTask(ContentParent* aObj) : mObj(aObj) { }
299 :
300 : // No-op
301 0 : NS_IMETHODIMP Run() { return NS_OK; }
302 :
303 : nsRefPtr<ContentParent> mObj;
304 : };
305 :
306 : }
307 :
308 : void
309 0 : ContentParent::ActorDestroy(ActorDestroyReason why)
310 : {
311 : nsCOMPtr<nsIThreadObserver>
312 0 : kungFuDeathGrip(static_cast<nsIThreadObserver*>(this));
313 0 : nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
314 0 : if (obs) {
315 0 : obs->RemoveObserver(static_cast<nsIObserver*>(this), "xpcom-shutdown");
316 0 : obs->RemoveObserver(static_cast<nsIObserver*>(this), "memory-pressure");
317 0 : obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-memory-reporter-request");
318 0 : obs->RemoveObserver(static_cast<nsIObserver*>(this), NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC);
319 0 : obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-gc-request");
320 0 : obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-cc-request");
321 : #ifdef ACCESSIBILITY
322 0 : obs->RemoveObserver(static_cast<nsIObserver*>(this), "a11y-init-or-shutdown");
323 : #endif
324 : }
325 :
326 0 : mMessageManager->Disconnect();
327 :
328 : // clear the child memory reporters
329 0 : InfallibleTArray<MemoryReport> empty;
330 0 : SetChildMemoryReporters(empty);
331 :
332 : // remove the global remote preferences observers
333 : nsCOMPtr<nsIPrefBranch> prefs
334 0 : (do_GetService(NS_PREFSERVICE_CONTRACTID));
335 0 : if (prefs) {
336 0 : prefs->RemoveObserver("", this);
337 : }
338 :
339 0 : RecvRemoveGeolocationListener();
340 0 : RecvRemoveDeviceMotionListener();
341 :
342 : nsCOMPtr<nsIThreadInternal>
343 0 : threadInt(do_QueryInterface(NS_GetCurrentThread()));
344 0 : if (threadInt)
345 0 : threadInt->RemoveObserver(this);
346 0 : if (mRunToCompletionDepth)
347 0 : mRunToCompletionDepth = 0;
348 :
349 0 : if (gContentParents) {
350 0 : gContentParents->RemoveElement(this);
351 0 : if (!gContentParents->Length()) {
352 0 : delete gContentParents;
353 0 : gContentParents = NULL;
354 : }
355 : }
356 :
357 0 : mIsAlive = false;
358 :
359 0 : if (obs) {
360 0 : nsRefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
361 0 : props->Init();
362 :
363 0 : if (AbnormalShutdown == why) {
364 0 : props->SetPropertyAsBool(NS_LITERAL_STRING("abnormal"), true);
365 :
366 : #ifdef MOZ_CRASHREPORTER
367 0 : MOZ_ASSERT(ManagedPCrashReporterParent().Length() > 0);
368 : CrashReporterParent* crashReporter =
369 0 : static_cast<CrashReporterParent*>(ManagedPCrashReporterParent()[0]);
370 :
371 0 : crashReporter->GenerateCrashReport(this, NULL);
372 :
373 0 : nsAutoString dumpID(crashReporter->ChildDumpID());
374 0 : props->SetPropertyAsAString(NS_LITERAL_STRING("dumpID"), dumpID);
375 : #endif
376 :
377 0 : obs->NotifyObservers((nsIPropertyBag2*) props, "ipc:content-shutdown", nsnull);
378 : }
379 : }
380 :
381 : MessageLoop::current()->
382 : PostTask(FROM_HERE,
383 0 : NewRunnableFunction(DelayedDeleteSubprocess, mSubprocess));
384 0 : mSubprocess = NULL;
385 :
386 : // IPDL rules require actors to live on past ActorDestroy, but it
387 : // may be that the kungFuDeathGrip above is the last reference to
388 : // |this|. If so, when we go out of scope here, we're deleted and
389 : // all hell breaks loose.
390 : //
391 : // This runnable ensures that a reference to |this| lives on at
392 : // least until after the current task finishes running.
393 0 : NS_DispatchToCurrentThread(new DelayedDeleteContentParentTask(this));
394 0 : }
395 :
396 : TabParent*
397 0 : ContentParent::CreateTab(PRUint32 aChromeFlags)
398 : {
399 0 : return static_cast<TabParent*>(SendPBrowserConstructor(aChromeFlags));
400 : }
401 :
402 : TestShellParent*
403 0 : ContentParent::CreateTestShell()
404 : {
405 0 : return static_cast<TestShellParent*>(SendPTestShellConstructor());
406 : }
407 :
408 : bool
409 0 : ContentParent::DestroyTestShell(TestShellParent* aTestShell)
410 : {
411 0 : return PTestShellParent::Send__delete__(aTestShell);
412 : }
413 :
414 : TestShellParent*
415 0 : ContentParent::GetTestShellSingleton()
416 : {
417 0 : if (!ManagedPTestShellParent().Length())
418 0 : return nsnull;
419 0 : return static_cast<TestShellParent*>(ManagedPTestShellParent()[0]);
420 : }
421 :
422 0 : ContentParent::ContentParent()
423 : : mGeolocationWatchID(-1)
424 : , mRunToCompletionDepth(0)
425 : , mShouldCallUnblockChild(false)
426 : , mIsAlive(true)
427 0 : , mSendPermissionUpdates(false)
428 : {
429 0 : NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
430 0 : mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content);
431 0 : mSubprocess->AsyncLaunch();
432 0 : Open(mSubprocess->GetChannel(), mSubprocess->GetChildProcessHandle());
433 0 : unused << SendSetID(gContentChildID++);
434 :
435 0 : nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
436 : nsChromeRegistryChrome* chromeRegistry =
437 0 : static_cast<nsChromeRegistryChrome*>(registrySvc.get());
438 0 : chromeRegistry->SendRegisteredChrome(this);
439 0 : mMessageManager = nsFrameMessageManager::NewProcessMessageManager(this);
440 :
441 0 : if (gAppData) {
442 0 : nsCString version(gAppData->version);
443 0 : nsCString buildID(gAppData->buildID);
444 :
445 : //Sending all information to content process
446 0 : SendAppInfo(version, buildID);
447 : }
448 0 : }
449 :
450 0 : ContentParent::~ContentParent()
451 : {
452 0 : if (OtherProcess())
453 0 : base::CloseProcessHandle(OtherProcess());
454 :
455 0 : NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
456 0 : NS_ASSERTION(!gContentParents || !gContentParents->Contains(this),
457 : "Should have been removed in ActorDestroy");
458 0 : }
459 :
460 : bool
461 0 : ContentParent::IsAlive()
462 : {
463 0 : return mIsAlive;
464 : }
465 :
466 : bool
467 0 : ContentParent::RecvReadPrefsArray(InfallibleTArray<PrefTuple> *prefs)
468 : {
469 0 : EnsurePrefService();
470 0 : Preferences::MirrorPreferences(prefs);
471 0 : return true;
472 : }
473 :
474 : bool
475 0 : ContentParent::RecvReadFontList(InfallibleTArray<FontListEntry>* retValue)
476 : {
477 : #ifdef ANDROID
478 : gfxAndroidPlatform::GetPlatform()->GetFontList(retValue);
479 : #endif
480 0 : return true;
481 : }
482 :
483 :
484 : void
485 0 : ContentParent::EnsurePrefService()
486 : {
487 : nsresult rv;
488 0 : if (!mPrefService) {
489 0 : mPrefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
490 0 : NS_ASSERTION(NS_SUCCEEDED(rv),
491 : "We lost prefService in the Chrome process !");
492 : }
493 0 : }
494 :
495 : bool
496 0 : ContentParent::RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions)
497 : {
498 : #ifdef MOZ_PERMISSIONS
499 : nsCOMPtr<nsIPermissionManager> permissionManagerIface =
500 0 : do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
501 : nsPermissionManager* permissionManager =
502 0 : static_cast<nsPermissionManager*>(permissionManagerIface.get());
503 0 : NS_ABORT_IF_FALSE(permissionManager,
504 : "We have no permissionManager in the Chrome process !");
505 :
506 0 : nsCOMPtr<nsISimpleEnumerator> enumerator;
507 0 : DebugOnly<nsresult> rv = permissionManager->GetEnumerator(getter_AddRefs(enumerator));
508 0 : NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "Could not get enumerator!");
509 0 : while(1) {
510 : bool hasMore;
511 0 : enumerator->HasMoreElements(&hasMore);
512 0 : if (!hasMore)
513 : break;
514 :
515 0 : nsCOMPtr<nsISupports> supp;
516 0 : enumerator->GetNext(getter_AddRefs(supp));
517 0 : nsCOMPtr<nsIPermission> perm = do_QueryInterface(supp);
518 :
519 0 : nsCString host;
520 0 : perm->GetHost(host);
521 0 : nsCString type;
522 0 : perm->GetType(type);
523 : PRUint32 capability;
524 0 : perm->GetCapability(&capability);
525 : PRUint32 expireType;
526 0 : perm->GetExpireType(&expireType);
527 : PRInt64 expireTime;
528 0 : perm->GetExpireTime(&expireTime);
529 :
530 : aPermissions->AppendElement(IPC::Permission(host, type, capability,
531 0 : expireType, expireTime));
532 : }
533 :
534 : // Ask for future changes
535 0 : mSendPermissionUpdates = true;
536 : #endif
537 :
538 0 : return true;
539 : }
540 :
541 : bool
542 0 : ContentParent::RecvGetIndexedDBDirectory(nsString* aDirectory)
543 : {
544 0 : indexedDB::IDBFactory::NoteUsedByProcessType(GeckoProcessType_Content);
545 :
546 0 : nsCOMPtr<nsIFile> dbDirectory;
547 0 : nsresult rv = indexedDB::IDBFactory::GetDirectory(getter_AddRefs(dbDirectory));
548 :
549 0 : if (NS_FAILED(rv)) {
550 0 : NS_ERROR("Failed to get IndexedDB directory");
551 0 : return true;
552 : }
553 :
554 0 : dbDirectory->GetPath(*aDirectory);
555 :
556 0 : return true;
557 : }
558 :
559 : bool
560 0 : ContentParent::RecvSetClipboardText(const nsString& text, const PRInt32& whichClipboard)
561 : {
562 : nsresult rv;
563 0 : nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
564 0 : NS_ENSURE_SUCCESS(rv, true);
565 :
566 : nsCOMPtr<nsISupportsString> dataWrapper =
567 0 : do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
568 0 : NS_ENSURE_SUCCESS(rv, true);
569 :
570 0 : rv = dataWrapper->SetData(text);
571 0 : NS_ENSURE_SUCCESS(rv, true);
572 :
573 0 : nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
574 0 : NS_ENSURE_SUCCESS(rv, true);
575 :
576 : // If our data flavor has already been added, this will fail. But we don't care
577 0 : trans->AddDataFlavor(kUnicodeMime);
578 :
579 : nsCOMPtr<nsISupports> nsisupportsDataWrapper =
580 0 : do_QueryInterface(dataWrapper);
581 :
582 0 : rv = trans->SetTransferData(kUnicodeMime, nsisupportsDataWrapper,
583 0 : text.Length() * sizeof(PRUnichar));
584 0 : NS_ENSURE_SUCCESS(rv, true);
585 :
586 0 : clipboard->SetData(trans, NULL, whichClipboard);
587 0 : return true;
588 : }
589 :
590 : bool
591 0 : ContentParent::RecvGetClipboardText(const PRInt32& whichClipboard, nsString* text)
592 : {
593 : nsresult rv;
594 0 : nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
595 0 : NS_ENSURE_SUCCESS(rv, true);
596 :
597 0 : nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
598 0 : NS_ENSURE_SUCCESS(rv, true);
599 :
600 0 : clipboard->GetData(trans, whichClipboard);
601 0 : nsCOMPtr<nsISupports> tmp;
602 : PRUint32 len;
603 0 : rv = trans->GetTransferData(kUnicodeMime, getter_AddRefs(tmp), &len);
604 0 : if (NS_FAILED(rv))
605 0 : return false;
606 :
607 0 : nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(tmp);
608 : // No support for non-text data
609 0 : if (!supportsString)
610 0 : return false;
611 0 : supportsString->GetData(*text);
612 0 : return true;
613 : }
614 :
615 : bool
616 0 : ContentParent::RecvEmptyClipboard()
617 : {
618 : nsresult rv;
619 0 : nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
620 0 : NS_ENSURE_SUCCESS(rv, true);
621 :
622 0 : clipboard->EmptyClipboard(nsIClipboard::kGlobalClipboard);
623 :
624 0 : return true;
625 : }
626 :
627 : bool
628 0 : ContentParent::RecvClipboardHasText(bool* hasText)
629 : {
630 : nsresult rv;
631 0 : nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
632 0 : NS_ENSURE_SUCCESS(rv, true);
633 :
634 0 : clipboard->HasDataMatchingFlavors(sClipboardTextFlavors, 1,
635 0 : nsIClipboard::kGlobalClipboard, hasText);
636 0 : return true;
637 : }
638 :
639 : bool
640 0 : ContentParent::RecvGetSystemColors(const PRUint32& colorsCount, InfallibleTArray<PRUint32>* colors)
641 : {
642 : #ifdef MOZ_WIDGET_ANDROID
643 : NS_ASSERTION(AndroidBridge::Bridge() != nsnull, "AndroidBridge is not available");
644 : if (AndroidBridge::Bridge() == nsnull) {
645 : // Do not fail - the colors won't be right, but it's not critical
646 : return true;
647 : }
648 :
649 : colors->AppendElements(colorsCount);
650 :
651 : // The array elements correspond to the members of AndroidSystemColors structure,
652 : // so just pass the pointer to the elements buffer
653 : AndroidBridge::Bridge()->GetSystemColors((AndroidSystemColors*)colors->Elements());
654 : #endif
655 0 : return true;
656 : }
657 :
658 : bool
659 0 : ContentParent::RecvGetIconForExtension(const nsCString& aFileExt, const PRUint32& aIconSize, InfallibleTArray<PRUint8>* bits)
660 : {
661 : #ifdef MOZ_WIDGET_ANDROID
662 : NS_ASSERTION(AndroidBridge::Bridge() != nsnull, "AndroidBridge is not available");
663 : if (AndroidBridge::Bridge() == nsnull) {
664 : // Do not fail - just no icon will be shown
665 : return true;
666 : }
667 :
668 : bits->AppendElements(aIconSize * aIconSize * 4);
669 :
670 : AndroidBridge::Bridge()->GetIconForExtension(aFileExt, aIconSize, bits->Elements());
671 : #endif
672 0 : return true;
673 : }
674 :
675 : bool
676 0 : ContentParent::RecvGetShowPasswordSetting(bool* showPassword)
677 : {
678 : // default behavior is to show the last password character
679 0 : *showPassword = true;
680 : #ifdef MOZ_WIDGET_ANDROID
681 : NS_ASSERTION(AndroidBridge::Bridge() != nsnull, "AndroidBridge is not available");
682 : if (AndroidBridge::Bridge() != nsnull)
683 : *showPassword = AndroidBridge::Bridge()->GetShowPasswordSetting();
684 : #endif
685 0 : return true;
686 : }
687 :
688 0 : NS_IMPL_THREADSAFE_ISUPPORTS4(ContentParent,
689 : nsIObserver,
690 : nsIThreadObserver,
691 : nsIDOMGeoPositionCallback,
692 : nsIDeviceMotionListener)
693 :
694 : NS_IMETHODIMP
695 0 : ContentParent::Observe(nsISupports* aSubject,
696 : const char* aTopic,
697 : const PRUnichar* aData)
698 : {
699 0 : if (!strcmp(aTopic, "xpcom-shutdown") && mSubprocess) {
700 0 : Close();
701 0 : NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
702 : }
703 :
704 0 : if (!mIsAlive || !mSubprocess)
705 0 : return NS_OK;
706 :
707 : // listening for memory pressure event
708 0 : if (!strcmp(aTopic, "memory-pressure")) {
709 0 : unused << SendFlushMemory(nsDependentString(aData));
710 : }
711 : // listening for remotePrefs...
712 0 : else if (!strcmp(aTopic, "nsPref:changed")) {
713 : // We know prefs are ASCII here.
714 0 : NS_LossyConvertUTF16toASCII strData(aData);
715 :
716 0 : PrefTuple pref;
717 0 : bool prefNeedUpdate = Preferences::MirrorPreference(strData.get(), &pref);
718 0 : if (prefNeedUpdate) {
719 0 : if (!SendPreferenceUpdate(pref)) {
720 0 : return NS_ERROR_NOT_AVAILABLE;
721 : }
722 : } else {
723 : // Pref wasn't found. It was probably removed.
724 0 : if (!SendClearUserPreference(strData)) {
725 0 : return NS_ERROR_NOT_AVAILABLE;
726 : }
727 : }
728 : }
729 0 : else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
730 0 : NS_ConvertUTF16toUTF8 dataStr(aData);
731 0 : const char *offline = dataStr.get();
732 0 : if (!SendSetOffline(!strcmp(offline, "true") ? true : false))
733 0 : return NS_ERROR_NOT_AVAILABLE;
734 : }
735 : // listening for alert notifications
736 0 : else if (!strcmp(aTopic, "alertfinished") ||
737 0 : !strcmp(aTopic, "alertclickcallback") ) {
738 0 : if (!SendNotifyAlertsObserver(nsDependentCString(aTopic),
739 0 : nsDependentString(aData)))
740 0 : return NS_ERROR_NOT_AVAILABLE;
741 : }
742 0 : else if (!strcmp(aTopic, "child-memory-reporter-request")) {
743 0 : unused << SendPMemoryReportRequestConstructor();
744 : }
745 0 : else if (!strcmp(aTopic, "child-gc-request")){
746 0 : SendGarbageCollect();
747 : }
748 0 : else if (!strcmp(aTopic, "child-cc-request")){
749 0 : SendCycleCollect();
750 : }
751 : #ifdef ACCESSIBILITY
752 : // Make sure accessibility is running in content process when accessibility
753 : // gets initiated in chrome process.
754 0 : else if (aData && (*aData == '1') &&
755 0 : !strcmp(aTopic, "a11y-init-or-shutdown")) {
756 0 : unused << SendActivateA11y();
757 : }
758 : #endif
759 :
760 0 : return NS_OK;
761 : }
762 :
763 : PBrowserParent*
764 0 : ContentParent::AllocPBrowser(const PRUint32& aChromeFlags)
765 : {
766 0 : TabParent* parent = new TabParent();
767 0 : if (parent){
768 0 : NS_ADDREF(parent);
769 : }
770 0 : return parent;
771 : }
772 :
773 : bool
774 0 : ContentParent::DeallocPBrowser(PBrowserParent* frame)
775 : {
776 0 : TabParent* parent = static_cast<TabParent*>(frame);
777 0 : NS_RELEASE(parent);
778 0 : return true;
779 : }
780 :
781 : PCrashReporterParent*
782 0 : ContentParent::AllocPCrashReporter(const NativeThreadId& tid,
783 : const PRUint32& processType)
784 : {
785 : #ifdef MOZ_CRASHREPORTER
786 0 : return new CrashReporterParent();
787 : #else
788 : return nsnull;
789 : #endif
790 : }
791 :
792 : bool
793 0 : ContentParent::RecvPCrashReporterConstructor(PCrashReporterParent* actor,
794 : const NativeThreadId& tid,
795 : const PRUint32& processType)
796 : {
797 0 : static_cast<CrashReporterParent*>(actor)->SetChildData(tid, processType);
798 0 : return true;
799 : }
800 :
801 : bool
802 0 : ContentParent::DeallocPCrashReporter(PCrashReporterParent* crashreporter)
803 : {
804 0 : delete crashreporter;
805 0 : return true;
806 : }
807 :
808 : PHalParent*
809 0 : ContentParent::AllocPHal()
810 : {
811 0 : return CreateHalParent();
812 : }
813 :
814 : bool
815 0 : ContentParent::DeallocPHal(PHalParent* aHal)
816 : {
817 0 : delete aHal;
818 0 : return true;
819 : }
820 :
821 : PMemoryReportRequestParent*
822 0 : ContentParent::AllocPMemoryReportRequest()
823 : {
824 0 : MemoryReportRequestParent* parent = new MemoryReportRequestParent();
825 0 : return parent;
826 : }
827 :
828 : bool
829 0 : ContentParent::DeallocPMemoryReportRequest(PMemoryReportRequestParent* actor)
830 : {
831 0 : delete actor;
832 0 : return true;
833 : }
834 :
835 : void
836 0 : ContentParent::SetChildMemoryReporters(const InfallibleTArray<MemoryReport>& report)
837 : {
838 : nsCOMPtr<nsIMemoryReporterManager> mgr =
839 0 : do_GetService("@mozilla.org/memory-reporter-manager;1");
840 0 : for (PRInt32 i = 0; i < mMemoryReporters.Count(); i++)
841 0 : mgr->UnregisterReporter(mMemoryReporters[i]);
842 :
843 0 : for (PRUint32 i = 0; i < report.Length(); i++) {
844 0 : nsCString process = report[i].process();
845 0 : nsCString path = report[i].path();
846 0 : PRInt32 kind = report[i].kind();
847 0 : PRInt32 units = report[i].units();
848 0 : PRInt64 amount = report[i].amount();
849 0 : nsCString desc = report[i].desc();
850 :
851 : nsRefPtr<nsMemoryReporter> r =
852 0 : new nsMemoryReporter(process, path, kind, units, amount, desc);
853 :
854 0 : mMemoryReporters.AppendObject(r);
855 0 : mgr->RegisterReporter(r);
856 : }
857 :
858 : nsCOMPtr<nsIObserverService> obs =
859 0 : do_GetService("@mozilla.org/observer-service;1");
860 0 : if (obs)
861 0 : obs->NotifyObservers(nsnull, "child-memory-reporter-update", nsnull);
862 0 : }
863 :
864 : PTestShellParent*
865 0 : ContentParent::AllocPTestShell()
866 : {
867 0 : return new TestShellParent();
868 : }
869 :
870 : bool
871 0 : ContentParent::DeallocPTestShell(PTestShellParent* shell)
872 : {
873 0 : delete shell;
874 0 : return true;
875 : }
876 :
877 : PAudioParent*
878 0 : ContentParent::AllocPAudio(const PRInt32& numChannels,
879 : const PRInt32& rate,
880 : const PRInt32& format)
881 : {
882 : #if defined(MOZ_SYDNEYAUDIO)
883 0 : AudioParent *parent = new AudioParent(numChannels, rate, format);
884 0 : NS_ADDREF(parent);
885 0 : return parent;
886 : #else
887 : return nsnull;
888 : #endif
889 : }
890 :
891 : bool
892 0 : ContentParent::DeallocPAudio(PAudioParent* doomed)
893 : {
894 : #if defined(MOZ_SYDNEYAUDIO)
895 0 : AudioParent *parent = static_cast<AudioParent*>(doomed);
896 0 : NS_RELEASE(parent);
897 : #endif
898 0 : return true;
899 : }
900 :
901 : PNeckoParent*
902 0 : ContentParent::AllocPNecko()
903 : {
904 0 : return new NeckoParent();
905 : }
906 :
907 : bool
908 0 : ContentParent::DeallocPNecko(PNeckoParent* necko)
909 : {
910 0 : delete necko;
911 0 : return true;
912 : }
913 :
914 : PExternalHelperAppParent*
915 0 : ContentParent::AllocPExternalHelperApp(const IPC::URI& uri,
916 : const nsCString& aMimeContentType,
917 : const nsCString& aContentDisposition,
918 : const bool& aForceSave,
919 : const PRInt64& aContentLength,
920 : const IPC::URI& aReferrer)
921 : {
922 0 : ExternalHelperAppParent *parent = new ExternalHelperAppParent(uri, aContentLength);
923 0 : parent->AddRef();
924 0 : parent->Init(this, aMimeContentType, aContentDisposition, aForceSave, aReferrer);
925 0 : return parent;
926 : }
927 :
928 : bool
929 0 : ContentParent::DeallocPExternalHelperApp(PExternalHelperAppParent* aService)
930 : {
931 0 : ExternalHelperAppParent *parent = static_cast<ExternalHelperAppParent *>(aService);
932 0 : parent->Release();
933 0 : return true;
934 : }
935 :
936 : PSmsParent*
937 0 : ContentParent::AllocPSms()
938 : {
939 0 : return new SmsParent();
940 : }
941 :
942 : bool
943 0 : ContentParent::DeallocPSms(PSmsParent* aSms)
944 : {
945 0 : delete aSms;
946 0 : return true;
947 : }
948 :
949 : PStorageParent*
950 0 : ContentParent::AllocPStorage(const StorageConstructData& aData)
951 : {
952 0 : return new StorageParent(aData);
953 : }
954 :
955 : bool
956 0 : ContentParent::DeallocPStorage(PStorageParent* aActor)
957 : {
958 0 : delete aActor;
959 0 : return true;
960 : }
961 :
962 : void
963 0 : ContentParent::ReportChildAlreadyBlocked()
964 : {
965 0 : if (!mRunToCompletionDepth) {
966 : #ifdef DEBUG
967 0 : printf("Running to completion...\n");
968 : #endif
969 0 : mRunToCompletionDepth = 1;
970 0 : mShouldCallUnblockChild = false;
971 : }
972 0 : }
973 :
974 : bool
975 0 : ContentParent::RequestRunToCompletion()
976 : {
977 0 : if (!mRunToCompletionDepth &&
978 0 : BlockChild()) {
979 : #ifdef DEBUG
980 0 : printf("Running to completion...\n");
981 : #endif
982 0 : mRunToCompletionDepth = 1;
983 0 : mShouldCallUnblockChild = true;
984 : }
985 0 : return !!mRunToCompletionDepth;
986 : }
987 :
988 : bool
989 0 : ContentParent::RecvStartVisitedQuery(const IPC::URI& aURI)
990 : {
991 0 : nsCOMPtr<nsIURI> newURI(aURI);
992 0 : nsCOMPtr<IHistory> history = services::GetHistoryService();
993 0 : NS_ABORT_IF_FALSE(history, "History must exist at this point.");
994 0 : if (history) {
995 0 : history->RegisterVisitedCallback(newURI, nsnull);
996 : }
997 0 : return true;
998 : }
999 :
1000 :
1001 : bool
1002 0 : ContentParent::RecvVisitURI(const IPC::URI& uri,
1003 : const IPC::URI& referrer,
1004 : const PRUint32& flags)
1005 : {
1006 0 : nsCOMPtr<nsIURI> ourURI(uri);
1007 0 : nsCOMPtr<nsIURI> ourReferrer(referrer);
1008 0 : nsCOMPtr<IHistory> history = services::GetHistoryService();
1009 0 : NS_ABORT_IF_FALSE(history, "History must exist at this point");
1010 0 : if (history) {
1011 0 : history->VisitURI(ourURI, ourReferrer, flags);
1012 : }
1013 0 : return true;
1014 : }
1015 :
1016 :
1017 : bool
1018 0 : ContentParent::RecvSetURITitle(const IPC::URI& uri,
1019 : const nsString& title)
1020 : {
1021 0 : nsCOMPtr<nsIURI> ourURI(uri);
1022 0 : nsCOMPtr<IHistory> history = services::GetHistoryService();
1023 0 : NS_ABORT_IF_FALSE(history, "History must exist at this point");
1024 0 : if (history) {
1025 0 : history->SetURITitle(ourURI, title);
1026 : }
1027 0 : return true;
1028 : }
1029 :
1030 : bool
1031 0 : ContentParent::RecvShowFilePicker(const PRInt16& mode,
1032 : const PRInt16& selectedType,
1033 : const bool& addToRecentDocs,
1034 : const nsString& title,
1035 : const nsString& defaultFile,
1036 : const nsString& defaultExtension,
1037 : const InfallibleTArray<nsString>& filters,
1038 : const InfallibleTArray<nsString>& filterNames,
1039 : InfallibleTArray<nsString>* files,
1040 : PRInt16* retValue,
1041 : nsresult* result)
1042 : {
1043 0 : nsCOMPtr<nsIFilePicker> filePicker = do_CreateInstance("@mozilla.org/filepicker;1");
1044 0 : if (!filePicker) {
1045 0 : *result = NS_ERROR_NOT_AVAILABLE;
1046 0 : return true;
1047 : }
1048 :
1049 : // as the parent given to the content process would be meaningless in this
1050 : // process, always use active window as the parent
1051 0 : nsCOMPtr<nsIWindowWatcher> ww = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
1052 0 : nsCOMPtr<nsIDOMWindow> window;
1053 0 : ww->GetActiveWindow(getter_AddRefs(window));
1054 :
1055 : // initialize the "real" picker with all data given
1056 0 : *result = filePicker->Init(window, title, mode);
1057 0 : if (NS_FAILED(*result))
1058 0 : return true;
1059 :
1060 0 : filePicker->SetAddToRecentDocs(addToRecentDocs);
1061 :
1062 0 : PRUint32 count = filters.Length();
1063 0 : for (PRUint32 i = 0; i < count; ++i) {
1064 0 : filePicker->AppendFilter(filterNames[i], filters[i]);
1065 : }
1066 :
1067 0 : filePicker->SetDefaultString(defaultFile);
1068 0 : filePicker->SetDefaultExtension(defaultExtension);
1069 0 : filePicker->SetFilterIndex(selectedType);
1070 :
1071 : // and finally open the dialog
1072 0 : *result = filePicker->Show(retValue);
1073 0 : if (NS_FAILED(*result))
1074 0 : return true;
1075 :
1076 0 : if (mode == nsIFilePicker::modeOpenMultiple) {
1077 0 : nsCOMPtr<nsISimpleEnumerator> fileIter;
1078 0 : *result = filePicker->GetFiles(getter_AddRefs(fileIter));
1079 :
1080 0 : nsCOMPtr<nsILocalFile> singleFile;
1081 0 : bool loop = true;
1082 0 : while (NS_SUCCEEDED(fileIter->HasMoreElements(&loop)) && loop) {
1083 0 : fileIter->GetNext(getter_AddRefs(singleFile));
1084 0 : if (singleFile) {
1085 0 : nsAutoString filePath;
1086 0 : singleFile->GetPath(filePath);
1087 0 : files->AppendElement(filePath);
1088 : }
1089 : }
1090 0 : return true;
1091 : }
1092 0 : nsCOMPtr<nsILocalFile> file;
1093 0 : filePicker->GetFile(getter_AddRefs(file));
1094 :
1095 : // even with NS_OK file can be null if nothing was selected
1096 0 : if (file) {
1097 0 : nsAutoString filePath;
1098 0 : file->GetPath(filePath);
1099 0 : files->AppendElement(filePath);
1100 : }
1101 :
1102 0 : return true;
1103 : }
1104 :
1105 : bool
1106 0 : ContentParent::RecvLoadURIExternal(const IPC::URI& uri)
1107 : {
1108 0 : nsCOMPtr<nsIExternalProtocolService> extProtService(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
1109 0 : if (!extProtService)
1110 0 : return true;
1111 0 : nsCOMPtr<nsIURI> ourURI(uri);
1112 0 : extProtService->LoadURI(ourURI, nsnull);
1113 0 : return true;
1114 : }
1115 :
1116 : /* void onDispatchedEvent (in nsIThreadInternal thread); */
1117 : NS_IMETHODIMP
1118 0 : ContentParent::OnDispatchedEvent(nsIThreadInternal *thread)
1119 : {
1120 0 : NS_NOTREACHED("OnDispatchedEvent unimplemented");
1121 0 : return NS_ERROR_NOT_IMPLEMENTED;
1122 : }
1123 :
1124 : /* void onProcessNextEvent (in nsIThreadInternal thread, in boolean mayWait, in unsigned long recursionDepth); */
1125 : NS_IMETHODIMP
1126 0 : ContentParent::OnProcessNextEvent(nsIThreadInternal *thread,
1127 : bool mayWait,
1128 : PRUint32 recursionDepth)
1129 : {
1130 0 : if (mRunToCompletionDepth)
1131 0 : ++mRunToCompletionDepth;
1132 :
1133 0 : return NS_OK;
1134 : }
1135 :
1136 : /* void afterProcessNextEvent (in nsIThreadInternal thread, in unsigned long recursionDepth); */
1137 : NS_IMETHODIMP
1138 0 : ContentParent::AfterProcessNextEvent(nsIThreadInternal *thread,
1139 : PRUint32 recursionDepth)
1140 : {
1141 0 : if (mRunToCompletionDepth &&
1142 0 : !--mRunToCompletionDepth) {
1143 : #ifdef DEBUG
1144 0 : printf("... ran to completion.\n");
1145 : #endif
1146 0 : if (mShouldCallUnblockChild) {
1147 0 : mShouldCallUnblockChild = false;
1148 0 : UnblockChild();
1149 : }
1150 : }
1151 :
1152 0 : return NS_OK;
1153 : }
1154 :
1155 : bool
1156 0 : ContentParent::RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
1157 : const nsString& aText, const bool& aTextClickable,
1158 : const nsString& aCookie, const nsString& aName)
1159 : {
1160 0 : nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
1161 0 : if (sysAlerts) {
1162 0 : sysAlerts->ShowAlertNotification(aImageUrl, aTitle, aText, aTextClickable,
1163 0 : aCookie, this, aName);
1164 : }
1165 :
1166 0 : return true;
1167 : }
1168 :
1169 : bool
1170 0 : ContentParent::RecvSyncMessage(const nsString& aMsg, const nsString& aJSON,
1171 : InfallibleTArray<nsString>* aRetvals)
1172 : {
1173 0 : nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
1174 0 : if (ppm) {
1175 0 : ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
1176 0 : aMsg,true, aJSON, nsnull, aRetvals);
1177 : }
1178 0 : return true;
1179 : }
1180 :
1181 : bool
1182 0 : ContentParent::RecvAsyncMessage(const nsString& aMsg, const nsString& aJSON)
1183 : {
1184 0 : nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
1185 0 : if (ppm) {
1186 0 : ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
1187 0 : aMsg, false, aJSON, nsnull, nsnull);
1188 : }
1189 0 : return true;
1190 : }
1191 :
1192 : bool
1193 0 : ContentParent::RecvAddGeolocationListener()
1194 : {
1195 0 : if (mGeolocationWatchID == -1) {
1196 0 : nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
1197 0 : if (!geo) {
1198 0 : return true;
1199 : }
1200 0 : geo->WatchPosition(this, nsnull, nsnull, &mGeolocationWatchID);
1201 : }
1202 0 : return true;
1203 : }
1204 :
1205 : bool
1206 0 : ContentParent::RecvRemoveGeolocationListener()
1207 : {
1208 0 : if (mGeolocationWatchID != -1) {
1209 0 : nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
1210 0 : if (!geo) {
1211 0 : return true;
1212 : }
1213 0 : geo->ClearWatch(mGeolocationWatchID);
1214 0 : mGeolocationWatchID = -1;
1215 : }
1216 0 : return true;
1217 : }
1218 :
1219 : bool
1220 0 : ContentParent::RecvAddDeviceMotionListener()
1221 : {
1222 : nsCOMPtr<nsIDeviceMotion> dm =
1223 0 : do_GetService(NS_DEVICE_MOTION_CONTRACTID);
1224 0 : if (dm)
1225 0 : dm->AddListener(this);
1226 0 : return true;
1227 : }
1228 :
1229 : bool
1230 0 : ContentParent::RecvRemoveDeviceMotionListener()
1231 : {
1232 : nsCOMPtr<nsIDeviceMotion> dm =
1233 0 : do_GetService(NS_DEVICE_MOTION_CONTRACTID);
1234 0 : if (dm)
1235 0 : dm->RemoveListener(this);
1236 0 : return true;
1237 : }
1238 :
1239 : NS_IMETHODIMP
1240 0 : ContentParent::HandleEvent(nsIDOMGeoPosition* postion)
1241 : {
1242 0 : unused << SendGeolocationUpdate(GeoPosition(postion));
1243 0 : return NS_OK;
1244 : }
1245 :
1246 : bool
1247 0 : ContentParent::RecvConsoleMessage(const nsString& aMessage)
1248 : {
1249 0 : nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
1250 0 : if (!svc)
1251 0 : return true;
1252 :
1253 0 : nsRefPtr<nsConsoleMessage> msg(new nsConsoleMessage(aMessage.get()));
1254 0 : svc->LogMessage(msg);
1255 0 : return true;
1256 : }
1257 :
1258 : bool
1259 0 : ContentParent::RecvScriptError(const nsString& aMessage,
1260 : const nsString& aSourceName,
1261 : const nsString& aSourceLine,
1262 : const PRUint32& aLineNumber,
1263 : const PRUint32& aColNumber,
1264 : const PRUint32& aFlags,
1265 : const nsCString& aCategory)
1266 : {
1267 0 : nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
1268 0 : if (!svc)
1269 0 : return true;
1270 :
1271 0 : nsCOMPtr<nsIScriptError> msg(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
1272 0 : nsresult rv = msg->Init(aMessage.get(), aSourceName.get(), aSourceLine.get(),
1273 0 : aLineNumber, aColNumber, aFlags, aCategory.get());
1274 0 : if (NS_FAILED(rv))
1275 0 : return true;
1276 :
1277 0 : svc->LogMessage(msg);
1278 0 : return true;
1279 : }
1280 :
1281 : NS_IMETHODIMP
1282 0 : ContentParent::OnMotionChange(nsIDeviceMotionData *aDeviceData) {
1283 : PRUint32 type;
1284 : double x, y, z;
1285 0 : aDeviceData->GetType(&type);
1286 0 : aDeviceData->GetX(&x);
1287 0 : aDeviceData->GetY(&y);
1288 0 : aDeviceData->GetZ(&z);
1289 :
1290 0 : unused << SendDeviceMotionChanged(type, x, y, z);
1291 0 : return NS_OK;
1292 : }
1293 :
1294 :
1295 : } // namespace dom
1296 : } // namespace mozilla
|