123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "mozilla/DebugOnly.h"
- #include "base/basictypes.h"
- #include "ContentParent.h"
- #include "TabParent.h"
- #if defined(LINUX)
- # include <sys/time.h>
- # include <sys/resource.h>
- #endif
- #include "chrome/common/process_watcher.h"
- #include "mozilla/a11y/PDocAccessible.h"
- #include "AppProcessChecker.h"
- #include "AudioChannelService.h"
- #include "BlobParent.h"
- #include "GMPServiceParent.h"
- #include "HandlerServiceParent.h"
- #include "IHistory.h"
- #include "imgIContainer.h"
- #include "mozIApplication.h"
- #if defined(XP_WIN) && defined(ACCESSIBILITY)
- #include "mozilla/a11y/AccessibleWrap.h"
- #endif
- #include "mozilla/ClearOnShutdown.h"
- #include "mozilla/StyleSheetInlines.h"
- #include "mozilla/DataStorage.h"
- #include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
- #include "mozilla/docshell/OfflineCacheUpdateParent.h"
- #include "mozilla/dom/DataTransfer.h"
- #include "mozilla/dom/DOMStorageIPC.h"
- #include "mozilla/dom/Element.h"
- #include "mozilla/dom/File.h"
- #include "mozilla/dom/FileSystemSecurity.h"
- #include "mozilla/dom/ExternalHelperAppParent.h"
- #include "mozilla/dom/GetFilesHelper.h"
- #include "mozilla/dom/GeolocationBinding.h"
- #include "mozilla/dom/Notification.h"
- #include "mozilla/dom/PContentBridgeParent.h"
- #include "mozilla/dom/PContentPermissionRequestParent.h"
- #include "mozilla/dom/PCycleCollectWithLogsParent.h"
- #include "mozilla/dom/PMemoryReportRequestParent.h"
- #include "mozilla/dom/ServiceWorkerRegistrar.h"
- #include "mozilla/dom/power/PowerManagerService.h"
- #include "mozilla/dom/Permissions.h"
- #include "mozilla/dom/PushNotifier.h"
- #include "mozilla/dom/quota/QuotaManagerService.h"
- #include "mozilla/dom/time/DateCacheCleaner.h"
- #include "mozilla/embedding/printingui/PrintingParent.h"
- #include "mozilla/gfx/gfxVars.h"
- #include "mozilla/gfx/GPUProcessManager.h"
- #include "mozilla/hal_sandbox/PHalParent.h"
- #include "mozilla/ipc/BackgroundChild.h"
- #include "mozilla/ipc/BackgroundParent.h"
- #include "mozilla/ipc/FileDescriptorUtils.h"
- #include "mozilla/ipc/PSendStreamParent.h"
- #include "mozilla/ipc/TestShellParent.h"
- #include "mozilla/ipc/InputStreamUtils.h"
- #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
- #include "mozilla/layers/PAPZParent.h"
- #include "mozilla/layers/CompositorThread.h"
- #include "mozilla/layers/ImageBridgeParent.h"
- #include "mozilla/layers/LayerTreeOwnerTracker.h"
- #include "mozilla/layout/RenderFrameParent.h"
- #include "mozilla/LookAndFeel.h"
- #include "mozilla/media/MediaParent.h"
- #include "mozilla/Move.h"
- #include "mozilla/net/NeckoParent.h"
- #include "mozilla/plugins/PluginBridge.h"
- #include "mozilla/Preferences.h"
- #include "mozilla/ProcessHangMonitor.h"
- #include "mozilla/ProcessHangMonitorIPC.h"
- #include "mozilla/ScopeExit.h"
- #include "mozilla/Services.h"
- #include "mozilla/StaticPtr.h"
- #include "mozilla/WebBrowserPersistDocumentParent.h"
- #include "mozilla/Unused.h"
- #include "nsAnonymousTemporaryFile.h"
- #include "nsAppRunner.h"
- #include "nsCDefaultURIFixup.h"
- #include "nsCExternalHandlerService.h"
- #include "nsCOMPtr.h"
- #include "nsChromeRegistryChrome.h"
- #include "nsConsoleMessage.h"
- #include "nsConsoleService.h"
- #include "nsContentUtils.h"
- #include "nsDebugImpl.h"
- #include "nsFrameMessageManager.h"
- #include "nsHashPropertyBag.h"
- #include "nsIAlertsService.h"
- #include "nsIAppsService.h"
- #include "nsIClipboard.h"
- #include "nsContentPermissionHelper.h"
- #include "nsICycleCollectorListener.h"
- #include "nsIDocShellTreeOwner.h"
- #include "nsIDocument.h"
- #include "nsIDOMGeoGeolocation.h"
- #include "nsIDOMGeoPositionError.h"
- #include "nsIDragService.h"
- #include "mozilla/dom/WakeLock.h"
- #include "nsIDOMWindow.h"
- #include "nsIExternalProtocolService.h"
- #include "nsIFormProcessor.h"
- #include "nsIFrameLoader.h"
- #include "nsIGfxInfo.h"
- #include "nsIIdleService.h"
- #include "nsIInterfaceRequestorUtils.h"
- #include "nsIMemoryInfoDumper.h"
- #include "nsIMemoryReporter.h"
- #include "nsIMozBrowserFrame.h"
- #include "nsIMutable.h"
- #include "nsINSSU2FToken.h"
- #include "nsIObserverService.h"
- #include "nsIParentChannel.h"
- #include "nsIPresShell.h"
- #include "nsIRemoteWindowContext.h"
- #include "nsIScriptError.h"
- #include "nsIScriptSecurityManager.h"
- #include "nsISiteSecurityService.h"
- #include "nsISpellChecker.h"
- #include "nsISupportsPrimitives.h"
- #include "nsITimer.h"
- #include "nsIURIFixup.h"
- #include "nsIDocShellTreeOwner.h"
- #include "nsIXULWindow.h"
- #include "nsIDOMChromeWindow.h"
- #include "nsIWindowWatcher.h"
- #include "nsPIWindowWatcher.h"
- #include "nsWindowWatcher.h"
- #include "nsIXULRuntime.h"
- #include "mozilla/dom/nsMixedContentBlocker.h"
- #include "nsMemoryInfoDumper.h"
- #include "nsMemoryReporterManager.h"
- #include "nsServiceManagerUtils.h"
- #include "nsStyleSheetService.h"
- #include "nsThreadUtils.h"
- #include "nsToolkitCompsCID.h"
- #include "nsWidgetsCID.h"
- #include "PreallocatedProcessManager.h"
- #include "ProcessPriorityManager.h"
- #include "SandboxHal.h"
- #include "ScreenManagerParent.h"
- #include "SourceSurfaceRawData.h"
- #include "TabParent.h"
- #include "URIUtils.h"
- #include "nsIWebBrowserChrome.h"
- #include "nsIDocShell.h"
- #include "nsDocShell.h"
- #include "nsOpenURIInFrameParams.h"
- #include "mozilla/net/NeckoMessageUtils.h"
- #include "gfxPrefs.h"
- #include "prio.h"
- #include "private/pprio.h"
- #include "ContentProcessManager.h"
- #include "mozilla/dom/ipc/StructuredCloneData.h"
- #include "mozilla/psm/PSMContentListener.h"
- #include "nsPluginHost.h"
- #include "nsPluginTags.h"
- #include "nsIBlocklistService.h"
- #include "mozilla/StyleSheet.h"
- #include "mozilla/StyleSheetInlines.h"
- #include "nsHostObjectProtocolHandler.h"
- #include "nsICaptivePortalService.h"
- #include "nsIBidiKeyboard.h"
- #include "nsLayoutStylesheetCache.h"
- #ifdef MOZ_WEBRTC
- #include "signaling/src/peerconnection/WebrtcGlobalParent.h"
- #endif
- #if defined(LINUX)
- #include "nsSystemInfo.h"
- #endif
- #if defined(XP_LINUX)
- #include "mozilla/Hal.h"
- #endif
- #ifdef MOZ_PERMISSIONS
- # include "nsPermissionManager.h"
- #endif
- #ifdef MOZ_WIDGET_GTK
- #include <gdk/gdk.h>
- #endif
- #include "mozilla/RemoteSpellCheckEngineParent.h"
- #include "Crypto.h"
- #ifdef MOZ_WEBSPEECH
- #include "mozilla/dom/SpeechSynthesisParent.h"
- #endif
- #ifdef MOZ_TOOLKIT_SEARCH
- #include "nsIBrowserSearchService.h"
- #endif
- #ifdef XP_WIN
- #include "mozilla/widget/AudioSession.h"
- #endif
- #ifdef ACCESSIBILITY
- #include "nsAccessibilityService.h"
- #endif
- // For VP9Benchmark::sBenchmarkFpsPref
- #include "Benchmark.h"
- static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
- using base::ChildPrivileges;
- using base::KillProcess;
- using namespace mozilla::dom;
- using namespace mozilla::dom::power;
- using namespace mozilla::media;
- using namespace mozilla::embedding;
- using namespace mozilla::gfx;
- using namespace mozilla::gmp;
- using namespace mozilla::hal;
- using namespace mozilla::ipc;
- using namespace mozilla::layers;
- using namespace mozilla::layout;
- using namespace mozilla::net;
- using namespace mozilla::jsipc;
- using namespace mozilla::psm;
- using namespace mozilla::widget;
- // XXX Workaround for bug 986973 to maintain the existing broken semantics
- template<>
- struct nsIConsoleService::COMTypeInfo<nsConsoleService, void> {
- static const nsIID kIID;
- };
- const nsIID nsIConsoleService::COMTypeInfo<nsConsoleService, void>::kIID = NS_ICONSOLESERVICE_IID;
- namespace mozilla {
- namespace dom {
- #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
- #define NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC "ipc:network:set-connectivity"
- class MemoryReportRequestParent : public PMemoryReportRequestParent
- {
- public:
- explicit MemoryReportRequestParent(uint32_t aGeneration);
- virtual ~MemoryReportRequestParent();
- virtual void ActorDestroy(ActorDestroyReason aWhy) override;
- virtual bool RecvReport(const MemoryReport& aReport) override;
- virtual bool Recv__delete__() override;
- private:
- const uint32_t mGeneration;
- // Non-null if we haven't yet called EndProcessReport() on it.
- RefPtr<nsMemoryReporterManager> mReporterManager;
- ContentParent* Owner()
- {
- return static_cast<ContentParent*>(Manager());
- }
- };
- MemoryReportRequestParent::MemoryReportRequestParent(uint32_t aGeneration)
- : mGeneration(aGeneration)
- {
- MOZ_COUNT_CTOR(MemoryReportRequestParent);
- mReporterManager = nsMemoryReporterManager::GetOrCreate();
- NS_WARNING_ASSERTION(mReporterManager, "GetOrCreate failed");
- }
- bool
- MemoryReportRequestParent::RecvReport(const MemoryReport& aReport)
- {
- if (mReporterManager) {
- mReporterManager->HandleChildReport(mGeneration, aReport);
- }
- return true;
- }
- bool
- MemoryReportRequestParent::Recv__delete__()
- {
- // Notifying the reporter manager is done in ActorDestroy, because
- // it needs to happen even if the child process exits mid-report.
- // (The reporter manager will time out eventually, but let's avoid
- // that if possible.)
- return true;
- }
- void
- MemoryReportRequestParent::ActorDestroy(ActorDestroyReason aWhy)
- {
- if (mReporterManager) {
- mReporterManager->EndProcessReport(mGeneration, aWhy == Deletion);
- mReporterManager = nullptr;
- }
- }
- MemoryReportRequestParent::~MemoryReportRequestParent()
- {
- MOZ_ASSERT(!mReporterManager);
- MOZ_COUNT_DTOR(MemoryReportRequestParent);
- }
- // IPC receiver for remote GC/CC logging.
- class CycleCollectWithLogsParent final : public PCycleCollectWithLogsParent
- {
- public:
- ~CycleCollectWithLogsParent()
- {
- MOZ_COUNT_DTOR(CycleCollectWithLogsParent);
- }
- static bool AllocAndSendConstructor(ContentParent* aManager,
- bool aDumpAllTraces,
- nsICycleCollectorLogSink* aSink,
- nsIDumpGCAndCCLogsCallback* aCallback)
- {
- CycleCollectWithLogsParent *actor;
- FILE* gcLog;
- FILE* ccLog;
- nsresult rv;
- actor = new CycleCollectWithLogsParent(aSink, aCallback);
- rv = actor->mSink->Open(&gcLog, &ccLog);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- delete actor;
- return false;
- }
- return aManager->
- SendPCycleCollectWithLogsConstructor(actor,
- aDumpAllTraces,
- FILEToFileDescriptor(gcLog),
- FILEToFileDescriptor(ccLog));
- }
- private:
- virtual bool RecvCloseGCLog() override
- {
- Unused << mSink->CloseGCLog();
- return true;
- }
- virtual bool RecvCloseCCLog() override
- {
- Unused << mSink->CloseCCLog();
- return true;
- }
- virtual bool Recv__delete__() override
- {
- // Report completion to mCallback only on successful
- // completion of the protocol.
- nsCOMPtr<nsIFile> gcLog, ccLog;
- mSink->GetGcLog(getter_AddRefs(gcLog));
- mSink->GetCcLog(getter_AddRefs(ccLog));
- Unused << mCallback->OnDump(gcLog, ccLog, /* parent = */ false);
- return true;
- }
- virtual void ActorDestroy(ActorDestroyReason aReason) override
- {
- // If the actor is unexpectedly destroyed, we deliberately
- // don't call Close[GC]CLog on the sink, because the logs may
- // be incomplete. See also the nsCycleCollectorLogSinkToFile
- // implementaiton of those methods, and its destructor.
- }
- CycleCollectWithLogsParent(nsICycleCollectorLogSink *aSink,
- nsIDumpGCAndCCLogsCallback *aCallback)
- : mSink(aSink), mCallback(aCallback)
- {
- MOZ_COUNT_CTOR(CycleCollectWithLogsParent);
- }
- nsCOMPtr<nsICycleCollectorLogSink> mSink;
- nsCOMPtr<nsIDumpGCAndCCLogsCallback> mCallback;
- };
- // A memory reporter for ContentParent objects themselves.
- class ContentParentsMemoryReporter final : public nsIMemoryReporter
- {
- ~ContentParentsMemoryReporter() {}
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIMEMORYREPORTER
- };
- NS_IMPL_ISUPPORTS(ContentParentsMemoryReporter, nsIMemoryReporter)
- NS_IMETHODIMP
- ContentParentsMemoryReporter::CollectReports(
- nsIHandleReportCallback* aHandleReport,
- nsISupports* aData,
- bool aAnonymize)
- {
- AutoTArray<ContentParent*, 16> cps;
- ContentParent::GetAllEvenIfDead(cps);
- for (uint32_t i = 0; i < cps.Length(); i++) {
- ContentParent* cp = cps[i];
- MessageChannel* channel = cp->GetIPCChannel();
- nsString friendlyName;
- cp->FriendlyName(friendlyName, aAnonymize);
- cp->AddRef();
- nsrefcnt refcnt = cp->Release();
- const char* channelStr = "no channel";
- uint32_t numQueuedMessages = 0;
- if (channel) {
- if (channel->Unsound_IsClosed()) {
- channelStr = "closed channel";
- } else {
- channelStr = "open channel";
- }
- numQueuedMessages = channel->Unsound_NumQueuedMessages();
- }
- nsPrintfCString path("queued-ipc-messages/content-parent"
- "(%s, pid=%d, %s, 0x%p, refcnt=%d)",
- NS_ConvertUTF16toUTF8(friendlyName).get(),
- cp->Pid(), channelStr,
- static_cast<nsIContentParent*>(cp), refcnt);
- NS_NAMED_LITERAL_CSTRING(desc,
- "The number of unset IPC messages held in this ContentParent's "
- "channel. A large value here might indicate that we're leaking "
- "messages. Similarly, a ContentParent object for a process that's no "
- "longer running could indicate that we're leaking ContentParents.");
- aHandleReport->Callback(/* process */ EmptyCString(), path,
- KIND_OTHER, UNITS_COUNT,
- numQueuedMessages, desc, aData);
- }
- return NS_OK;
- }
- nsDataHashtable<nsStringHashKey, ContentParent*>* ContentParent::sAppContentParents;
- nsTArray<ContentParent*>* ContentParent::sNonAppContentParents;
- nsTArray<ContentParent*>* ContentParent::sLargeAllocationContentParents;
- nsTArray<ContentParent*>* ContentParent::sPrivateContent;
- StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
- // This is true when subprocess launching is enabled. This is the
- // case between StartUp() and ShutDown() or JoinAllSubprocesses().
- static bool sCanLaunchSubprocesses;
- // Set to true if the DISABLE_UNSAFE_CPOW_WARNINGS environment variable is
- // set.
- static bool sDisableUnsafeCPOWWarnings = false;
- // The first content child has ID 1, so the chrome process can have ID 0.
- static uint64_t gContentChildID = 1;
- // We want the prelaunched process to know that it's for apps, but not
- // actually for any app in particular. Use a magic manifest URL.
- // Can't be a static constant.
- #define MAGIC_PREALLOCATED_APP_MANIFEST_URL NS_LITERAL_STRING("{{template}}")
- static const char* sObserverTopics[] = {
- "xpcom-shutdown",
- "profile-before-change",
- NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC,
- NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC,
- NS_IPC_CAPTIVE_PORTAL_SET_STATE,
- "memory-pressure",
- "child-gc-request",
- "child-cc-request",
- "child-mmu-request",
- "last-pb-context-exited",
- "file-watcher-update",
- #ifdef ACCESSIBILITY
- "a11y-init-or-shutdown",
- #endif
- "cacheservice:empty-cache",
- };
- // PreallocateAppProcess is called by the PreallocatedProcessManager.
- // ContentParent then takes this process back within
- // GetNewOrPreallocatedAppProcess.
- /*static*/ already_AddRefed<ContentParent>
- ContentParent::PreallocateAppProcess()
- {
- RefPtr<ContentParent> process =
- new ContentParent(/* app = */ nullptr,
- /* aOpener = */ nullptr,
- /* isForBrowserElement = */ false,
- /* isForPreallocated = */ true);
- if (!process->LaunchSubprocess(PROCESS_PRIORITY_PREALLOC)) {
- return nullptr;
- }
- process->Init();
- return process.forget();
- }
- /*static*/ already_AddRefed<ContentParent>
- ContentParent::GetNewOrPreallocatedAppProcess(mozIApplication* aApp,
- ProcessPriority aInitialPriority,
- ContentParent* aOpener,
- /*out*/ bool* aTookPreAllocated)
- {
- MOZ_ASSERT(aApp);
- RefPtr<ContentParent> process = PreallocatedProcessManager::Take();
- if (process) {
- if (!process->SetPriorityAndCheckIsAlive(aInitialPriority)) {
- // Kill the process just in case it's not actually dead; we don't want
- // to "leak" this process!
- process->KillHard("GetNewOrPreallocatedAppProcess");
- }
- else {
- nsAutoString manifestURL;
- if (NS_FAILED(aApp->GetManifestURL(manifestURL))) {
- NS_ERROR("Failed to get manifest URL");
- return nullptr;
- }
- process->TransformPreallocatedIntoApp(aOpener, manifestURL);
- process->ForwardKnownInfo();
- if (aTookPreAllocated) {
- *aTookPreAllocated = true;
- }
- return process.forget();
- }
- }
- NS_WARNING("Unable to use pre-allocated app process");
- process = new ContentParent(aApp,
- /* aOpener = */ aOpener,
- /* isForBrowserElement = */ false,
- /* isForPreallocated = */ false);
- if (!process->LaunchSubprocess(aInitialPriority)) {
- return nullptr;
- }
- process->Init();
- process->ForwardKnownInfo();
- if (aTookPreAllocated) {
- *aTookPreAllocated = false;
- }
- return process.forget();
- }
- /*static*/ void
- ContentParent::StartUp()
- {
- // We could launch sub processes from content process
- // FIXME Bug 1023701 - Stop using ContentParent static methods in
- // child process
- sCanLaunchSubprocesses = true;
- if (!XRE_IsParentProcess()) {
- return;
- }
- // Note: This reporter measures all ContentParents.
- RegisterStrongMemoryReporter(new ContentParentsMemoryReporter());
- mozilla::dom::time::InitializeDateCacheCleaner();
- BlobParent::Startup(BlobParent::FriendKey());
- BackgroundChild::Startup();
- // Try to preallocate a process that we can transform into an app later.
- PreallocatedProcessManager::AllocateAfterDelay();
- sDisableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
- }
- /*static*/ void
- ContentParent::ShutDown()
- {
- // No-op for now. We rely on normal process shutdown and
- // ClearOnShutdown() to clean up our state.
- sCanLaunchSubprocesses = false;
- }
- /*static*/ void
- ContentParent::JoinProcessesIOThread(const nsTArray<ContentParent*>* aProcesses,
- Monitor* aMonitor, bool* aDone)
- {
- const nsTArray<ContentParent*>& processes = *aProcesses;
- for (uint32_t i = 0; i < processes.Length(); ++i) {
- if (GeckoChildProcessHost* process = processes[i]->mSubprocess) {
- process->Join();
- }
- }
- {
- MonitorAutoLock lock(*aMonitor);
- *aDone = true;
- lock.Notify();
- }
- // Don't touch any arguments to this function from now on.
- }
- /*static*/ void
- ContentParent::JoinAllSubprocesses()
- {
- MOZ_ASSERT(NS_IsMainThread());
- AutoTArray<ContentParent*, 8> processes;
- GetAll(processes);
- if (processes.IsEmpty()) {
- printf_stderr("There are no live subprocesses.");
- return;
- }
- printf_stderr("Subprocesses are still alive. Doing emergency join.\n");
- bool done = false;
- Monitor monitor("mozilla.dom.ContentParent.JoinAllSubprocesses");
- XRE_GetIOMessageLoop()->PostTask(NewRunnableFunction(
- &ContentParent::JoinProcessesIOThread,
- &processes, &monitor, &done));
- {
- MonitorAutoLock lock(monitor);
- while (!done) {
- lock.Wait();
- }
- }
- sCanLaunchSubprocesses = false;
- }
- /*static*/ already_AddRefed<ContentParent>
- ContentParent::GetNewOrUsedBrowserProcess(bool aForBrowserElement,
- ProcessPriority aPriority,
- ContentParent* aOpener,
- bool aLargeAllocationProcess)
- {
- nsTArray<ContentParent*>* contentParents;
- int32_t maxContentParents;
- // Decide which pool of content parents we are going to be pulling from based
- // on the aLargeAllocationProcess flag.
- if (aLargeAllocationProcess) {
- if (!sLargeAllocationContentParents) {
- sLargeAllocationContentParents = new nsTArray<ContentParent*>();
- }
- contentParents = sLargeAllocationContentParents;
- maxContentParents = Preferences::GetInt("dom.ipc.dedicatedProcessCount", 2);
- } else {
- if (!sNonAppContentParents) {
- sNonAppContentParents = new nsTArray<ContentParent*>();
- }
- contentParents = sNonAppContentParents;
- maxContentParents = Preferences::GetInt("dom.ipc.processCount", 1);
- }
- if (maxContentParents < 1) {
- maxContentParents = 1;
- }
- if (contentParents->Length() >= uint32_t(maxContentParents)) {
- uint32_t maxSelectable = std::min(static_cast<uint32_t>(contentParents->Length()),
- static_cast<uint32_t>(maxContentParents));
- uint32_t startIdx = rand() % maxSelectable;
- uint32_t currIdx = startIdx;
- do {
- RefPtr<ContentParent> p = (*contentParents)[currIdx];
- NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in sNonAppContntParents?");
- if (p->mOpener == aOpener) {
- return p.forget();
- }
- currIdx = (currIdx + 1) % maxSelectable;
- } while (currIdx != startIdx);
- }
- // Try to take and transform the preallocated process into browser.
- RefPtr<ContentParent> p = PreallocatedProcessManager::Take();
- if (p) {
- p->TransformPreallocatedIntoBrowser(aOpener);
- } else {
- // Failed in using the preallocated process: fork from the chrome process.
- p = new ContentParent(/* app = */ nullptr,
- aOpener,
- aForBrowserElement,
- /* isForPreallocated = */ false);
- if (!p->LaunchSubprocess(aPriority)) {
- return nullptr;
- }
- p->Init();
- }
- p->mLargeAllocationProcess = aLargeAllocationProcess;
- p->ForwardKnownInfo();
- contentParents->AppendElement(p);
- return p.forget();
- }
- /*static*/ ProcessPriority
- ContentParent::GetInitialProcessPriority(Element* aFrameElement)
- {
- // Frames with mozapptype == critical which are expecting a system message
- // get FOREGROUND_HIGH priority.
- if (!aFrameElement) {
- return PROCESS_PRIORITY_FOREGROUND;
- }
- if (aFrameElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::mozapptype,
- NS_LITERAL_STRING("inputmethod"), eCaseMatters)) {
- return PROCESS_PRIORITY_FOREGROUND_KEYBOARD;
- } else if (!aFrameElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::mozapptype,
- NS_LITERAL_STRING("critical"), eCaseMatters)) {
- return PROCESS_PRIORITY_FOREGROUND;
- }
- nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(aFrameElement);
- if (!browserFrame) {
- return PROCESS_PRIORITY_FOREGROUND;
- }
- return PROCESS_PRIORITY_FOREGROUND;
- }
- #if defined(XP_WIN)
- extern const wchar_t* kPluginWidgetContentParentProperty;
- /*static*/ void
- ContentParent::SendAsyncUpdate(nsIWidget* aWidget)
- {
- if (!aWidget || aWidget->Destroyed()) {
- return;
- }
- // Fire off an async request to the plugin to paint its window
- HWND hwnd = (HWND)aWidget->GetNativeData(NS_NATIVE_WINDOW);
- NS_ASSERTION(hwnd, "Expected valid hwnd value.");
- ContentParent* cp = reinterpret_cast<ContentParent*>(
- ::GetPropW(hwnd, kPluginWidgetContentParentProperty));
- if (cp && !cp->IsDestroyed()) {
- Unused << cp->SendUpdateWindow((uintptr_t)hwnd);
- }
- }
- #endif // defined(XP_WIN)
- bool
- ContentParent::PreallocatedProcessReady()
- {
- return true;
- }
- bool
- ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
- const hal::ProcessPriority& aPriority,
- const TabId& aOpenerTabId,
- ContentParentId* aCpId,
- bool* aIsForApp,
- bool* aIsForBrowser,
- TabId* aTabId)
- {
- #if 0
- if (!CanOpenBrowser(aContext)) {
- return false;
- }
- #endif
- RefPtr<ContentParent> cp;
- MaybeInvalidTabContext tc(aContext);
- if (!tc.IsValid()) {
- NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
- "the child process. (%s)",
- tc.GetInvalidReason()).get());
- return false;
- }
- nsCOMPtr<mozIApplication> ownApp = tc.GetTabContext().GetOwnApp();
- if (ownApp) {
- cp = GetNewOrPreallocatedAppProcess(ownApp, aPriority, this);
- }
- else {
- cp = GetNewOrUsedBrowserProcess(/* isBrowserElement = */ true,
- aPriority, this);
- }
- if (!cp) {
- *aCpId = 0;
- *aIsForApp = false;
- *aIsForBrowser = false;
- return true;
- }
- *aCpId = cp->ChildID();
- *aIsForApp = cp->IsForApp();
- *aIsForBrowser = cp->IsForBrowser();
- ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
- cpm->AddContentProcess(cp, this->ChildID());
- if (cpm->AddGrandchildProcess(this->ChildID(), cp->ChildID())) {
- // Pre-allocate a TabId here to save one time IPC call at app startup.
- *aTabId = AllocateTabId(aOpenerTabId, aContext, cp->ChildID());
- return (*aTabId != 0);
- }
- return false;
- }
- bool
- ContentParent::RecvBridgeToChildProcess(const ContentParentId& aCpId)
- {
- ContentProcessManager *cpm = ContentProcessManager::GetSingleton();
- ContentParent* cp = cpm->GetContentProcessById(aCpId);
- if (cp) {
- ContentParentId parentId;
- if (cpm->GetParentProcessId(cp->ChildID(), &parentId) &&
- parentId == this->ChildID()) {
- return NS_SUCCEEDED(PContentBridge::Bridge(this, cp));
- }
- }
- // You can't bridge to a process you didn't open!
- KillHard("BridgeToChildProcess");
- return false;
- }
- static nsIDocShell* GetOpenerDocShellHelper(Element* aFrameElement)
- {
- // Propagate the private-browsing status of the element's parent
- // docshell to the remote docshell, via the chrome flags.
- nsCOMPtr<Element> frameElement = do_QueryInterface(aFrameElement);
- MOZ_ASSERT(frameElement);
- nsPIDOMWindowOuter* win = frameElement->OwnerDoc()->GetWindow();
- if (!win) {
- NS_WARNING("Remote frame has no window");
- return nullptr;
- }
- nsIDocShell* docShell = win->GetDocShell();
- if (!docShell) {
- NS_WARNING("Remote frame has no docshell");
- return nullptr;
- }
- return docShell;
- }
- bool
- ContentParent::RecvCreateGMPService()
- {
- return PGMPService::Open(this);
- }
- bool
- ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv, uint32_t* aRunID)
- {
- *aRv = NS_OK;
- return mozilla::plugins::SetupBridge(aPluginId, this, false, aRv, aRunID);
- }
- bool
- ContentParent::RecvUngrabPointer(const uint32_t& aTime)
- {
- #if !defined(MOZ_WIDGET_GTK)
- NS_RUNTIMEABORT("This message only makes sense on GTK platforms");
- return false;
- #else
- gdk_pointer_ungrab(aTime);
- return true;
- #endif
- }
- bool
- ContentParent::RecvRemovePermission(const IPC::Principal& aPrincipal,
- const nsCString& aPermissionType,
- nsresult* aRv) {
- *aRv = Permissions::RemovePermission(aPrincipal, aPermissionType.get());
- return true;
- }
- bool
- ContentParent::RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv)
- {
- *aRv = NS_OK;
- // We don't need to get the run ID for the plugin, since we already got it
- // in the first call to SetupBridge in RecvLoadPlugin, so we pass in a dummy
- // pointer and just throw it away.
- uint32_t dummy = 0;
- return mozilla::plugins::SetupBridge(aPluginId, this, true, aRv, &dummy);
- }
- bool
- ContentParent::RecvGetBlocklistState(const uint32_t& aPluginId,
- uint32_t* aState)
- {
- *aState = nsIBlocklistService::STATE_BLOCKED;
- RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
- if (!pluginHost) {
- NS_WARNING("Plugin host not found");
- return false;
- }
- nsPluginTag* tag = pluginHost->PluginWithId(aPluginId);
- if (!tag) {
- // Default state is blocked anyway
- NS_WARNING("Plugin tag not found. This should never happen, but to avoid a crash we're forcibly blocking it");
- return true;
- }
- return NS_SUCCEEDED(tag->GetBlocklistState(aState));
- }
- bool
- ContentParent::RecvFindPlugins(const uint32_t& aPluginEpoch,
- nsresult* aRv,
- nsTArray<PluginTag>* aPlugins,
- uint32_t* aNewPluginEpoch)
- {
- *aRv = mozilla::plugins::FindPluginsForContent(aPluginEpoch, aPlugins, aNewPluginEpoch);
- return true;
- }
- /*static*/ TabParent*
- ContentParent::CreateBrowserOrApp(const TabContext& aContext,
- Element* aFrameElement,
- ContentParent* aOpenerContentParent,
- bool aFreshProcess)
- {
- PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
- if (!sCanLaunchSubprocesses) {
- return nullptr;
- }
- if (TabParent* parent = TabParent::GetNextTabParent()) {
- parent->SetOwnerElement(aFrameElement);
- return parent;
- }
- ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
- bool isInContentProcess = !XRE_IsParentProcess();
- TabId tabId;
- nsIDocShell* docShell = GetOpenerDocShellHelper(aFrameElement);
- TabId openerTabId;
- if (docShell) {
- openerTabId = TabParent::GetTabIdFrom(docShell);
- }
- if (aContext.IsMozBrowserElement() || !aContext.HasOwnApp()) {
- RefPtr<nsIContentParent> constructorSender;
- if (isInContentProcess) {
- MOZ_ASSERT(aContext.IsMozBrowserElement());
- constructorSender = CreateContentBridgeParent(aContext, initialPriority,
- openerTabId, &tabId);
- } else {
- if (aOpenerContentParent) {
- constructorSender = aOpenerContentParent;
- } else {
- constructorSender =
- GetNewOrUsedBrowserProcess(aContext.IsMozBrowserElement(),
- initialPriority,
- nullptr,
- aFreshProcess);
- if (!constructorSender) {
- return nullptr;
- }
- }
- tabId = AllocateTabId(openerTabId,
- aContext.AsIPCTabContext(),
- constructorSender->ChildID());
- }
- if (constructorSender) {
- nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
- docShell->GetTreeOwner(getter_AddRefs(treeOwner));
- if (!treeOwner) {
- return nullptr;
- }
- nsCOMPtr<nsIWebBrowserChrome> wbc = do_GetInterface(treeOwner);
- if (!wbc) {
- return nullptr;
- }
- uint32_t chromeFlags = 0;
- wbc->GetChromeFlags(&chromeFlags);
- nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
- if (loadContext && loadContext->UsePrivateBrowsing()) {
- chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
- }
- if (docShell->GetAffectPrivateSessionLifetime()) {
- chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME;
- }
- if (tabId == 0) {
- return nullptr;
- }
- RefPtr<TabParent> tp(new TabParent(constructorSender, tabId,
- aContext, chromeFlags));
- tp->SetInitedByParent();
- PBrowserParent* browser =
- constructorSender->SendPBrowserConstructor(
- // DeallocPBrowserParent() releases this ref.
- tp.forget().take(), tabId,
- aContext.AsIPCTabContext(),
- chromeFlags,
- constructorSender->ChildID(),
- constructorSender->IsForApp(),
- constructorSender->IsForBrowser());
- if (aFreshProcess) {
- Unused << browser->SendSetFreshProcess();
- }
- if (browser) {
- RefPtr<TabParent> constructedTabParent = TabParent::GetFrom(browser);
- constructedTabParent->SetOwnerElement(aFrameElement);
- return constructedTabParent;
- }
- }
- return nullptr;
- }
- // If we got here, we have an app and we're not a browser element. ownApp
- // shouldn't be null, because we otherwise would have gone into the
- // !HasOwnApp() branch above.
- RefPtr<nsIContentParent> parent;
- bool reused = false;
- bool tookPreallocated = false;
- nsAutoString manifestURL;
- if (isInContentProcess) {
- parent = CreateContentBridgeParent(aContext,
- initialPriority,
- openerTabId,
- &tabId);
- }
- else {
- nsCOMPtr<mozIApplication> ownApp = aContext.GetOwnApp();
- if (!sAppContentParents) {
- sAppContentParents =
- new nsDataHashtable<nsStringHashKey, ContentParent*>();
- }
- // Each app gets its own ContentParent instance unless it shares it with
- // a parent app.
- if (NS_FAILED(ownApp->GetManifestURL(manifestURL))) {
- NS_ERROR("Failed to get manifest URL");
- return nullptr;
- }
- RefPtr<ContentParent> p = sAppContentParents->Get(manifestURL);
- if (!p && Preferences::GetBool("dom.ipc.reuse_parent_app")) {
- nsAutoString parentAppManifestURL;
- aFrameElement->GetAttr(kNameSpaceID_None,
- nsGkAtoms::parentapp, parentAppManifestURL);
- nsAdoptingString systemAppManifestURL =
- Preferences::GetString("b2g.system_manifest_url");
- nsCOMPtr<nsIAppsService> appsService =
- do_GetService(APPS_SERVICE_CONTRACTID);
- if (!parentAppManifestURL.IsEmpty() &&
- !parentAppManifestURL.Equals(systemAppManifestURL) &&
- appsService) {
- nsCOMPtr<mozIApplication> parentApp;
- nsCOMPtr<mozIApplication> app;
- appsService->GetAppByManifestURL(parentAppManifestURL,
- getter_AddRefs(parentApp));
- appsService->GetAppByManifestURL(manifestURL,
- getter_AddRefs(app));
- // Only let certified apps re-use the same process.
- unsigned short parentAppStatus = 0;
- unsigned short appStatus = 0;
- if (app &&
- NS_SUCCEEDED(app->GetAppStatus(&appStatus)) &&
- appStatus == nsIPrincipal::APP_STATUS_CERTIFIED &&
- parentApp &&
- NS_SUCCEEDED(parentApp->GetAppStatus(&parentAppStatus)) &&
- parentAppStatus == nsIPrincipal::APP_STATUS_CERTIFIED) {
- // Check if we can re-use the process of the parent app.
- p = sAppContentParents->Get(parentAppManifestURL);
- }
- }
- }
- if (p) {
- // Check that the process is still alive and set its priority.
- // Hopefully the process won't die after this point, if this call
- // succeeds.
- if (!p->SetPriorityAndCheckIsAlive(initialPriority)) {
- p = nullptr;
- }
- }
- reused = !!p;
- if (!p) {
- p = GetNewOrPreallocatedAppProcess(ownApp, initialPriority, nullptr,
- &tookPreallocated);
- MOZ_ASSERT(p);
- sAppContentParents->Put(manifestURL, p);
- }
- tabId = AllocateTabId(openerTabId, aContext.AsIPCTabContext(),
- p->ChildID());
- parent = static_cast<nsIContentParent*>(p);
- }
- if (!parent || (tabId == 0)) {
- return nullptr;
- }
- uint32_t chromeFlags = 0;
- RefPtr<TabParent> tp = new TabParent(parent, tabId, aContext, chromeFlags);
- tp->SetInitedByParent();
- PBrowserParent* browser = parent->SendPBrowserConstructor(
- // DeallocPBrowserParent() releases this ref.
- RefPtr<TabParent>(tp).forget().take(),
- tabId,
- aContext.AsIPCTabContext(),
- chromeFlags,
- parent->ChildID(),
- parent->IsForApp(),
- parent->IsForBrowser());
- if (aFreshProcess) {
- Unused << browser->SendSetFreshProcess();
- }
- if (browser) {
- RefPtr<TabParent> constructedTabParent = TabParent::GetFrom(browser);
- constructedTabParent->SetOwnerElement(aFrameElement);
- }
- if (isInContentProcess) {
- // Just return directly without the following check in content process.
- return TabParent::GetFrom(browser);
- }
- if (!browser) {
- // We failed to actually start the PBrowser. This can happen if the
- // other process has already died.
- if (!reused) {
- // Don't leave a broken ContentParent in the hashtable.
- parent->AsContentParent()->KillHard("CreateBrowserOrApp");
- sAppContentParents->Remove(manifestURL);
- parent = nullptr;
- }
- // If we took the preallocated process and it was already dead, try
- // again with a non-preallocated process. We can be sure this won't
- // loop forever, because the next time through there will be no
- // preallocated process to take.
- if (tookPreallocated) {
- return ContentParent::CreateBrowserOrApp(aContext, aFrameElement,
- aOpenerContentParent);
- }
- // Otherwise just give up.
- return nullptr;
- }
- return TabParent::GetFrom(browser);
- }
- /*static*/ ContentBridgeParent*
- ContentParent::CreateContentBridgeParent(const TabContext& aContext,
- const hal::ProcessPriority& aPriority,
- const TabId& aOpenerTabId,
- /*out*/ TabId* aTabId)
- {
- MOZ_ASSERT(aTabId);
- ContentChild* child = ContentChild::GetSingleton();
- ContentParentId cpId;
- bool isForApp;
- bool isForBrowser;
- if (!child->SendCreateChildProcess(aContext.AsIPCTabContext(),
- aPriority,
- aOpenerTabId,
- &cpId,
- &isForApp,
- &isForBrowser,
- aTabId)) {
- return nullptr;
- }
- if (cpId == 0) {
- return nullptr;
- }
- if (!child->SendBridgeToChildProcess(cpId)) {
- return nullptr;
- }
- ContentBridgeParent* parent = child->GetLastBridge();
- parent->SetChildID(cpId);
- parent->SetIsForApp(isForApp);
- parent->SetIsForBrowser(isForBrowser);
- return parent;
- }
- void
- ContentParent::GetAll(nsTArray<ContentParent*>& aArray)
- {
- aArray.Clear();
- for (auto* cp : AllProcesses(eLive)) {
- aArray.AppendElement(cp);
- }
- }
- void
- ContentParent::GetAllEvenIfDead(nsTArray<ContentParent*>& aArray)
- {
- aArray.Clear();
- for (auto* cp : AllProcesses(eAll)) {
- aArray.AppendElement(cp);
- }
- }
- void
- ContentParent::Init()
- {
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- size_t length = ArrayLength(sObserverTopics);
- for (size_t i = 0; i < length; ++i) {
- obs->AddObserver(this, sObserverTopics[i], false);
- }
- }
- Preferences::AddStrongObserver(this, "");
- if (obs) {
- nsAutoString cpId;
- cpId.AppendInt(static_cast<uint64_t>(this->ChildID()));
- obs->NotifyObservers(static_cast<nsIObserver*>(this), "ipc:content-created", cpId.get());
- }
- #ifdef ACCESSIBILITY
- // If accessibility is running in chrome process then start it in content
- // process.
- if (nsIPresShell::IsAccessibilityActive()) {
- #if !defined(XP_WIN)
- Unused << SendActivateA11y(0);
- #endif
- }
- #endif
- RefPtr<GeckoMediaPluginServiceParent> gmps(GeckoMediaPluginServiceParent::GetSingleton());
- gmps->UpdateContentProcessGMPCapabilities();
- }
- void
- ContentParent::ForwardKnownInfo()
- {
- MOZ_ASSERT(mMetamorphosed);
- if (!mMetamorphosed) {
- return;
- }
- }
- namespace {
- class RemoteWindowContext final : public nsIRemoteWindowContext
- , public nsIInterfaceRequestor
- {
- public:
- explicit RemoteWindowContext(TabParent* aTabParent)
- : mTabParent(aTabParent)
- {
- }
- NS_DECL_ISUPPORTS
- NS_DECL_NSIINTERFACEREQUESTOR
- NS_DECL_NSIREMOTEWINDOWCONTEXT
- private:
- ~RemoteWindowContext();
- RefPtr<TabParent> mTabParent;
- };
- NS_IMPL_ISUPPORTS(RemoteWindowContext, nsIRemoteWindowContext, nsIInterfaceRequestor)
- RemoteWindowContext::~RemoteWindowContext()
- {
- }
- NS_IMETHODIMP
- RemoteWindowContext::GetInterface(const nsIID& aIID, void** aSink)
- {
- return QueryInterface(aIID, aSink);
- }
- NS_IMETHODIMP
- RemoteWindowContext::OpenURI(nsIURI* aURI)
- {
- mTabParent->LoadURL(aURI);
- return NS_OK;
- }
- } // namespace
- bool
- ContentParent::SetPriorityAndCheckIsAlive(ProcessPriority aPriority)
- {
- ProcessPriorityManager::SetProcessPriority(this, aPriority);
- return true;
- }
- // Helper for ContentParent::TransformPreallocatedIntoApp.
- static void
- TryGetNameFromManifestURL(const nsAString& aManifestURL,
- nsAString& aName)
- {
- aName.Truncate();
- if (aManifestURL.IsEmpty() ||
- aManifestURL == MAGIC_PREALLOCATED_APP_MANIFEST_URL) {
- return;
- }
- nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
- NS_ENSURE_TRUE_VOID(appsService);
- nsCOMPtr<mozIApplication> app;
- appsService->GetAppByManifestURL(aManifestURL, getter_AddRefs(app));
- if (!app) {
- return;
- }
- app->GetName(aName);
- }
- void
- ContentParent::TransformPreallocatedIntoApp(ContentParent* aOpener,
- const nsAString& aAppManifestURL)
- {
- MOZ_ASSERT(IsPreallocated());
- mMetamorphosed = true;
- mOpener = aOpener;
- mAppManifestURL = aAppManifestURL;
- TryGetNameFromManifestURL(aAppManifestURL, mAppName);
- }
- void
- ContentParent::TransformPreallocatedIntoBrowser(ContentParent* aOpener)
- {
- // Reset mAppManifestURL, mIsForBrowser and mOSPrivileges for browser.
- mMetamorphosed = true;
- mOpener = aOpener;
- mAppManifestURL.Truncate();
- mIsForBrowser = true;
- }
- void
- ContentParent::ShutDownProcess(ShutDownMethod aMethod)
- {
- // Shutting down by sending a shutdown message works differently than the
- // other methods. We first call Shutdown() in the child. After the child is
- // ready, it calls FinishShutdown() on us. Then we close the channel.
- if (aMethod == SEND_SHUTDOWN_MESSAGE) {
- if (mIPCOpen && !mShutdownPending && SendShutdown()) {
- mShutdownPending = true;
- // Start the force-kill timer if we haven't already.
- StartForceKillTimer();
- }
- // If call was not successful, the channel must have been broken
- // somehow, and we will clean up the error in ActorDestroy.
- return;
- }
- using mozilla::dom::quota::QuotaManagerService;
- if (QuotaManagerService* quotaManagerService = QuotaManagerService::Get()) {
- quotaManagerService->AbortOperationsForProcess(mChildID);
- }
- // If Close() fails with an error, we'll end up back in this function, but
- // with aMethod = CLOSE_CHANNEL_WITH_ERROR.
- if (aMethod == CLOSE_CHANNEL && !mCalledClose) {
- // Close() can only be called once: It kicks off the destruction
- // sequence.
- mCalledClose = true;
- Close();
- }
- const ManagedContainer<POfflineCacheUpdateParent>& ocuParents =
- ManagedPOfflineCacheUpdateParent();
- for (auto iter = ocuParents.ConstIter(); !iter.Done(); iter.Next()) {
- RefPtr<mozilla::docshell::OfflineCacheUpdateParent> ocuParent =
- static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(iter.Get()->GetKey());
- ocuParent->StopSendingMessagesToChild();
- }
- // NB: must MarkAsDead() here so that this isn't accidentally
- // returned from Get*() while in the midst of shutdown.
- MarkAsDead();
- // A ContentParent object might not get freed until after XPCOM shutdown has
- // shut down the cycle collector. But by then it's too late to release any
- // CC'ed objects, so we need to null them out here, while we still can. See
- // bug 899761.
- ShutDownMessageManager();
- }
- bool
- ContentParent::RecvFinishShutdown()
- {
- // At this point, we already called ShutDownProcess once with
- // SEND_SHUTDOWN_MESSAGE. To actually close the channel, we call
- // ShutDownProcess again with CLOSE_CHANNEL.
- MOZ_ASSERT(mShutdownPending);
- ShutDownProcess(CLOSE_CHANNEL);
- return true;
- }
- void
- ContentParent::ShutDownMessageManager()
- {
- if (!mMessageManager) {
- return;
- }
- mMessageManager->ReceiveMessage(
- static_cast<nsIContentFrameMessageManager*>(mMessageManager.get()), nullptr,
- CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
- nullptr, nullptr, nullptr, nullptr);
- mMessageManager->Disconnect();
- mMessageManager = nullptr;
- }
- void
- ContentParent::MarkAsDead()
- {
- if (!mAppManifestURL.IsEmpty()) {
- if (sAppContentParents) {
- sAppContentParents->Remove(mAppManifestURL);
- if (!sAppContentParents->Count()) {
- delete sAppContentParents;
- sAppContentParents = nullptr;
- }
- }
- } else {
- if (sNonAppContentParents) {
- sNonAppContentParents->RemoveElement(this);
- if (!sNonAppContentParents->Length()) {
- delete sNonAppContentParents;
- sNonAppContentParents = nullptr;
- }
- }
- if (sLargeAllocationContentParents) {
- sLargeAllocationContentParents->RemoveElement(this);
- if (!sLargeAllocationContentParents->Length()) {
- delete sLargeAllocationContentParents;
- sLargeAllocationContentParents = nullptr;
- }
- }
- }
- if (sPrivateContent) {
- sPrivateContent->RemoveElement(this);
- if (!sPrivateContent->Length()) {
- delete sPrivateContent;
- sPrivateContent = nullptr;
- }
- }
- mIsAlive = false;
- }
- void
- ContentParent::OnChannelError()
- {
- RefPtr<ContentParent> content(this);
- PContentParent::OnChannelError();
- }
- void
- ContentParent::OnChannelConnected(int32_t pid)
- {
- SetOtherProcessId(pid);
- #if defined(LINUX)
- // Check nice preference
- int32_t nice = Preferences::GetInt("dom.ipc.content.nice", 0);
- // Environment variable overrides preference
- char* relativeNicenessStr = getenv("MOZ_CHILD_PROCESS_RELATIVE_NICENESS");
- if (relativeNicenessStr) {
- nice = atoi(relativeNicenessStr);
- }
- /* make the GUI thread have higher priority on single-cpu devices */
- nsCOMPtr<nsIPropertyBag2> infoService = do_GetService(NS_SYSTEMINFO_CONTRACTID);
- if (infoService) {
- int32_t cpus;
- nsresult rv = infoService->GetPropertyAsInt32(NS_LITERAL_STRING("cpucount"), &cpus);
- if (NS_FAILED(rv)) {
- cpus = 1;
- }
- if (nice != 0 && cpus == 1) {
- setpriority(PRIO_PROCESS, pid, getpriority(PRIO_PROCESS, pid) + nice);
- }
- }
- #endif
- }
- void
- ContentParent::ProcessingError(Result aCode, const char* aReason)
- {
- if (MsgDropped == aCode) {
- return;
- }
- // Other errors are big deals.
- KillHard(aReason);
- }
- /* static */
- bool
- ContentParent::AllocateLayerTreeId(TabParent* aTabParent, uint64_t* aId)
- {
- return AllocateLayerTreeId(aTabParent->Manager()->AsContentParent(),
- aTabParent, aTabParent->GetTabId(), aId);
- }
- /* static */
- bool
- ContentParent::AllocateLayerTreeId(ContentParent* aContent,
- TabParent* aTopLevel, const TabId& aTabId,
- uint64_t* aId)
- {
- GPUProcessManager* gpu = GPUProcessManager::Get();
- *aId = gpu->AllocateLayerTreeId();
- if (!aContent || !aTopLevel) {
- return false;
- }
- gpu->MapLayerTreeId(*aId, aContent->OtherPid());
- if (!gfxPlatform::AsyncPanZoomEnabled()) {
- return true;
- }
- return aContent->SendNotifyLayerAllocated(aTabId, *aId);
- }
- bool
- ContentParent::RecvAllocateLayerTreeId(const ContentParentId& aCpId,
- const TabId& aTabId, uint64_t* aId)
- {
- // Protect against spoofing by a compromised child. aCpId must either
- // correspond to the process that this ContentParent represents or be a
- // child of it.
- ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
- if (ChildID() != aCpId) {
- ContentParentId parent;
- if (!cpm->GetParentProcessId(aCpId, &parent) ||
- ChildID() != parent) {
- return false;
- }
- }
- // GetTopLevelTabParentByProcessAndTabId will make sure that aTabId
- // lives in the process for aCpId.
- RefPtr<ContentParent> contentParent = cpm->GetContentProcessById(aCpId);
- RefPtr<TabParent> browserParent =
- cpm->GetTopLevelTabParentByProcessAndTabId(aCpId, aTabId);
- MOZ_ASSERT(contentParent && browserParent);
- return AllocateLayerTreeId(contentParent, browserParent, aTabId, aId);
- }
- bool
- ContentParent::RecvDeallocateLayerTreeId(const uint64_t& aId)
- {
- GPUProcessManager* gpu = GPUProcessManager::Get();
- if (!gpu->IsLayerTreeIdMapped(aId, OtherPid()))
- {
- // You can't deallocate layer tree ids that you didn't allocate
- KillHard("DeallocateLayerTreeId");
- }
- gpu->UnmapLayerTreeId(aId, OtherPid());
- return true;
- }
- namespace {
- void
- DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
- {
- RefPtr<DeleteTask<GeckoChildProcessHost>> task = new DeleteTask<GeckoChildProcessHost>(aSubprocess);
- XRE_GetIOMessageLoop()->PostTask(task.forget());
- }
- // This runnable only exists to delegate ownership of the
- // ContentParent to this runnable, until it's deleted by the event
- // system.
- struct DelayedDeleteContentParentTask : public Runnable
- {
- explicit DelayedDeleteContentParentTask(ContentParent* aObj) : mObj(aObj) { }
- // No-op
- NS_IMETHOD Run() override { return NS_OK; }
- RefPtr<ContentParent> mObj;
- };
- } // namespace
- void
- ContentParent::ActorDestroy(ActorDestroyReason why)
- {
- if (mForceKillTimer) {
- mForceKillTimer->Cancel();
- mForceKillTimer = nullptr;
- }
- // Signal shutdown completion regardless of error state, so we can
- // finish waiting in the xpcom-shutdown/profile-before-change observer.
- mIPCOpen = false;
- if (mHangMonitorActor) {
- ProcessHangMonitor::RemoveProcess(mHangMonitorActor);
- mHangMonitorActor = nullptr;
- }
- RefPtr<FileSystemSecurity> fss = FileSystemSecurity::Get();
- if (fss) {
- fss->Forget(ChildID());
- }
- if (why == NormalShutdown && !mCalledClose) {
- // If we shut down normally but haven't called Close, assume somebody
- // else called Close on us. In that case, we still need to call
- // ShutDownProcess below to perform other necessary clean up.
- mCalledClose = true;
- }
- // Make sure we always clean up.
- ShutDownProcess(why == NormalShutdown ? CLOSE_CHANNEL
- : CLOSE_CHANNEL_WITH_ERROR);
- RefPtr<ContentParent> kungFuDeathGrip(this);
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- size_t length = ArrayLength(sObserverTopics);
- for (size_t i = 0; i < length; ++i) {
- obs->RemoveObserver(static_cast<nsIObserver*>(this),
- sObserverTopics[i]);
- }
- }
- // remove the global remote preferences observers
- Preferences::RemoveObserver(this, "");
- gfxVars::RemoveReceiver(this);
- if (GPUProcessManager* gpu = GPUProcessManager::Get()) {
- // Note: the manager could have shutdown already.
- gpu->RemoveListener(this);
- }
- RecvRemoveGeolocationListener();
- mConsoleService = nullptr;
- if (obs) {
- RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
- props->SetPropertyAsUint64(NS_LITERAL_STRING("childID"), mChildID);
- if (AbnormalShutdown == why) {
- props->SetPropertyAsBool(NS_LITERAL_STRING("abnormal"), true);
- }
- nsAutoString cpId;
- cpId.AppendInt(static_cast<uint64_t>(this->ChildID()));
- obs->NotifyObservers((nsIPropertyBag2*) props, "ipc:content-shutdown", cpId.get());
- }
- // Remove any and all idle listeners.
- nsCOMPtr<nsIIdleService> idleService =
- do_GetService("@mozilla.org/widget/idleservice;1");
- MOZ_ASSERT(idleService);
- RefPtr<ParentIdleListener> listener;
- for (int32_t i = mIdleListeners.Length() - 1; i >= 0; --i) {
- listener = static_cast<ParentIdleListener*>(mIdleListeners[i].get());
- idleService->RemoveIdleObserver(listener, listener->mTime);
- }
- mIdleListeners.Clear();
- MessageLoop::current()->
- PostTask(NewRunnableFunction(DelayedDeleteSubprocess, mSubprocess));
- mSubprocess = nullptr;
- // IPDL rules require actors to live on past ActorDestroy, but it
- // may be that the kungFuDeathGrip above is the last reference to
- // |this|. If so, when we go out of scope here, we're deleted and
- // all hell breaks loose.
- //
- // This runnable ensures that a reference to |this| lives on at
- // least until after the current task finishes running.
- NS_DispatchToCurrentThread(new DelayedDeleteContentParentTask(this));
- ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
- nsTArray<ContentParentId> childIDArray =
- cpm->GetAllChildProcessById(this->ChildID());
- // Destroy any processes created by this ContentParent
- for(uint32_t i = 0; i < childIDArray.Length(); i++) {
- ContentParent* cp = cpm->GetContentProcessById(childIDArray[i]);
- MessageLoop::current()->PostTask(NewRunnableMethod
- <ShutDownMethod>(cp,
- &ContentParent::ShutDownProcess,
- SEND_SHUTDOWN_MESSAGE));
- }
- cpm->RemoveContentProcess(this->ChildID());
- if (mDriverCrashGuard) {
- mDriverCrashGuard->NotifyCrashed();
- }
- // Unregister all the BlobURLs registered by the ContentChild.
- for (uint32_t i = 0; i < mBlobURLs.Length(); ++i) {
- nsHostObjectProtocolHandler::RemoveDataEntry(mBlobURLs[i]);
- }
- mBlobURLs.Clear();
- #if defined(XP_WIN32) && defined(ACCESSIBILITY)
- a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
- #endif
- }
- void
- ContentParent::NotifyTabDestroying(const TabId& aTabId,
- const ContentParentId& aCpId)
- {
- if (XRE_IsParentProcess()) {
- // There can be more than one PBrowser for a given app process
- // because of popup windows. PBrowsers can also destroy
- // concurrently. When all the PBrowsers are destroying, kick off
- // another task to ensure the child process *really* shuts down,
- // even if the PBrowsers themselves never finish destroying.
- ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
- ContentParent* cp = cpm->GetContentProcessById(aCpId);
- if (!cp) {
- return;
- }
- ++cp->mNumDestroyingTabs;
- nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(aCpId);
- if (static_cast<size_t>(cp->mNumDestroyingTabs) != tabIds.Length()) {
- return;
- }
- uint32_t numberOfParents = sNonAppContentParents ? sNonAppContentParents->Length() : 0;
- int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
- if (!cp->mLargeAllocationProcess && static_cast<int32_t>(numberOfParents) <= processesToKeepAlive) {
- return;
- }
- // We're dying now, so prevent this content process from being
- // recycled during its shutdown procedure.
- cp->MarkAsDead();
- cp->StartForceKillTimer();
- } else {
- ContentChild::GetSingleton()->SendNotifyTabDestroying(aTabId, aCpId);
- }
- }
- void
- ContentParent::StartForceKillTimer()
- {
- if (mForceKillTimer || !mIPCOpen) {
- return;
- }
- int32_t timeoutSecs = Preferences::GetInt("dom.ipc.tabs.shutdownTimeoutSecs", 5);
- if (timeoutSecs > 0) {
- mForceKillTimer = do_CreateInstance("@mozilla.org/timer;1");
- MOZ_ASSERT(mForceKillTimer);
- mForceKillTimer->InitWithFuncCallback(ContentParent::ForceKillTimerCallback,
- this,
- timeoutSecs * 1000,
- nsITimer::TYPE_ONE_SHOT);
- }
- }
- void
- ContentParent::NotifyTabDestroyed(const TabId& aTabId,
- bool aNotifiedDestroying)
- {
- if (aNotifiedDestroying) {
- --mNumDestroyingTabs;
- }
- nsTArray<PContentPermissionRequestParent*> parentArray =
- nsContentPermissionUtils::GetContentPermissionRequestParentById(aTabId);
- // Need to close undeleted ContentPermissionRequestParents before tab is closed.
- for (auto& permissionRequestParent : parentArray) {
- Unused << PContentPermissionRequestParent::Send__delete__(permissionRequestParent);
- }
- // There can be more than one PBrowser for a given app process
- // because of popup windows. When the last one closes, shut
- // us down.
- ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
- nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(this->ChildID());
- // We might want to keep alive some content processes for testing, because of performance
- // reasons, but we don't want to alter behavior if the pref is not set.
- uint32_t numberOfParents = sNonAppContentParents ? sNonAppContentParents->Length() : 0;
- int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
- bool shouldKeepAliveAny = !mLargeAllocationProcess && processesToKeepAlive > 0;
- bool shouldKeepAliveThis = shouldKeepAliveAny && static_cast<int32_t>(numberOfParents) <= processesToKeepAlive;
- if (tabIds.Length() == 1 && !shouldKeepAliveThis) {
- // In the case of normal shutdown, send a shutdown message to child to
- // allow it to perform shutdown tasks.
- MessageLoop::current()->PostTask(NewRunnableMethod
- <ShutDownMethod>(this,
- &ContentParent::ShutDownProcess,
- SEND_SHUTDOWN_MESSAGE));
- }
- }
- jsipc::CPOWManager*
- ContentParent::GetCPOWManager()
- {
- if (PJavaScriptParent* p = LoneManagedOrNullAsserts(ManagedPJavaScriptParent())) {
- return CPOWManagerFor(p);
- }
- return nullptr;
- }
- TestShellParent*
- ContentParent::CreateTestShell()
- {
- return static_cast<TestShellParent*>(SendPTestShellConstructor());
- }
- bool
- ContentParent::DestroyTestShell(TestShellParent* aTestShell)
- {
- return PTestShellParent::Send__delete__(aTestShell);
- }
- TestShellParent*
- ContentParent::GetTestShellSingleton()
- {
- PTestShellParent* p = LoneManagedOrNullAsserts(ManagedPTestShellParent());
- return static_cast<TestShellParent*>(p);
- }
- void
- ContentParent::InitializeMembers()
- {
- mSubprocess = nullptr;
- mChildID = gContentChildID++;
- mGeolocationWatchID = -1;
- mNumDestroyingTabs = 0;
- mIsAlive = true;
- mMetamorphosed = false;
- mSendPermissionUpdates = false;
- mCalledClose = false;
- mCalledKillHard = false;
- mCreatedPairedMinidumps = false;
- mShutdownPending = false;
- mIPCOpen = true;
- mHangMonitorActor = nullptr;
- }
- bool
- ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */)
- {
- PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
- std::vector<std::string> extraArgs;
- if (gSafeMode) {
- extraArgs.push_back("-safeMode");
- }
- if (!mSubprocess->LaunchAndWaitForProcessHandle(extraArgs)) {
- MarkAsDead();
- return false;
- }
- Open(mSubprocess->GetChannel(),
- base::GetProcId(mSubprocess->GetChildProcessHandle()));
- InitInternal(aInitialPriority,
- true, /* Setup off-main thread compositing */
- true /* Send registered chrome */);
- ContentProcessManager::GetSingleton()->AddContentProcess(this);
- ProcessHangMonitor::AddProcess(this);
- // Set a reply timeout for CPOWs.
- SetReplyTimeoutMs(Preferences::GetInt("dom.ipc.cpow.timeout", 0));
- return true;
- }
- ContentParent::ContentParent(mozIApplication* aApp,
- ContentParent* aOpener,
- bool aIsForBrowser,
- bool aIsForPreallocated)
- : nsIContentParent()
- , mOpener(aOpener)
- , mIsForBrowser(aIsForBrowser)
- , mLargeAllocationProcess(false)
- {
- InitializeMembers(); // Perform common initialization.
- // No more than one of !!aApp, aIsForBrowser, aIsForPreallocated should be
- // true.
- MOZ_ASSERT(!!aApp + aIsForBrowser + aIsForPreallocated <= 1);
- mMetamorphosed = true;
- // Insert ourselves into the global linked list of ContentParent objects.
- if (!sContentParents) {
- sContentParents = new LinkedList<ContentParent>();
- }
- sContentParents->insertBack(this);
- if (aApp) {
- aApp->GetManifestURL(mAppManifestURL);
- aApp->GetName(mAppName);
- } else if (aIsForPreallocated) {
- mAppManifestURL = MAGIC_PREALLOCATED_APP_MANIFEST_URL;
- }
- // From this point on, NS_WARNING, NS_ASSERTION, etc. should print out the
- // PID along with the warning.
- nsDebugImpl::SetMultiprocessMode("Parent");
- #if defined(XP_WIN)
- // Request Windows message deferral behavior on our side of the PContent
- // channel. Generally only applies to the situation where we get caught in
- // a deadlock with the plugin process when sending CPOWs.
- GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
- #endif
- NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
- ChildPrivileges privs = base::PRIVILEGES_DEFAULT;
- mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content, privs);
- }
- ContentParent::~ContentParent()
- {
- if (mForceKillTimer) {
- mForceKillTimer->Cancel();
- }
- NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
- // We should be removed from all these lists in ActorDestroy.
- MOZ_ASSERT(!sPrivateContent || !sPrivateContent->Contains(this));
- if (mAppManifestURL.IsEmpty()) {
- MOZ_ASSERT((!sNonAppContentParents ||
- !sNonAppContentParents->Contains(this)) &&
- (!sLargeAllocationContentParents ||
- !sLargeAllocationContentParents->Contains(this)));
- } else {
- // In general, we expect sAppContentParents->Get(mAppManifestURL) to be
- // nullptr. But it could be that we created another ContentParent for
- // this app after we did this->ActorDestroy(), so the right check is
- // that sAppContentParents->Get(mAppManifestURL) != this.
- MOZ_ASSERT(!sAppContentParents ||
- sAppContentParents->Get(mAppManifestURL) != this);
- }
- }
- void
- ContentParent::InitInternal(ProcessPriority aInitialPriority,
- bool aSetupOffMainThreadCompositing,
- bool aSendRegisteredChrome)
- {
- if (aSendRegisteredChrome) {
- nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
- nsChromeRegistryChrome* chromeRegistry =
- static_cast<nsChromeRegistryChrome*>(registrySvc.get());
- chromeRegistry->SendRegisteredChrome(this);
- }
- if (gAppData) {
- nsCString version(gAppData->version);
- nsCString buildID(gAppData->buildID);
- nsCString name(gAppData->name);
- nsCString UAName(gAppData->UAName);
- nsCString ID(gAppData->ID);
- nsCString vendor(gAppData->vendor);
- // Sending all information to content process.
- Unused << SendAppInfo(version, buildID, name, UAName, ID, vendor);
- }
- // Initialize the message manager (and load delayed scripts) now that we
- // have established communications with the child.
- mMessageManager->InitWithCallback(this);
- // Set the subprocess's priority. We do this early on because we're likely
- // /lowering/ the process's CPU and memory priority, which it has inherited
- // from this process.
- //
- // This call can cause us to send IPC messages to the child process, so it
- // must come after the Open() call above.
- ProcessPriorityManager::SetProcessPriority(this, aInitialPriority);
- if (aSetupOffMainThreadCompositing) {
- // NB: internally, this will send an IPC message to the child
- // process to get it to create the CompositorBridgeChild. This
- // message goes through the regular IPC queue for this
- // channel, so delivery will happen-before any other messages
- // we send. The CompositorBridgeChild must be created before any
- // PBrowsers are created, because they rely on the Compositor
- // already being around. (Creation is async, so can't happen
- // on demand.)
- bool useOffMainThreadCompositing = !!CompositorThreadHolder::Loop();
- if (useOffMainThreadCompositing) {
- GPUProcessManager* gpm = GPUProcessManager::Get();
- Endpoint<PCompositorBridgeChild> compositor;
- Endpoint<PImageBridgeChild> imageBridge;
- Endpoint<PVideoDecoderManagerChild> videoManager;
- DebugOnly<bool> opened = gpm->CreateContentBridges(
- OtherPid(),
- &compositor,
- &imageBridge,
- &videoManager);
- MOZ_ASSERT(opened);
- Unused << SendInitRendering(
- Move(compositor),
- Move(imageBridge),
- Move(videoManager));
- gpm->AddListener(this);
- }
- }
- if (gAppData) {
- // Sending all information to content process.
- Unused << SendAppInit();
- }
- nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
- if (sheetService) {
- // This looks like a lot of work, but in a normal browser session we just
- // send two loads.
- for (StyleSheet* sheet : *sheetService->AgentStyleSheets()) {
- URIParams uri;
- SerializeURI(sheet->GetSheetURI(), uri);
- Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::AGENT_SHEET);
- }
- for (StyleSheet* sheet : *sheetService->UserStyleSheets()) {
- URIParams uri;
- SerializeURI(sheet->GetSheetURI(), uri);
- Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::USER_SHEET);
- }
- for (StyleSheet* sheet : *sheetService->AuthorStyleSheets()) {
- URIParams uri;
- SerializeURI(sheet->GetSheetURI(), uri);
- Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::AUTHOR_SHEET);
- }
- }
- #if defined(XP_WIN)
- // Send the info needed to join the browser process's audio session.
- nsID id;
- nsString sessionName;
- nsString iconPath;
- if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName,
- iconPath))) {
- Unused << SendSetAudioSessionData(id, sessionName, iconPath);
- }
- #endif
- {
- RefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();
- MOZ_ASSERT(swr);
- nsTArray<ServiceWorkerRegistrationData> registrations;
- swr->GetRegistrations(registrations);
- Unused << SendInitServiceWorkers(ServiceWorkerConfiguration(registrations));
- }
- {
- nsTArray<BlobURLRegistrationData> registrations;
- if (nsHostObjectProtocolHandler::GetAllBlobURLEntries(registrations,
- this)) {
- Unused << SendInitBlobURLs(registrations);
- }
- }
- }
- bool
- ContentParent::IsAlive() const
- {
- return mIsAlive;
- }
- bool
- ContentParent::IsForApp() const
- {
- return !mAppManifestURL.IsEmpty();
- }
- int32_t
- ContentParent::Pid() const
- {
- if (!mSubprocess || !mSubprocess->GetChildProcessHandle()) {
- return -1;
- }
- return base::GetProcId(mSubprocess->GetChildProcessHandle());
- }
- bool
- ContentParent::RecvReadPrefsArray(InfallibleTArray<PrefSetting>* aPrefs)
- {
- Preferences::GetPreferences(aPrefs);
- return true;
- }
- bool
- ContentParent::RecvGetGfxVars(InfallibleTArray<GfxVarUpdate>* aVars)
- {
- // Ensure gfxVars is initialized (for xpcshell tests).
- gfxVars::Initialize();
- *aVars = gfxVars::FetchNonDefaultVars();
- // Now that content has initialized gfxVars, we can start listening for
- // updates.
- gfxVars::AddReceiver(this);
- return true;
- }
- void
- ContentParent::OnCompositorUnexpectedShutdown()
- {
- GPUProcessManager* gpm = GPUProcessManager::Get();
- Endpoint<PCompositorBridgeChild> compositor;
- Endpoint<PImageBridgeChild> imageBridge;
- Endpoint<PVideoDecoderManagerChild> videoManager;
- DebugOnly<bool> opened = gpm->CreateContentBridges(
- OtherPid(),
- &compositor,
- &imageBridge,
- &videoManager);
- MOZ_ASSERT(opened);
- Unused << SendReinitRendering(
- Move(compositor),
- Move(imageBridge),
- Move(videoManager));
- }
- void
- ContentParent::OnVarChanged(const GfxVarUpdate& aVar)
- {
- if (!mIPCOpen) {
- return;
- }
- Unused << SendVarUpdate(aVar);
- }
- bool
- ContentParent::RecvReadFontList(InfallibleTArray<FontListEntry>* retValue)
- {
- return true;
- }
- bool
- ContentParent::RecvReadDataStorageArray(const nsString& aFilename,
- InfallibleTArray<DataStorageItem>* aValues)
- {
- // If we're shutting down, the DataStorage object may have been cleared
- // already, and setting it up is pointless anyways since we're about to die.
- if (mShutdownPending) {
- return true;
- }
- // Ensure the SSS is initialized before we try to use its storage.
- nsCOMPtr<nsISiteSecurityService> sss = do_GetService("@mozilla.org/ssservice;1");
- RefPtr<DataStorage> storage = DataStorage::Get(aFilename);
- storage->GetAll(aValues);
- return true;
- }
- bool
- ContentParent::RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions)
- {
- #ifdef MOZ_PERMISSIONS
- nsCOMPtr<nsIPermissionManager> permissionManagerIface =
- services::GetPermissionManager();
- nsPermissionManager* permissionManager =
- static_cast<nsPermissionManager*>(permissionManagerIface.get());
- MOZ_ASSERT(permissionManager,
- "We have no permissionManager in the Chrome process !");
- nsCOMPtr<nsISimpleEnumerator> enumerator;
- DebugOnly<nsresult> rv = permissionManager->GetEnumerator(getter_AddRefs(enumerator));
- MOZ_ASSERT(NS_SUCCEEDED(rv), "Could not get enumerator!");
- while(1) {
- bool hasMore;
- enumerator->HasMoreElements(&hasMore);
- if (!hasMore)
- break;
- nsCOMPtr<nsISupports> supp;
- enumerator->GetNext(getter_AddRefs(supp));
- nsCOMPtr<nsIPermission> perm = do_QueryInterface(supp);
- nsCOMPtr<nsIPrincipal> principal;
- perm->GetPrincipal(getter_AddRefs(principal));
- nsCString origin;
- if (principal) {
- principal->GetOrigin(origin);
- }
- nsCString type;
- perm->GetType(type);
- uint32_t capability;
- perm->GetCapability(&capability);
- uint32_t expireType;
- perm->GetExpireType(&expireType);
- int64_t expireTime;
- perm->GetExpireTime(&expireTime);
- aPermissions->AppendElement(IPC::Permission(origin, type,
- capability, expireType,
- expireTime));
- }
- // Ask for future changes
- mSendPermissionUpdates = true;
- #endif
- return true;
- }
- bool
- ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer,
- const bool& aIsPrivateData,
- const IPC::Principal& aRequestingPrincipal,
- const int32_t& aWhichClipboard)
- {
- nsresult rv;
- nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
- NS_ENSURE_SUCCESS(rv, true);
- nsCOMPtr<nsITransferable> trans =
- do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
- NS_ENSURE_SUCCESS(rv, true);
- trans->Init(nullptr);
- rv = nsContentUtils::IPCTransferableToTransferable(aDataTransfer,
- aIsPrivateData,
- aRequestingPrincipal,
- trans, this, nullptr);
- NS_ENSURE_SUCCESS(rv, true);
- clipboard->SetData(trans, nullptr, aWhichClipboard);
- return true;
- }
- bool
- ContentParent::RecvGetClipboard(nsTArray<nsCString>&& aTypes,
- const int32_t& aWhichClipboard,
- IPCDataTransfer* aDataTransfer)
- {
- nsresult rv;
- nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
- NS_ENSURE_SUCCESS(rv, true);
- nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
- NS_ENSURE_SUCCESS(rv, true);
- trans->Init(nullptr);
- for (uint32_t t = 0; t < aTypes.Length(); t++) {
- trans->AddDataFlavor(aTypes[t].get());
- }
- clipboard->GetData(trans, aWhichClipboard);
- nsContentUtils::TransferableToIPCTransferable(trans, aDataTransfer,
- true, nullptr, this);
- return true;
- }
- bool
- ContentParent::RecvEmptyClipboard(const int32_t& aWhichClipboard)
- {
- nsresult rv;
- nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
- NS_ENSURE_SUCCESS(rv, true);
- clipboard->EmptyClipboard(aWhichClipboard);
- return true;
- }
- bool
- ContentParent::RecvClipboardHasType(nsTArray<nsCString>&& aTypes,
- const int32_t& aWhichClipboard,
- bool* aHasType)
- {
- nsresult rv;
- nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
- NS_ENSURE_SUCCESS(rv, true);
- const char** typesChrs = new const char *[aTypes.Length()];
- for (uint32_t t = 0; t < aTypes.Length(); t++) {
- typesChrs[t] = aTypes[t].get();
- }
- clipboard->HasDataMatchingFlavors(typesChrs, aTypes.Length(),
- aWhichClipboard, aHasType);
- delete [] typesChrs;
- return true;
- }
- bool
- ContentParent::RecvGetSystemColors(const uint32_t& colorsCount,
- InfallibleTArray<uint32_t>* colors)
- {
- return true;
- }
- bool
- ContentParent::RecvGetIconForExtension(const nsCString& aFileExt,
- const uint32_t& aIconSize,
- InfallibleTArray<uint8_t>* bits)
- {
- return true;
- }
- bool
- ContentParent::RecvGetShowPasswordSetting(bool* showPassword)
- {
- // default behavior is to show the last password character
- *showPassword = true;
- return true;
- }
- bool
- ContentParent::RecvFirstIdle()
- {
- // When the ContentChild goes idle, it sends us a FirstIdle message
- // which we use as a good time to prelaunch another process. If we
- // prelaunch any sooner than this, then we'll be competing with the
- // child process and slowing it down.
- PreallocatedProcessManager::AllocateAfterDelay();
- return true;
- }
- bool
- ContentParent::RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
- const bool& aHidden)
- {
- RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
- MOZ_ASSERT(service);
- service->SetDefaultVolumeControlChannelInternal(aChannel, aHidden, mChildID);
- return true;
- }
- bool
- ContentParent::RecvAudioChannelServiceStatus(
- const bool& aTelephonyChannel,
- const bool& aContentOrNormalChannel,
- const bool& aAnyChannel)
- {
- RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
- MOZ_ASSERT(service);
- service->ChildStatusReceived(mChildID, aTelephonyChannel,
- aContentOrNormalChannel, aAnyChannel);
- return true;
- }
- // We want ContentParent to show up in CC logs for debugging purposes, but we
- // don't actually cycle collect it.
- NS_IMPL_CYCLE_COLLECTION_0(ContentParent)
- NS_IMPL_CYCLE_COLLECTING_ADDREF(ContentParent)
- NS_IMPL_CYCLE_COLLECTING_RELEASE(ContentParent)
- NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ContentParent)
- NS_INTERFACE_MAP_ENTRY(nsIContentParent)
- NS_INTERFACE_MAP_ENTRY(nsIObserver)
- NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionCallback)
- NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionErrorCallback)
- NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
- NS_INTERFACE_MAP_END
- NS_IMETHODIMP
- ContentParent::Observe(nsISupports* aSubject,
- const char* aTopic,
- const char16_t* aData)
- {
- if (mSubprocess && (!strcmp(aTopic, "profile-before-change") ||
- !strcmp(aTopic, "xpcom-shutdown"))) {
- // Okay to call ShutDownProcess multiple times.
- ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
- // Wait for shutdown to complete, so that we receive any shutdown
- // data (e.g. telemetry) from the child before we quit.
- // This loop terminate prematurely based on mForceKillTimer.
- while (mIPCOpen && !mCalledKillHard) {
- NS_ProcessNextEvent(nullptr, true);
- }
- NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
- }
- if (!mIsAlive || !mSubprocess)
- return NS_OK;
- // listening for memory pressure event
- if (!strcmp(aTopic, "memory-pressure") &&
- !StringEndsWith(nsDependentString(aData),
- NS_LITERAL_STRING("-no-forward"))) {
- Unused << SendFlushMemory(nsDependentString(aData));
- }
- // listening for remotePrefs...
- else if (!strcmp(aTopic, "nsPref:changed")) {
- // We know prefs are ASCII here.
- NS_LossyConvertUTF16toASCII strData(aData);
- PrefSetting pref(strData, null_t(), null_t());
- Preferences::GetPreference(&pref);
- if (!SendPreferenceUpdate(pref)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- }
- else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
- NS_ConvertUTF16toUTF8 dataStr(aData);
- const char *offline = dataStr.get();
- if (!SendSetOffline(!strcmp(offline, "true") ? true : false)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- }
- else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC)) {
- if (!SendSetConnectivity(NS_LITERAL_STRING("true").Equals(aData))) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- } else if (!strcmp(aTopic, NS_IPC_CAPTIVE_PORTAL_SET_STATE)) {
- nsCOMPtr<nsICaptivePortalService> cps = do_QueryInterface(aSubject);
- MOZ_ASSERT(cps, "Should QI to a captive portal service");
- if (!cps) {
- return NS_ERROR_FAILURE;
- }
- int32_t state;
- cps->GetState(&state);
- if (!SendSetCaptivePortalState(state)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- }
- // listening for alert notifications
- else if (!strcmp(aTopic, "alertfinished") ||
- !strcmp(aTopic, "alertclickcallback") ||
- !strcmp(aTopic, "alertshow") ||
- !strcmp(aTopic, "alertdisablecallback") ||
- !strcmp(aTopic, "alertsettingscallback")) {
- if (!SendNotifyAlertsObserver(nsDependentCString(aTopic),
- nsDependentString(aData)))
- return NS_ERROR_NOT_AVAILABLE;
- }
- else if (!strcmp(aTopic, "child-gc-request")){
- Unused << SendGarbageCollect();
- }
- else if (!strcmp(aTopic, "child-cc-request")){
- Unused << SendCycleCollect();
- }
- else if (!strcmp(aTopic, "child-mmu-request")){
- Unused << SendMinimizeMemoryUsage();
- }
- else if (!strcmp(aTopic, "last-pb-context-exited")) {
- Unused << SendLastPrivateDocShellDestroyed();
- }
- #ifdef ACCESSIBILITY
- else if (aData && !strcmp(aTopic, "a11y-init-or-shutdown")) {
- if (*aData == '1') {
- // Make sure accessibility is running in content process when
- // accessibility gets initiated in chrome process.
- #if !defined(XP_WIN)
- Unused << SendActivateA11y(0);
- #endif
- } else {
- // If possible, shut down accessibility in content process when
- // accessibility gets shutdown in chrome process.
- Unused << SendShutdownA11y();
- }
- }
- #endif
- else if (!strcmp(aTopic, "cacheservice:empty-cache")) {
- Unused << SendNotifyEmptyHTTPCache();
- }
- return NS_OK;
- }
- PGMPServiceParent*
- ContentParent::AllocPGMPServiceParent(mozilla::ipc::Transport* aTransport,
- base::ProcessId aOtherProcess)
- {
- return GMPServiceParent::Create(aTransport, aOtherProcess);
- }
- PBackgroundParent*
- ContentParent::AllocPBackgroundParent(Transport* aTransport,
- ProcessId aOtherProcess)
- {
- return BackgroundParent::Alloc(this, aTransport, aOtherProcess);
- }
- PProcessHangMonitorParent*
- ContentParent::AllocPProcessHangMonitorParent(Transport* aTransport,
- ProcessId aOtherProcess)
- {
- mHangMonitorActor = CreateHangMonitorParent(this, aTransport, aOtherProcess);
- return mHangMonitorActor;
- }
- bool
- ContentParent::RecvGetProcessAttributes(ContentParentId* aCpId,
- bool* aIsForApp, bool* aIsForBrowser)
- {
- *aCpId = mChildID;
- *aIsForApp = IsForApp();
- *aIsForBrowser = mIsForBrowser;
- return true;
- }
- bool
- ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline,
- bool* aIsConnected,
- int32_t* aCaptivePortalState,
- bool* aIsLangRTL,
- bool* aHaveBidiKeyboards,
- InfallibleTArray<nsString>* dictionaries,
- ClipboardCapabilities* clipboardCaps,
- DomainPolicyClone* domainPolicy,
- StructuredCloneData* aInitialData,
- OptionalURIParams* aUserContentCSSURL)
- {
- nsCOMPtr<nsIIOService> io(do_GetIOService());
- MOZ_ASSERT(io, "No IO service?");
- DebugOnly<nsresult> rv = io->GetOffline(aIsOffline);
- MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting offline?");
- rv = io->GetConnectivity(aIsConnected);
- MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting connectivity?");
- *aCaptivePortalState = nsICaptivePortalService::UNKNOWN;
- nsCOMPtr<nsICaptivePortalService> cps = do_GetService(NS_CAPTIVEPORTAL_CONTRACTID);
- if (cps) {
- cps->GetState(aCaptivePortalState);
- }
- nsIBidiKeyboard* bidi = nsContentUtils::GetBidiKeyboard();
- *aIsLangRTL = false;
- *aHaveBidiKeyboards = false;
- if (bidi) {
- bidi->IsLangRTL(aIsLangRTL);
- bidi->GetHaveBidiKeyboards(aHaveBidiKeyboards);
- }
- nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID));
- MOZ_ASSERT(spellChecker, "No spell checker?");
- spellChecker->GetDictionaryList(dictionaries);
- nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1"));
- MOZ_ASSERT(clipboard, "No clipboard?");
- rv = clipboard->SupportsSelectionClipboard(&clipboardCaps->supportsSelectionClipboard());
- MOZ_ASSERT(NS_SUCCEEDED(rv));
- rv = clipboard->SupportsFindClipboard(&clipboardCaps->supportsFindClipboard());
- MOZ_ASSERT(NS_SUCCEEDED(rv));
- // Let's copy the domain policy from the parent to the child (if it's active).
- nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
- NS_ENSURE_TRUE(ssm, false);
- ssm->CloneDomainPolicy(domainPolicy);
- if (nsFrameMessageManager* mm = nsFrameMessageManager::sParentProcessManager) {
- AutoJSAPI jsapi;
- if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
- return false;
- }
- JS::RootedValue init(jsapi.cx());
- nsresult result = mm->GetInitialProcessData(jsapi.cx(), &init);
- if (NS_FAILED(result)) {
- return false;
- }
- ErrorResult rv;
- aInitialData->Write(jsapi.cx(), init, rv);
- if (NS_WARN_IF(rv.Failed())) {
- rv.SuppressException();
- return false;
- }
- }
- // Content processes have no permission to access profile directory, so we
- // send the file URL instead.
- StyleSheet* ucs = nsLayoutStylesheetCache::For(StyleBackendType::Gecko)->UserContentSheet();
- if (ucs) {
- SerializeURI(ucs->GetSheetURI(), *aUserContentCSSURL);
- } else {
- SerializeURI(nullptr, *aUserContentCSSURL);
- }
- return true;
- }
- mozilla::jsipc::PJavaScriptParent *
- ContentParent::AllocPJavaScriptParent()
- {
- MOZ_ASSERT(ManagedPJavaScriptParent().IsEmpty());
- return nsIContentParent::AllocPJavaScriptParent();
- }
- bool
- ContentParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
- {
- return nsIContentParent::DeallocPJavaScriptParent(parent);
- }
- PBrowserParent*
- ContentParent::AllocPBrowserParent(const TabId& aTabId,
- const IPCTabContext& aContext,
- const uint32_t& aChromeFlags,
- const ContentParentId& aCpId,
- const bool& aIsForApp,
- const bool& aIsForBrowser)
- {
- return nsIContentParent::AllocPBrowserParent(aTabId,
- aContext,
- aChromeFlags,
- aCpId,
- aIsForApp,
- aIsForBrowser);
- }
- bool
- ContentParent::DeallocPBrowserParent(PBrowserParent* frame)
- {
- return nsIContentParent::DeallocPBrowserParent(frame);
- }
- PBlobParent*
- ContentParent::AllocPBlobParent(const BlobConstructorParams& aParams)
- {
- return nsIContentParent::AllocPBlobParent(aParams);
- }
- bool
- ContentParent::DeallocPBlobParent(PBlobParent* aActor)
- {
- return nsIContentParent::DeallocPBlobParent(aActor);
- }
- bool
- ContentParent::RecvPBlobConstructor(PBlobParent* aActor,
- const BlobConstructorParams& aParams)
- {
- const ParentBlobConstructorParams& params = aParams.get_ParentBlobConstructorParams();
- if (params.blobParams().type() == AnyBlobConstructorParams::TKnownBlobConstructorParams) {
- return aActor->SendCreatedFromKnownBlob();
- }
- return true;
- }
- mozilla::PRemoteSpellcheckEngineParent *
- ContentParent::AllocPRemoteSpellcheckEngineParent()
- {
- mozilla::RemoteSpellcheckEngineParent *parent = new mozilla::RemoteSpellcheckEngineParent();
- return parent;
- }
- bool
- ContentParent::DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent *parent)
- {
- delete parent;
- return true;
- }
- /* static */ void
- ContentParent::ForceKillTimerCallback(nsITimer* aTimer, void* aClosure)
- {
- // We don't want to time out the content process during XPCShell tests. This
- // is the easiest way to ensure that.
- if (PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR")) {
- return;
- }
- auto self = static_cast<ContentParent*>(aClosure);
- self->KillHard("ShutDownKill");
- }
- // WARNING: aReason appears in telemetry, so any new value passed in requires
- // data review.
- void
- ContentParent::KillHard(const char* aReason)
- {
- PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);
- // On Windows, calling KillHard multiple times causes problems - the
- // process handle becomes invalid on the first call, causing a second call
- // to crash our process - more details in bug 890840.
- if (mCalledKillHard) {
- return;
- }
- mCalledKillHard = true;
- mForceKillTimer = nullptr;
- ProcessHandle otherProcessHandle;
- if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle)) {
- NS_ERROR("Failed to open child process when attempting kill.");
- return;
- }
- if (!KillProcess(otherProcessHandle, base::PROCESS_END_KILLED_BY_USER,
- false)) {
- NS_WARNING("failed to kill subprocess!");
- }
- if (mSubprocess) {
- mSubprocess->SetAlreadyDead();
- }
- // EnsureProcessTerminated has responsibilty for closing otherProcessHandle.
- XRE_GetIOMessageLoop()->PostTask(
- NewRunnableFunction(&ProcessWatcher::EnsureProcessTerminated,
- otherProcessHandle, /*force=*/true));
- }
- bool
- ContentParent::IsPreallocated() const
- {
- return mAppManifestURL == MAGIC_PREALLOCATED_APP_MANIFEST_URL;
- }
- void
- ContentParent::FriendlyName(nsAString& aName, bool aAnonymize)
- {
- aName.Truncate();
- if (IsPreallocated()) {
- aName.AssignLiteral("(Preallocated)");
- } else if (mIsForBrowser) {
- aName.AssignLiteral("Browser");
- } else if (aAnonymize) {
- aName.AssignLiteral("<anonymized-name>");
- } else if (!mAppName.IsEmpty()) {
- aName = mAppName;
- } else if (!mAppManifestURL.IsEmpty()) {
- aName.AssignLiteral("Unknown app: ");
- aName.Append(mAppManifestURL);
- } else {
- aName.AssignLiteral("???");
- }
- }
- hal_sandbox::PHalParent*
- ContentParent::AllocPHalParent()
- {
- return hal_sandbox::CreateHalParent();
- }
- bool
- ContentParent::DeallocPHalParent(hal_sandbox::PHalParent* aHal)
- {
- delete aHal;
- return true;
- }
- devtools::PHeapSnapshotTempFileHelperParent*
- ContentParent::AllocPHeapSnapshotTempFileHelperParent()
- {
- return devtools::HeapSnapshotTempFileHelperParent::Create();
- }
- bool
- ContentParent::DeallocPHeapSnapshotTempFileHelperParent(
- devtools::PHeapSnapshotTempFileHelperParent* aHeapSnapshotHelper)
- {
- delete aHeapSnapshotHelper;
- return true;
- }
- PMemoryReportRequestParent*
- ContentParent::AllocPMemoryReportRequestParent(const uint32_t& aGeneration,
- const bool &aAnonymize,
- const bool &aMinimizeMemoryUsage,
- const MaybeFileDesc &aDMDFile)
- {
- MemoryReportRequestParent* parent =
- new MemoryReportRequestParent(aGeneration);
- return parent;
- }
- bool
- ContentParent::DeallocPMemoryReportRequestParent(PMemoryReportRequestParent* actor)
- {
- delete actor;
- return true;
- }
- PCycleCollectWithLogsParent*
- ContentParent::AllocPCycleCollectWithLogsParent(const bool& aDumpAllTraces,
- const FileDescriptor& aGCLog,
- const FileDescriptor& aCCLog)
- {
- MOZ_CRASH("Don't call this; use ContentParent::CycleCollectWithLogs");
- }
- bool
- ContentParent::DeallocPCycleCollectWithLogsParent(PCycleCollectWithLogsParent* aActor)
- {
- delete aActor;
- return true;
- }
- bool
- ContentParent::CycleCollectWithLogs(bool aDumpAllTraces,
- nsICycleCollectorLogSink* aSink,
- nsIDumpGCAndCCLogsCallback* aCallback)
- {
- return CycleCollectWithLogsParent::AllocAndSendConstructor(this,
- aDumpAllTraces,
- aSink,
- aCallback);
- }
- PTestShellParent*
- ContentParent::AllocPTestShellParent()
- {
- return new TestShellParent();
- }
- bool
- ContentParent::DeallocPTestShellParent(PTestShellParent* shell)
- {
- delete shell;
- return true;
- }
- PNeckoParent*
- ContentParent::AllocPNeckoParent()
- {
- return new NeckoParent();
- }
- bool
- ContentParent::DeallocPNeckoParent(PNeckoParent* necko)
- {
- delete necko;
- return true;
- }
- PPrintingParent*
- ContentParent::AllocPPrintingParent()
- {
- #ifdef NS_PRINTING
- MOZ_RELEASE_ASSERT(!mPrintingParent,
- "Only one PrintingParent should be created per process.");
- // Create the printing singleton for this process.
- mPrintingParent = new PrintingParent();
- // Take another reference for IPDL code.
- mPrintingParent.get()->AddRef();
- return mPrintingParent.get();
- #else
- MOZ_ASSERT_UNREACHABLE("Should never be created if no printing.");
- return nullptr;
- #endif
- }
- bool
- ContentParent::DeallocPPrintingParent(PPrintingParent* printing)
- {
- #ifdef NS_PRINTING
- MOZ_RELEASE_ASSERT(mPrintingParent == printing,
- "Only one PrintingParent should have been created per process.");
- // Release reference taken for IPDL code.
- static_cast<PrintingParent*>(printing)->Release();
- mPrintingParent = nullptr;
- #else
- MOZ_ASSERT_UNREACHABLE("Should never have been created if no printing.");
- #endif
- return true;
- }
- #ifdef NS_PRINTING
- already_AddRefed<embedding::PrintingParent>
- ContentParent::GetPrintingParent()
- {
- MOZ_ASSERT(mPrintingParent);
- RefPtr<embedding::PrintingParent> printingParent = mPrintingParent;
- return printingParent.forget();
- }
- #endif
- PSendStreamParent*
- ContentParent::AllocPSendStreamParent()
- {
- return nsIContentParent::AllocPSendStreamParent();
- }
- bool
- ContentParent::DeallocPSendStreamParent(PSendStreamParent* aActor)
- {
- return nsIContentParent::DeallocPSendStreamParent(aActor);
- }
- PScreenManagerParent*
- ContentParent::AllocPScreenManagerParent(uint32_t* aNumberOfScreens,
- float* aSystemDefaultScale,
- bool* aSuccess)
- {
- return new ScreenManagerParent(aNumberOfScreens, aSystemDefaultScale, aSuccess);
- }
- bool
- ContentParent::DeallocPScreenManagerParent(PScreenManagerParent* aActor)
- {
- delete aActor;
- return true;
- }
- PPSMContentDownloaderParent*
- ContentParent::AllocPPSMContentDownloaderParent(const uint32_t& aCertType)
- {
- RefPtr<PSMContentDownloaderParent> downloader =
- new PSMContentDownloaderParent(aCertType);
- return downloader.forget().take();
- }
- bool
- ContentParent::DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aListener)
- {
- auto* listener = static_cast<PSMContentDownloaderParent*>(aListener);
- RefPtr<PSMContentDownloaderParent> downloader = dont_AddRef(listener);
- return true;
- }
- PExternalHelperAppParent*
- ContentParent::AllocPExternalHelperAppParent(const OptionalURIParams& uri,
- const nsCString& aMimeContentType,
- const nsCString& aContentDisposition,
- const uint32_t& aContentDispositionHint,
- const nsString& aContentDispositionFilename,
- const bool& aForceSave,
- const int64_t& aContentLength,
- const bool& aWasFileChannel,
- const OptionalURIParams& aReferrer,
- PBrowserParent* aBrowser)
- {
- ExternalHelperAppParent *parent =
- new ExternalHelperAppParent(uri, aContentLength, aWasFileChannel);
- parent->AddRef();
- parent->Init(this,
- aMimeContentType,
- aContentDisposition,
- aContentDispositionHint,
- aContentDispositionFilename,
- aForceSave,
- aReferrer,
- aBrowser);
- return parent;
- }
- bool
- ContentParent::DeallocPExternalHelperAppParent(PExternalHelperAppParent* aService)
- {
- ExternalHelperAppParent *parent = static_cast<ExternalHelperAppParent *>(aService);
- parent->Release();
- return true;
- }
- PHandlerServiceParent*
- ContentParent::AllocPHandlerServiceParent()
- {
- HandlerServiceParent* actor = new HandlerServiceParent();
- actor->AddRef();
- return actor;
- }
- bool
- ContentParent::DeallocPHandlerServiceParent(PHandlerServiceParent* aHandlerServiceParent)
- {
- static_cast<HandlerServiceParent*>(aHandlerServiceParent)->Release();
- return true;
- }
- media::PMediaParent*
- ContentParent::AllocPMediaParent()
- {
- return media::AllocPMediaParent();
- }
- bool
- ContentParent::DeallocPMediaParent(media::PMediaParent *aActor)
- {
- return media::DeallocPMediaParent(aActor);
- }
- PStorageParent*
- ContentParent::AllocPStorageParent()
- {
- return new DOMStorageDBParent();
- }
- bool
- ContentParent::DeallocPStorageParent(PStorageParent* aActor)
- {
- DOMStorageDBParent* child = static_cast<DOMStorageDBParent*>(aActor);
- child->ReleaseIPDLReference();
- return true;
- }
- PSpeechSynthesisParent*
- ContentParent::AllocPSpeechSynthesisParent()
- {
- #ifdef MOZ_WEBSPEECH
- return new mozilla::dom::SpeechSynthesisParent();
- #else
- return nullptr;
- #endif
- }
- bool
- ContentParent::DeallocPSpeechSynthesisParent(PSpeechSynthesisParent* aActor)
- {
- #ifdef MOZ_WEBSPEECH
- delete aActor;
- return true;
- #else
- return false;
- #endif
- }
- bool
- ContentParent::RecvPSpeechSynthesisConstructor(PSpeechSynthesisParent* aActor)
- {
- #ifdef MOZ_WEBSPEECH
- return true;
- #else
- return false;
- #endif
- }
- bool
- ContentParent::RecvSpeakerManagerGetSpeakerStatus(bool* aValue)
- {
- return false;
- }
- bool
- ContentParent::RecvSpeakerManagerForceSpeaker(const bool& aEnable)
- {
- return false;
- }
- bool
- ContentParent::RecvStartVisitedQuery(const URIParams& aURI)
- {
- nsCOMPtr<nsIURI> newURI = DeserializeURI(aURI);
- if (!newURI) {
- return false;
- }
- nsCOMPtr<IHistory> history = services::GetHistoryService();
- if (history) {
- history->RegisterVisitedCallback(newURI, nullptr);
- }
- return true;
- }
- bool
- ContentParent::RecvVisitURI(const URIParams& uri,
- const OptionalURIParams& referrer,
- const uint32_t& flags)
- {
- nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
- if (!ourURI) {
- return false;
- }
- nsCOMPtr<nsIURI> ourReferrer = DeserializeURI(referrer);
- nsCOMPtr<IHistory> history = services::GetHistoryService();
- if (history) {
- history->VisitURI(ourURI, ourReferrer, flags);
- }
- return true;
- }
- bool
- ContentParent::RecvSetURITitle(const URIParams& uri,
- const nsString& title)
- {
- nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
- if (!ourURI) {
- return false;
- }
- nsCOMPtr<IHistory> history = services::GetHistoryService();
- if (history) {
- history->SetURITitle(ourURI, title);
- }
- return true;
- }
- bool
- ContentParent::RecvNSSU2FTokenIsCompatibleVersion(const nsString& aVersion,
- bool* aIsCompatible)
- {
- MOZ_ASSERT(aIsCompatible);
- nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
- if (NS_WARN_IF(!nssToken)) {
- return false;
- }
- nsresult rv = nssToken->IsCompatibleVersion(aVersion, aIsCompatible);
- return NS_SUCCEEDED(rv);
- }
- bool
- ContentParent::RecvNSSU2FTokenIsRegistered(nsTArray<uint8_t>&& aKeyHandle,
- bool* aIsValidKeyHandle)
- {
- MOZ_ASSERT(aIsValidKeyHandle);
- nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
- if (NS_WARN_IF(!nssToken)) {
- return false;
- }
- nsresult rv = nssToken->IsRegistered(aKeyHandle.Elements(), aKeyHandle.Length(),
- aIsValidKeyHandle);
- return NS_SUCCEEDED(rv);
- }
- bool
- ContentParent::RecvNSSU2FTokenRegister(nsTArray<uint8_t>&& aApplication,
- nsTArray<uint8_t>&& aChallenge,
- nsTArray<uint8_t>* aRegistration)
- {
- MOZ_ASSERT(aRegistration);
- nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
- if (NS_WARN_IF(!nssToken)) {
- return false;
- }
- uint8_t* buffer;
- uint32_t bufferlen;
- nsresult rv = nssToken->Register(aApplication.Elements(), aApplication.Length(),
- aChallenge.Elements(), aChallenge.Length(),
- &buffer, &bufferlen);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return false;
- }
- MOZ_ASSERT(buffer);
- aRegistration->ReplaceElementsAt(0, aRegistration->Length(), buffer, bufferlen);
- free(buffer);
- return NS_SUCCEEDED(rv);
- }
- bool
- ContentParent::RecvNSSU2FTokenSign(nsTArray<uint8_t>&& aApplication,
- nsTArray<uint8_t>&& aChallenge,
- nsTArray<uint8_t>&& aKeyHandle,
- nsTArray<uint8_t>* aSignature)
- {
- MOZ_ASSERT(aSignature);
- nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
- if (NS_WARN_IF(!nssToken)) {
- return false;
- }
- uint8_t* buffer;
- uint32_t bufferlen;
- nsresult rv = nssToken->Sign(aApplication.Elements(), aApplication.Length(),
- aChallenge.Elements(), aChallenge.Length(),
- aKeyHandle.Elements(), aKeyHandle.Length(),
- &buffer, &bufferlen);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return false;
- }
- MOZ_ASSERT(buffer);
- aSignature->ReplaceElementsAt(0, aSignature->Length(), buffer, bufferlen);
- free(buffer);
- return NS_SUCCEEDED(rv);
- }
- bool
- ContentParent::RecvGetLookAndFeelCache(nsTArray<LookAndFeelInt>* aLookAndFeelIntCache)
- {
- *aLookAndFeelIntCache = LookAndFeel::GetIntCache();
- return true;
- }
- bool
- ContentParent::RecvIsSecureURI(const uint32_t& type,
- const URIParams& uri,
- const uint32_t& flags,
- bool* isSecureURI)
- {
- nsCOMPtr<nsISiteSecurityService> sss(do_GetService(NS_SSSERVICE_CONTRACTID));
- if (!sss) {
- return false;
- }
- nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
- if (!ourURI) {
- return false;
- }
- nsresult rv = sss->IsSecureURI(type, ourURI, flags, nullptr, isSecureURI);
- return NS_SUCCEEDED(rv);
- }
- bool
- ContentParent::RecvLoadURIExternal(const URIParams& uri,
- PBrowserParent* windowContext)
- {
- nsCOMPtr<nsIExternalProtocolService> extProtService(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
- if (!extProtService) {
- return true;
- }
- nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
- if (!ourURI) {
- return false;
- }
- RefPtr<RemoteWindowContext> context =
- new RemoteWindowContext(static_cast<TabParent*>(windowContext));
- extProtService->LoadURI(ourURI, context);
- return true;
- }
- bool
- ContentParent::RecvExtProtocolChannelConnectParent(const uint32_t& registrarId)
- {
- nsresult rv;
- // First get the real channel created before redirect on the parent.
- nsCOMPtr<nsIChannel> channel;
- rv = NS_LinkRedirectChannels(registrarId, nullptr, getter_AddRefs(channel));
- NS_ENSURE_SUCCESS(rv, true);
- nsCOMPtr<nsIParentChannel> parent = do_QueryInterface(channel, &rv);
- NS_ENSURE_SUCCESS(rv, true);
- // The channel itself is its own (faked) parent, link it.
- rv = NS_LinkRedirectChannels(registrarId, parent, getter_AddRefs(channel));
- NS_ENSURE_SUCCESS(rv, true);
- // Signal the parent channel that it's a redirect-to parent. This will
- // make AsyncOpen on it do nothing (what we want).
- // Yes, this is a bit of a hack, but I don't think it's necessary to invent
- // a new interface just to set this flag on the channel.
- parent->SetParentListener(nullptr);
- return true;
- }
- bool
- ContentParent::HasNotificationPermission(const IPC::Principal& aPrincipal)
- {
- return true;
- }
- bool
- ContentParent::RecvShowAlert(const AlertNotificationType& aAlert)
- {
- nsCOMPtr<nsIAlertNotification> alert(dont_AddRef(aAlert));
- if (NS_WARN_IF(!alert)) {
- return true;
- }
- nsCOMPtr<nsIPrincipal> principal;
- nsresult rv = alert->GetPrincipal(getter_AddRefs(principal));
- if (NS_WARN_IF(NS_FAILED(rv)) ||
- !HasNotificationPermission(IPC::Principal(principal))) {
- return true;
- }
- nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
- if (sysAlerts) {
- sysAlerts->ShowAlert(alert, this);
- }
- return true;
- }
- bool
- ContentParent::RecvCloseAlert(const nsString& aName,
- const IPC::Principal& aPrincipal)
- {
- if (!HasNotificationPermission(aPrincipal)) {
- return true;
- }
- nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
- if (sysAlerts) {
- sysAlerts->CloseAlert(aName, aPrincipal);
- }
- return true;
- }
- bool
- ContentParent::RecvDisableNotifications(const IPC::Principal& aPrincipal)
- {
- if (HasNotificationPermission(aPrincipal)) {
- Unused << Notification::RemovePermission(aPrincipal);
- }
- return true;
- }
- bool
- ContentParent::RecvOpenNotificationSettings(const IPC::Principal& aPrincipal)
- {
- if (HasNotificationPermission(aPrincipal)) {
- Unused << Notification::OpenSettings(aPrincipal);
- }
- return true;
- }
- bool
- ContentParent::RecvSyncMessage(const nsString& aMsg,
- const ClonedMessageData& aData,
- InfallibleTArray<CpowEntry>&& aCpows,
- const IPC::Principal& aPrincipal,
- nsTArray<StructuredCloneData>* aRetvals)
- {
- return nsIContentParent::RecvSyncMessage(aMsg, aData, Move(aCpows),
- aPrincipal, aRetvals);
- }
- bool
- ContentParent::RecvRpcMessage(const nsString& aMsg,
- const ClonedMessageData& aData,
- InfallibleTArray<CpowEntry>&& aCpows,
- const IPC::Principal& aPrincipal,
- nsTArray<StructuredCloneData>* aRetvals)
- {
- return nsIContentParent::RecvRpcMessage(aMsg, aData, Move(aCpows), aPrincipal,
- aRetvals);
- }
- bool
- ContentParent::RecvAsyncMessage(const nsString& aMsg,
- InfallibleTArray<CpowEntry>&& aCpows,
- const IPC::Principal& aPrincipal,
- const ClonedMessageData& aData)
- {
- return nsIContentParent::RecvAsyncMessage(aMsg, Move(aCpows), aPrincipal,
- aData);
- }
- static int32_t
- AddGeolocationListener(nsIDOMGeoPositionCallback* watcher,
- nsIDOMGeoPositionErrorCallback* errorCallBack,
- bool highAccuracy)
- {
- nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
- if (!geo) {
- return -1;
- }
- UniquePtr<PositionOptions> options = MakeUnique<PositionOptions>();
- options->mTimeout = 0;
- options->mMaximumAge = 0;
- options->mEnableHighAccuracy = highAccuracy;
- int32_t retval = 1;
- geo->WatchPosition(watcher, errorCallBack, Move(options), &retval);
- return retval;
- }
- bool
- ContentParent::RecvAddGeolocationListener(const IPC::Principal& aPrincipal,
- const bool& aHighAccuracy)
- {
- // To ensure no geolocation updates are skipped, we always force the
- // creation of a new listener.
- RecvRemoveGeolocationListener();
- mGeolocationWatchID = AddGeolocationListener(this, this, aHighAccuracy);
- return true;
- }
- bool
- ContentParent::RecvRemoveGeolocationListener()
- {
- if (mGeolocationWatchID != -1) {
- nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
- if (!geo) {
- return true;
- }
- geo->ClearWatch(mGeolocationWatchID);
- mGeolocationWatchID = -1;
- }
- return true;
- }
- bool
- ContentParent::RecvSetGeolocationHigherAccuracy(const bool& aEnable)
- {
- // This should never be called without a listener already present,
- // so this check allows us to forgo securing privileges.
- if (mGeolocationWatchID != -1) {
- RecvRemoveGeolocationListener();
- mGeolocationWatchID = AddGeolocationListener(this, this, aEnable);
- }
- return true;
- }
- NS_IMETHODIMP
- ContentParent::HandleEvent(nsIDOMGeoPosition* postion)
- {
- Unused << SendGeolocationUpdate(GeoPosition(postion));
- return NS_OK;
- }
- NS_IMETHODIMP
- ContentParent::HandleEvent(nsIDOMGeoPositionError* postionError)
- {
- int16_t errorCode;
- nsresult rv;
- rv = postionError->GetCode(&errorCode);
- NS_ENSURE_SUCCESS(rv,rv);
- Unused << SendGeolocationError(errorCode);
- return NS_OK;
- }
- nsConsoleService *
- ContentParent::GetConsoleService()
- {
- if (mConsoleService) {
- return mConsoleService.get();
- }
- // XXXkhuey everything about this is terrible.
- // Get the ConsoleService by CID rather than ContractID, so that we
- // can cast the returned pointer to an nsConsoleService (rather than
- // just an nsIConsoleService). This allows us to call the non-idl function
- // nsConsoleService::LogMessageWithMode.
- NS_DEFINE_CID(consoleServiceCID, NS_CONSOLESERVICE_CID);
- nsCOMPtr<nsIConsoleService> consoleService(do_GetService(consoleServiceCID));
- mConsoleService = static_cast<nsConsoleService*>(consoleService.get());
- return mConsoleService.get();
- }
- bool
- ContentParent::RecvConsoleMessage(const nsString& aMessage)
- {
- RefPtr<nsConsoleService> consoleService = GetConsoleService();
- if (!consoleService) {
- return true;
- }
- RefPtr<nsConsoleMessage> msg(new nsConsoleMessage(aMessage.get()));
- consoleService->LogMessageWithMode(msg, nsConsoleService::SuppressLog);
- return true;
- }
- bool
- ContentParent::RecvScriptError(const nsString& aMessage,
- const nsString& aSourceName,
- const nsString& aSourceLine,
- const uint32_t& aLineNumber,
- const uint32_t& aColNumber,
- const uint32_t& aFlags,
- const nsCString& aCategory)
- {
- RefPtr<nsConsoleService> consoleService = GetConsoleService();
- if (!consoleService) {
- return true;
- }
- nsCOMPtr<nsIScriptError> msg(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
- nsresult rv = msg->Init(aMessage, aSourceName, aSourceLine,
- aLineNumber, aColNumber, aFlags, aCategory.get());
- if (NS_FAILED(rv))
- return true;
- consoleService->LogMessageWithMode(msg, nsConsoleService::SuppressLog);
- return true;
- }
- bool
- ContentParent::RecvPrivateDocShellsExist(const bool& aExist)
- {
- if (!sPrivateContent)
- sPrivateContent = new nsTArray<ContentParent*>();
- if (aExist) {
- sPrivateContent->AppendElement(this);
- } else {
- sPrivateContent->RemoveElement(this);
- // Only fire the notification if we have private and non-private
- // windows: if privatebrowsing.autostart is true, all windows are
- // private.
- if (!sPrivateContent->Length() &&
- !Preferences::GetBool("browser.privatebrowsing.autostart")) {
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- obs->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
- delete sPrivateContent;
- sPrivateContent = nullptr;
- }
- }
- return true;
- }
- bool
- ContentParent::DoLoadMessageManagerScript(const nsAString& aURL,
- bool aRunInGlobalScope)
- {
- MOZ_ASSERT(!aRunInGlobalScope);
- return SendLoadProcessScript(nsString(aURL));
- }
- nsresult
- ContentParent::DoSendAsyncMessage(JSContext* aCx,
- const nsAString& aMessage,
- StructuredCloneData& aHelper,
- JS::Handle<JSObject *> aCpows,
- nsIPrincipal* aPrincipal)
- {
- ClonedMessageData data;
- if (!BuildClonedMessageDataForParent(this, aHelper, data)) {
- return NS_ERROR_DOM_DATA_CLONE_ERR;
- }
- InfallibleTArray<CpowEntry> cpows;
- jsipc::CPOWManager* mgr = GetCPOWManager();
- if (aCpows && (!mgr || !mgr->Wrap(aCx, aCpows, &cpows))) {
- return NS_ERROR_UNEXPECTED;
- }
- if (!SendAsyncMessage(nsString(aMessage), cpows, Principal(aPrincipal), data)) {
- return NS_ERROR_UNEXPECTED;
- }
- return NS_OK;
- }
- bool
- ContentParent::CheckPermission(const nsAString& aPermission)
- {
- return AssertAppProcessPermission(this, NS_ConvertUTF16toUTF8(aPermission).get());
- }
- bool
- ContentParent::CheckManifestURL(const nsAString& aManifestURL)
- {
- return AssertAppProcessManifestURL(this, NS_ConvertUTF16toUTF8(aManifestURL).get());
- }
- bool
- ContentParent::CheckAppHasPermission(const nsAString& aPermission)
- {
- return AssertAppHasPermission(this, NS_ConvertUTF16toUTF8(aPermission).get());
- }
- bool
- ContentParent::CheckAppHasStatus(unsigned short aStatus)
- {
- return AssertAppHasStatus(this, aStatus);
- }
- bool
- ContentParent::KillChild()
- {
- KillHard("KillChild");
- return true;
- }
- PBlobParent*
- ContentParent::SendPBlobConstructor(PBlobParent* aActor,
- const BlobConstructorParams& aParams)
- {
- return PContentParent::SendPBlobConstructor(aActor, aParams);
- }
- PBrowserParent*
- ContentParent::SendPBrowserConstructor(PBrowserParent* aActor,
- const TabId& aTabId,
- const IPCTabContext& aContext,
- const uint32_t& aChromeFlags,
- const ContentParentId& aCpId,
- const bool& aIsForApp,
- const bool& aIsForBrowser)
- {
- return PContentParent::SendPBrowserConstructor(aActor,
- aTabId,
- aContext,
- aChromeFlags,
- aCpId,
- aIsForApp,
- aIsForBrowser);
- }
- bool
- ContentParent::RecvCreateFakeVolume(const nsString& fsName,
- const nsString& mountPoint)
- {
- NS_WARNING("ContentParent::RecvCreateFakeVolume shouldn't be called");
- return false;
- }
- bool
- ContentParent::RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState)
- {
- NS_WARNING("ContentParent::RecvSetFakeVolumeState shouldn't be called");
- return false;
- }
- bool
- ContentParent::RecvRemoveFakeVolume(const nsString& fsName)
- {
- NS_WARNING("ContentParent::RecvRemoveFakeVolume shouldn't be called");
- return false;
- }
- bool
- ContentParent::RecvKeywordToURI(const nsCString& aKeyword,
- nsString* aProviderName,
- OptionalInputStreamParams* aPostData,
- OptionalURIParams* aURI)
- {
- *aPostData = void_t();
- *aURI = void_t();
- nsCOMPtr<nsIURIFixup> fixup = do_GetService(NS_URIFIXUP_CONTRACTID);
- if (!fixup) {
- return true;
- }
- nsCOMPtr<nsIInputStream> postData;
- nsCOMPtr<nsIURIFixupInfo> info;
- if (NS_FAILED(fixup->KeywordToURI(aKeyword, getter_AddRefs(postData),
- getter_AddRefs(info)))) {
- return true;
- }
- info->GetKeywordProviderName(*aProviderName);
- nsTArray<mozilla::ipc::FileDescriptor> fds;
- SerializeInputStream(postData, *aPostData, fds);
- MOZ_ASSERT(fds.IsEmpty());
- nsCOMPtr<nsIURI> uri;
- info->GetPreferredURI(getter_AddRefs(uri));
- SerializeURI(uri, *aURI);
- return true;
- }
- bool
- ContentParent::RecvNotifyKeywordSearchLoading(const nsString &aProvider,
- const nsString &aKeyword)
- {
- #ifdef MOZ_TOOLKIT_SEARCH
- nsCOMPtr<nsIBrowserSearchService> searchSvc = do_GetService("@mozilla.org/browser/search-service;1");
- if (searchSvc) {
- nsCOMPtr<nsISearchEngine> searchEngine;
- searchSvc->GetEngineByName(aProvider, getter_AddRefs(searchEngine));
- if (searchEngine) {
- nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
- if (obsSvc) {
- // Note that "keyword-search" refers to a search via the url
- // bar, not a bookmarks keyword search.
- obsSvc->NotifyObservers(searchEngine, "keyword-search", aKeyword.get());
- }
- }
- }
- #endif
- return true;
- }
- bool
- ContentParent::RecvCopyFavicon(const URIParams& aOldURI,
- const URIParams& aNewURI,
- const IPC::Principal& aLoadingPrincipal,
- const bool& aInPrivateBrowsing)
- {
- nsCOMPtr<nsIURI> oldURI = DeserializeURI(aOldURI);
- if (!oldURI) {
- return true;
- }
- nsCOMPtr<nsIURI> newURI = DeserializeURI(aNewURI);
- if (!newURI) {
- return true;
- }
- nsDocShell::CopyFavicon(oldURI, newURI, aLoadingPrincipal, aInPrivateBrowsing);
- return true;
- }
- bool
- ContentParent::ShouldContinueFromReplyTimeout()
- {
- RefPtr<ProcessHangMonitor> monitor = ProcessHangMonitor::Get();
- return !monitor || !monitor->ShouldTimeOutCPOWs();
- }
- bool
- ContentParent::RecvRecordingDeviceEvents(const nsString& aRecordingStatus,
- const nsString& aPageURL,
- const bool& aIsAudio,
- const bool& aIsVideo)
- {
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- // recording-device-ipc-events needs to gather more information from content process
- RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
- props->SetPropertyAsUint64(NS_LITERAL_STRING("childID"), ChildID());
- props->SetPropertyAsBool(NS_LITERAL_STRING("isApp"), IsForApp());
- props->SetPropertyAsBool(NS_LITERAL_STRING("isAudio"), aIsAudio);
- props->SetPropertyAsBool(NS_LITERAL_STRING("isVideo"), aIsVideo);
- nsString requestURL = IsForApp() ? AppManifestURL() : aPageURL;
- props->SetPropertyAsAString(NS_LITERAL_STRING("requestURL"), requestURL);
- obs->NotifyObservers((nsIPropertyBag2*) props,
- "recording-device-ipc-events",
- aRecordingStatus.get());
- } else {
- NS_WARNING("Could not get the Observer service for ContentParent::RecvRecordingDeviceEvents.");
- }
- return true;
- }
- bool
- ContentParent::RecvGetGraphicsFeatureStatus(const int32_t& aFeature,
- int32_t* aStatus,
- nsCString* aFailureId,
- bool* aSuccess)
- {
- nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
- if (!gfxInfo) {
- *aSuccess = false;
- return true;
- }
- *aSuccess = NS_SUCCEEDED(gfxInfo->GetFeatureStatus(aFeature, *aFailureId, aStatus));
- return true;
- }
- bool
- ContentParent::RecvAddIdleObserver(const uint64_t& aObserver,
- const uint32_t& aIdleTimeInS)
- {
- nsresult rv;
- nsCOMPtr<nsIIdleService> idleService =
- do_GetService("@mozilla.org/widget/idleservice;1", &rv);
- NS_ENSURE_SUCCESS(rv, false);
- RefPtr<ParentIdleListener> listener =
- new ParentIdleListener(this, aObserver, aIdleTimeInS);
- rv = idleService->AddIdleObserver(listener, aIdleTimeInS);
- NS_ENSURE_SUCCESS(rv, false);
- mIdleListeners.AppendElement(listener);
- return true;
- }
- bool
- ContentParent::RecvRemoveIdleObserver(const uint64_t& aObserver,
- const uint32_t& aIdleTimeInS)
- {
- RefPtr<ParentIdleListener> listener;
- for (int32_t i = mIdleListeners.Length() - 1; i >= 0; --i) {
- listener = static_cast<ParentIdleListener*>(mIdleListeners[i].get());
- if (listener->mObserver == aObserver &&
- listener->mTime == aIdleTimeInS) {
- nsresult rv;
- nsCOMPtr<nsIIdleService> idleService =
- do_GetService("@mozilla.org/widget/idleservice;1", &rv);
- NS_ENSURE_SUCCESS(rv, false);
- idleService->RemoveIdleObserver(listener, aIdleTimeInS);
- mIdleListeners.RemoveElementAt(i);
- break;
- }
- }
- return true;
- }
- bool
- ContentParent::RecvBackUpXResources(const FileDescriptor& aXSocketFd)
- {
- #ifndef MOZ_X11
- NS_RUNTIMEABORT("This message only makes sense on X11 platforms");
- #else
- MOZ_ASSERT(0 > mChildXSocketFdDup.get(),
- "Already backed up X resources??");
- if (aXSocketFd.IsValid()) {
- auto rawFD = aXSocketFd.ClonePlatformHandle();
- mChildXSocketFdDup.reset(rawFD.release());
- }
- #endif
- return true;
- }
- bool
- ContentParent::RecvOpenAnonymousTemporaryFile(FileDescOrError *aFD)
- {
- PRFileDesc *prfd;
- nsresult rv = NS_OpenAnonymousTemporaryFile(&prfd);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- // Returning false will kill the child process; instead
- // propagate the error and let the child handle it.
- *aFD = rv;
- return true;
- }
- *aFD = FileDescriptor(FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(prfd)));
- // The FileDescriptor object owns a duplicate of the file handle; we
- // must close the original (and clean up the NSPR descriptor).
- PR_Close(prfd);
- return true;
- }
- static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
- bool
- ContentParent::RecvKeygenProcessValue(const nsString& oldValue,
- const nsString& challenge,
- const nsString& keytype,
- const nsString& keyparams,
- nsString* newValue)
- {
- nsCOMPtr<nsIFormProcessor> formProcessor =
- do_GetService(kFormProcessorCID);
- if (!formProcessor) {
- newValue->Truncate();
- return true;
- }
- formProcessor->ProcessValueIPC(oldValue, challenge, keytype, keyparams,
- *newValue);
- return true;
- }
- bool
- ContentParent::RecvKeygenProvideContent(nsString* aAttribute,
- nsTArray<nsString>* aContent)
- {
- nsCOMPtr<nsIFormProcessor> formProcessor =
- do_GetService(kFormProcessorCID);
- if (!formProcessor) {
- return true;
- }
- formProcessor->ProvideContent(NS_LITERAL_STRING("SELECT"), *aContent,
- *aAttribute);
- return true;
- }
- PFileDescriptorSetParent*
- ContentParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
- {
- return nsIContentParent::AllocPFileDescriptorSetParent(aFD);
- }
- bool
- ContentParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
- {
- return nsIContentParent::DeallocPFileDescriptorSetParent(aActor);
- }
- bool
- ContentParent::IgnoreIPCPrincipal()
- {
- static bool sDidAddVarCache = false;
- static bool sIgnoreIPCPrincipal = false;
- if (!sDidAddVarCache) {
- sDidAddVarCache = true;
- Preferences::AddBoolVarCache(&sIgnoreIPCPrincipal,
- "dom.testing.ignore_ipc_principal", false);
- }
- return sIgnoreIPCPrincipal;
- }
- void
- ContentParent::NotifyUpdatedDictionaries()
- {
- nsCOMPtr<nsISpellChecker> spellChecker(do_GetService(NS_SPELLCHECKER_CONTRACTID));
- MOZ_ASSERT(spellChecker, "No spell checker?");
- InfallibleTArray<nsString> dictionaries;
- spellChecker->GetDictionaryList(&dictionaries);
- for (auto* cp : AllProcesses(eLive)) {
- Unused << cp->SendUpdateDictionaryList(dictionaries);
- }
- }
- /*static*/ TabId
- ContentParent::AllocateTabId(const TabId& aOpenerTabId,
- const IPCTabContext& aContext,
- const ContentParentId& aCpId)
- {
- TabId tabId;
- if (XRE_IsParentProcess()) {
- ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
- tabId = cpm->AllocateTabId(aOpenerTabId, aContext, aCpId);
- }
- else {
- ContentChild::GetSingleton()->SendAllocateTabId(aOpenerTabId,
- aContext,
- aCpId,
- &tabId);
- }
- return tabId;
- }
- /*static*/ void
- ContentParent::DeallocateTabId(const TabId& aTabId,
- const ContentParentId& aCpId,
- bool aMarkedDestroying)
- {
- if (XRE_IsParentProcess()) {
- ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
- ContentParent* cp = cpm->GetContentProcessById(aCpId);
- cp->NotifyTabDestroyed(aTabId, aMarkedDestroying);
- ContentProcessManager::GetSingleton()->DeallocateTabId(aCpId, aTabId);
- } else {
- ContentChild::GetSingleton()->SendDeallocateTabId(aTabId, aCpId,
- aMarkedDestroying);
- }
- }
- bool
- ContentParent::RecvAllocateTabId(const TabId& aOpenerTabId,
- const IPCTabContext& aContext,
- const ContentParentId& aCpId,
- TabId* aTabId)
- {
- *aTabId = AllocateTabId(aOpenerTabId, aContext, aCpId);
- if (!(*aTabId)) {
- return false;
- }
- return true;
- }
- bool
- ContentParent::RecvDeallocateTabId(const TabId& aTabId,
- const ContentParentId& aCpId,
- const bool& aMarkedDestroying)
- {
- DeallocateTabId(aTabId, aCpId, aMarkedDestroying);
- return true;
- }
- bool
- ContentParent::RecvNotifyTabDestroying(const TabId& aTabId,
- const ContentParentId& aCpId)
- {
- NotifyTabDestroying(aTabId, aCpId);
- return true;
- }
- nsTArray<TabContext>
- ContentParent::GetManagedTabContext()
- {
- return Move(ContentProcessManager::GetSingleton()->
- GetTabContextByContentProcess(this->ChildID()));
- }
- mozilla::docshell::POfflineCacheUpdateParent*
- ContentParent::AllocPOfflineCacheUpdateParent(const URIParams& aManifestURI,
- const URIParams& aDocumentURI,
- const PrincipalInfo& aLoadingPrincipalInfo,
- const bool& aStickDocument)
- {
- RefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
- new mozilla::docshell::OfflineCacheUpdateParent();
- // Use this reference as the IPDL reference.
- return update.forget().take();
- }
- bool
- ContentParent::RecvPOfflineCacheUpdateConstructor(POfflineCacheUpdateParent* aActor,
- const URIParams& aManifestURI,
- const URIParams& aDocumentURI,
- const PrincipalInfo& aLoadingPrincipal,
- const bool& aStickDocument)
- {
- MOZ_ASSERT(aActor);
- RefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
- static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor);
- nsresult rv = update->Schedule(aManifestURI, aDocumentURI, aLoadingPrincipal, aStickDocument);
- if (NS_FAILED(rv) && IsAlive()) {
- // Inform the child of failure.
- Unused << update->SendFinish(false, false);
- }
- return true;
- }
- bool
- ContentParent::DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActor)
- {
- // Reclaim the IPDL reference.
- RefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
- dont_AddRef(static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor));
- return true;
- }
- PWebrtcGlobalParent *
- ContentParent::AllocPWebrtcGlobalParent()
- {
- #ifdef MOZ_WEBRTC
- return WebrtcGlobalParent::Alloc();
- #else
- return nullptr;
- #endif
- }
- bool
- ContentParent::DeallocPWebrtcGlobalParent(PWebrtcGlobalParent *aActor)
- {
- #ifdef MOZ_WEBRTC
- WebrtcGlobalParent::Dealloc(static_cast<WebrtcGlobalParent*>(aActor));
- return true;
- #else
- return false;
- #endif
- }
- bool
- ContentParent::RecvSetOfflinePermission(const Principal& aPrincipal)
- {
- nsIPrincipal* principal = aPrincipal;
- nsContentUtils::MaybeAllowOfflineAppByDefault(principal);
- return true;
- }
- void
- ContentParent::MaybeInvokeDragSession(TabParent* aParent)
- {
- nsCOMPtr<nsIDragService> dragService =
- do_GetService("@mozilla.org/widget/dragservice;1");
- if (dragService && dragService->MaybeAddChildProcess(this)) {
- // We need to send transferable data to child process.
- nsCOMPtr<nsIDragSession> session;
- dragService->GetCurrentSession(getter_AddRefs(session));
- if (session) {
- nsTArray<IPCDataTransfer> dataTransfers;
- nsCOMPtr<nsIDOMDataTransfer> domTransfer;
- session->GetDataTransfer(getter_AddRefs(domTransfer));
- nsCOMPtr<DataTransfer> transfer = do_QueryInterface(domTransfer);
- if (!transfer) {
- // Pass eDrop to get DataTransfer with external
- // drag formats cached.
- transfer = new DataTransfer(nullptr, eDrop, true, -1);
- session->SetDataTransfer(transfer);
- }
- // Note, even though this fills the DataTransfer object with
- // external data, the data is usually transfered over IPC lazily when
- // needed.
- transfer->FillAllExternalData();
- nsCOMPtr<nsILoadContext> lc = aParent ?
- aParent->GetLoadContext() : nullptr;
- nsCOMPtr<nsIArray> transferables =
- transfer->GetTransferables(lc);
- nsContentUtils::TransferablesToIPCTransferables(transferables,
- dataTransfers,
- false,
- nullptr,
- this);
- uint32_t action;
- session->GetDragAction(&action);
- mozilla::Unused << SendInvokeDragSession(dataTransfers, action);
- }
- }
- }
- bool
- ContentParent::RecvUpdateDropEffect(const uint32_t& aDragAction,
- const uint32_t& aDropEffect)
- {
- nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
- if (dragSession) {
- dragSession->SetDragAction(aDragAction);
- nsCOMPtr<nsIDOMDataTransfer> dt;
- dragSession->GetDataTransfer(getter_AddRefs(dt));
- if (dt) {
- dt->SetDropEffectInt(aDropEffect);
- }
- dragSession->UpdateDragEffect();
- }
- return true;
- }
- PContentPermissionRequestParent*
- ContentParent::AllocPContentPermissionRequestParent(const InfallibleTArray<PermissionRequest>& aRequests,
- const IPC::Principal& aPrincipal,
- const TabId& aTabId)
- {
- ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
- RefPtr<TabParent> tp =
- cpm->GetTopLevelTabParentByProcessAndTabId(this->ChildID(), aTabId);
- if (!tp) {
- return nullptr;
- }
- return nsContentPermissionUtils::CreateContentPermissionRequestParent(aRequests,
- tp->GetOwnerElement(),
- aPrincipal,
- aTabId);
- }
- bool
- ContentParent::DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor)
- {
- nsContentPermissionUtils::NotifyRemoveContentPermissionRequestParent(actor);
- delete actor;
- return true;
- }
- PWebBrowserPersistDocumentParent*
- ContentParent::AllocPWebBrowserPersistDocumentParent(PBrowserParent* aBrowser,
- const uint64_t& aOuterWindowID)
- {
- return new WebBrowserPersistDocumentParent();
- }
- bool
- ContentParent::DeallocPWebBrowserPersistDocumentParent(PWebBrowserPersistDocumentParent* aActor)
- {
- delete aActor;
- return true;
- }
- bool
- ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
- PBrowserParent* aNewTab,
- PRenderFrameParent* aRenderFrame,
- const uint32_t& aChromeFlags,
- const bool& aCalledFromJS,
- const bool& aPositionSpecified,
- const bool& aSizeSpecified,
- const nsCString& aFeatures,
- const nsCString& aBaseURI,
- const DocShellOriginAttributes& aOpenerOriginAttributes,
- const float& aFullZoom,
- nsresult* aResult,
- bool* aWindowIsNew,
- InfallibleTArray<FrameScriptInfo>* aFrameScripts,
- nsCString* aURLToLoad,
- TextureFactoryIdentifier* aTextureFactoryIdentifier,
- uint64_t* aLayersId)
- {
- // We always expect to open a new window here. If we don't, it's an error.
- *aWindowIsNew = true;
- *aResult = NS_OK;
- // The content process should never be in charge of computing whether or
- // not a window should be private or remote - the parent will do that.
- const uint32_t badFlags =
- nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW
- | nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW
- | nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME
- | nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
- if (!!(aChromeFlags & badFlags)) {
- return false;
- }
- TabParent* thisTabParent = nullptr;
- if (aThisTab) {
- thisTabParent = TabParent::GetFrom(aThisTab);
- }
- if (NS_WARN_IF(thisTabParent && thisTabParent->IsMozBrowserOrApp())) {
- return false;
- }
- TabParent* newTab = TabParent::GetFrom(aNewTab);
- MOZ_ASSERT(newTab);
- auto destroyNewTabOnError = MakeScopeExit([&] {
- if (!*aWindowIsNew || NS_FAILED(*aResult)) {
- if (newTab) {
- newTab->Destroy();
- }
- }
- });
- // Content has requested that we open this new content window, so
- // we must have an opener.
- newTab->SetHasContentOpener(true);
- nsCOMPtr<nsIContent> frame;
- if (thisTabParent) {
- frame = do_QueryInterface(thisTabParent->GetOwnerElement());
- }
- nsCOMPtr<nsPIDOMWindowOuter> parent;
- if (frame) {
- parent = frame->OwnerDoc()->GetWindow();
- // If our chrome window is in the process of closing, don't try to open a
- // new tab in it.
- if (parent && parent->Closed()) {
- parent = nullptr;
- }
- }
- nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
- if (thisTabParent) {
- browserDOMWin = thisTabParent->GetBrowserDOMWindow();
- }
- // If we haven't found a chrome window to open in, just use the most recently
- // opened one.
- if (!parent) {
- parent = nsContentUtils::GetMostRecentNonPBWindow();
- if (NS_WARN_IF(!parent)) {
- *aResult = NS_ERROR_FAILURE;
- return true;
- }
- nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(parent);
- if (rootChromeWin) {
- rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
- }
- }
- int32_t openLocation =
- nsWindowWatcher::GetWindowOpenLocation(parent, aChromeFlags, aCalledFromJS,
- aPositionSpecified, aSizeSpecified);
- MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
- openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
- // Opening new tabs is the easy case...
- if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
- if (NS_WARN_IF(!browserDOMWin)) {
- *aResult = NS_ERROR_ABORT;
- return true;
- }
- bool isPrivate = false;
- if (thisTabParent) {
- nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
- loadContext->GetUsePrivateBrowsing(&isPrivate);
- }
- nsCOMPtr<nsIOpenURIInFrameParams> params =
- new nsOpenURIInFrameParams(aOpenerOriginAttributes);
- params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI));
- params->SetIsPrivate(isPrivate);
- TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
- nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
- browserDOMWin->OpenURIInFrame(nullptr, params,
- openLocation,
- nsIBrowserDOMWindow::OPEN_NEW,
- getter_AddRefs(frameLoaderOwner));
- if (!frameLoaderOwner) {
- *aWindowIsNew = false;
- }
- newTab->SwapFrameScriptsFrom(*aFrameScripts);
- RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
- if (!newTab->SetRenderFrame(rfp) ||
- !newTab->GetRenderFrameInfo(aTextureFactoryIdentifier, aLayersId)) {
- *aResult = NS_ERROR_FAILURE;
- }
- return true;
- }
- TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
- nsCOMPtr<nsPIWindowWatcher> pwwatch =
- do_GetService(NS_WINDOWWATCHER_CONTRACTID, aResult);
- if (NS_WARN_IF(NS_FAILED(*aResult))) {
- return true;
- }
- nsCOMPtr<nsITabParent> newRemoteTab;
- if (!thisTabParent) {
- // Because we weren't passed an opener tab, the content process has asked us
- // to open a new window that is unrelated to a pre-existing tab.
- *aResult = pwwatch->OpenWindowWithoutParent(getter_AddRefs(newRemoteTab));
- } else {
- *aResult = pwwatch->OpenWindowWithTabParent(thisTabParent, aFeatures, aCalledFromJS,
- aFullZoom, getter_AddRefs(newRemoteTab));
- }
- if (NS_WARN_IF(NS_FAILED(*aResult))) {
- return true;
- }
- MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
- newTab->SwapFrameScriptsFrom(*aFrameScripts);
- RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
- if (!newTab->SetRenderFrame(rfp) ||
- !newTab->GetRenderFrameInfo(aTextureFactoryIdentifier, aLayersId)) {
- *aResult = NS_ERROR_FAILURE;
- }
- return true;
- }
- bool
- ContentParent::RecvGetGraphicsDeviceInitData(ContentDeviceData* aOut)
- {
- gfxPlatform::GetPlatform()->BuildContentDeviceData(aOut);
- return true;
- }
- bool
- ContentParent::RecvGraphicsError(const nsCString& aError)
- {
- gfx::LogForwarder* lf = gfx::Factory::GetLogForwarder();
- if (lf) {
- std::stringstream message;
- message << "CP+" << aError.get();
- lf->UpdateStringsVector(message.str());
- }
- return true;
- }
- bool
- ContentParent::RecvBeginDriverCrashGuard(const uint32_t& aGuardType, bool* aOutCrashed)
- {
- // Only one driver crash guard should be active at a time, per-process.
- MOZ_ASSERT(!mDriverCrashGuard);
- UniquePtr<gfx::DriverCrashGuard> guard;
- switch (gfx::CrashGuardType(aGuardType)) {
- case gfx::CrashGuardType::D3D11Layers:
- guard = MakeUnique<gfx::D3D11LayersCrashGuard>(this);
- break;
- case gfx::CrashGuardType::D3D9Video:
- guard = MakeUnique<gfx::D3D9VideoCrashGuard>(this);
- break;
- case gfx::CrashGuardType::GLContext:
- guard = MakeUnique<gfx::GLContextCrashGuard>(this);
- break;
- case gfx::CrashGuardType::D3D11Video:
- guard = MakeUnique<gfx::D3D11VideoCrashGuard>(this);
- break;
- default:
- MOZ_ASSERT_UNREACHABLE("unknown crash guard type");
- return false;
- }
- if (guard->Crashed()) {
- *aOutCrashed = true;
- return true;
- }
- *aOutCrashed = false;
- mDriverCrashGuard = Move(guard);
- return true;
- }
- bool
- ContentParent::RecvEndDriverCrashGuard(const uint32_t& aGuardType)
- {
- mDriverCrashGuard = nullptr;
- return true;
- }
- bool
- ContentParent::RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo)
- {
- MOZ_CRASH("wrong platform!");
- return false;
- }
- bool
- ContentParent::RecvNotifyBenchmarkResult(const nsString& aCodecName,
- const uint32_t& aDecodeFPS)
- {
- if (aCodecName.EqualsLiteral("VP9")) {
- Preferences::SetUint(VP9Benchmark::sBenchmarkFpsPref, aDecodeFPS);
- Preferences::SetUint(VP9Benchmark::sBenchmarkFpsVersionCheck,
- VP9Benchmark::sBenchmarkVersionID);
- }
- return true;
- }
- bool
- ContentParent::RecvNotifyPushObservers(const nsCString& aScope,
- const IPC::Principal& aPrincipal,
- const nsString& aMessageId)
- {
- PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Nothing());
- Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
- return true;
- }
- bool
- ContentParent::RecvNotifyPushObserversWithData(const nsCString& aScope,
- const IPC::Principal& aPrincipal,
- const nsString& aMessageId,
- InfallibleTArray<uint8_t>&& aData)
- {
- PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Some(aData));
- Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
- return true;
- }
- bool
- ContentParent::RecvNotifyPushSubscriptionChangeObservers(const nsCString& aScope,
- const IPC::Principal& aPrincipal)
- {
- PushSubscriptionChangeDispatcher dispatcher(aScope, aPrincipal);
- Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
- return true;
- }
- bool
- ContentParent::RecvNotifyPushSubscriptionModifiedObservers(const nsCString& aScope,
- const IPC::Principal& aPrincipal)
- {
- PushSubscriptionModifiedDispatcher dispatcher(aScope, aPrincipal);
- Unused << NS_WARN_IF(NS_FAILED(dispatcher.NotifyObservers()));
- return true;
- }
- bool
- ContentParent::RecvNotifyLowMemory()
- {
- return true;
- }
- /* static */ void
- ContentParent::BroadcastBlobURLRegistration(const nsACString& aURI,
- BlobImpl* aBlobImpl,
- nsIPrincipal* aPrincipal,
- ContentParent* aIgnoreThisCP)
- {
- nsCString uri(aURI);
- IPC::Principal principal(aPrincipal);
- for (auto* cp : AllProcesses(eLive)) {
- if (cp != aIgnoreThisCP) {
- PBlobParent* blobParent = cp->GetOrCreateActorForBlobImpl(aBlobImpl);
- if (blobParent) {
- Unused << cp->SendBlobURLRegistration(uri, blobParent, principal);
- }
- }
- }
- }
- /* static */ void
- ContentParent::BroadcastBlobURLUnregistration(const nsACString& aURI,
- ContentParent* aIgnoreThisCP)
- {
- nsCString uri(aURI);
- for (auto* cp : AllProcesses(eLive)) {
- if (cp != aIgnoreThisCP) {
- Unused << cp->SendBlobURLUnregistration(uri);
- }
- }
- }
- bool
- ContentParent::RecvStoreAndBroadcastBlobURLRegistration(const nsCString& aURI,
- PBlobParent* aBlobParent,
- const Principal& aPrincipal)
- {
- RefPtr<BlobImpl> blobImpl =
- static_cast<BlobParent*>(aBlobParent)->GetBlobImpl();
- if (NS_WARN_IF(!blobImpl)) {
- return false;
- }
- if (NS_SUCCEEDED(nsHostObjectProtocolHandler::AddDataEntry(aURI, aPrincipal,
- blobImpl))) {
- BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, this);
- // We want to store this blobURL, so we can unregister it if the child
- // crashes.
- mBlobURLs.AppendElement(aURI);
- }
- BroadcastBlobURLRegistration(aURI, blobImpl, aPrincipal, this);
- return true;
- }
- bool
- ContentParent::RecvUnstoreAndBroadcastBlobURLUnregistration(const nsCString& aURI)
- {
- nsHostObjectProtocolHandler::RemoveDataEntry(aURI,
- false /* Don't broadcast */);
- BroadcastBlobURLUnregistration(aURI, this);
- mBlobURLs.RemoveElement(aURI);
- return true;
- }
- bool
- ContentParent::RecvGetA11yContentId(uint32_t* aContentId)
- {
- #if defined(XP_WIN32) && defined(ACCESSIBILITY)
- *aContentId = a11y::AccessibleWrap::GetContentProcessIdFor(ChildID());
- MOZ_ASSERT(*aContentId);
- return true;
- #else
- return false;
- #endif
- }
- } // namespace dom
- } // namespace mozilla
- NS_IMPL_ISUPPORTS(ParentIdleListener, nsIObserver)
- NS_IMETHODIMP
- ParentIdleListener::Observe(nsISupports*, const char* aTopic, const char16_t* aData)
- {
- mozilla::Unused << mParent->SendNotifyIdleObserver(mObserver,
- nsDependentCString(aTopic),
- nsDependentString(aData));
- return NS_OK;
- }
- bool
- ContentParent::HandleWindowsMessages(const Message& aMsg) const
- {
- MOZ_ASSERT(aMsg.is_sync());
- // a11y messages can be triggered by windows messages, which means if we
- // allow handling windows messages while we wait for the response to a sync
- // a11y message we can reenter the ipc message sending code.
- if (a11y::PDocAccessible::PDocAccessibleStart < aMsg.type() &&
- a11y::PDocAccessible::PDocAccessibleEnd > aMsg.type()) {
- return false;
- }
- return true;
- }
- bool
- ContentParent::RecvGetFilesRequest(const nsID& aUUID,
- const nsString& aDirectoryPath,
- const bool& aRecursiveFlag)
- {
- MOZ_ASSERT(!mGetFilesPendingRequests.GetWeak(aUUID));
- if (!mozilla::Preferences::GetBool("dom.filesystem.pathcheck.disabled", false)) {
- RefPtr<FileSystemSecurity> fss = FileSystemSecurity::Get();
- if (NS_WARN_IF(!fss ||
- !fss->ContentProcessHasAccessTo(ChildID(), aDirectoryPath))) {
- return false;
- }
- }
- ErrorResult rv;
- RefPtr<GetFilesHelper> helper =
- GetFilesHelperParent::Create(aUUID, aDirectoryPath, aRecursiveFlag, this,
- rv);
- if (NS_WARN_IF(rv.Failed())) {
- return SendGetFilesResponse(aUUID,
- GetFilesResponseFailure(rv.StealNSResult()));
- }
- mGetFilesPendingRequests.Put(aUUID, helper);
- return true;
- }
- bool
- ContentParent::RecvDeleteGetFilesRequest(const nsID& aUUID)
- {
- GetFilesHelper* helper = mGetFilesPendingRequests.GetWeak(aUUID);
- if (helper) {
- mGetFilesPendingRequests.Remove(aUUID);
- }
- return true;
- }
- void
- ContentParent::SendGetFilesResponseAndForget(const nsID& aUUID,
- const GetFilesResponseResult& aResult)
- {
- GetFilesHelper* helper = mGetFilesPendingRequests.GetWeak(aUUID);
- if (helper) {
- mGetFilesPendingRequests.Remove(aUUID);
- Unused << SendGetFilesResponse(aUUID, aResult);
- }
- }
- void
- ContentParent::ForceTabPaint(TabParent* aTabParent, uint64_t aLayerObserverEpoch)
- {
- if (!mHangMonitorActor) {
- return;
- }
- ProcessHangMonitor::ForcePaint(mHangMonitorActor, aTabParent, aLayerObserverEpoch);
- }
|