LCOV - code coverage report
Current view: directory - dom/ipc - ContentParent.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 537 4 0.7 %
Date: 2012-06-02 Functions: 82 1 1.2 %

       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

Generated by: LCOV version 1.7