1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "mozilla/dom/ContentBridgeParent.h"
8 #include "mozilla/dom/TabParent.h"
9 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
10 #include "nsXULAppAPI.h"
11 #include "nsIObserverService.h"
12 #include "base/task.h"
13
14 using namespace mozilla::ipc;
15 using namespace mozilla::jsipc;
16
17 namespace mozilla {
18 namespace dom {
19
NS_IMPL_ISUPPORTS(ContentBridgeParent,nsIContentParent,nsIObserver)20 NS_IMPL_ISUPPORTS(ContentBridgeParent,
21 nsIContentParent,
22 nsIObserver)
23
24 ContentBridgeParent::ContentBridgeParent(Transport* aTransport)
25 : mTransport(aTransport)
26 {}
27
~ContentBridgeParent()28 ContentBridgeParent::~ContentBridgeParent()
29 {
30 }
31
32 void
ActorDestroy(ActorDestroyReason aWhy)33 ContentBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
34 {
35 nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
36 if (os) {
37 os->RemoveObserver(this, "content-child-shutdown");
38 }
39 MessageLoop::current()->PostTask(NewRunnableMethod(this, &ContentBridgeParent::DeferredDestroy));
40 }
41
42 /*static*/ ContentBridgeParent*
Create(Transport * aTransport,ProcessId aOtherPid)43 ContentBridgeParent::Create(Transport* aTransport, ProcessId aOtherPid)
44 {
45 RefPtr<ContentBridgeParent> bridge =
46 new ContentBridgeParent(aTransport);
47 bridge->mSelfRef = bridge;
48
49 DebugOnly<bool> ok = bridge->Open(aTransport, aOtherPid,
50 XRE_GetIOMessageLoop());
51 MOZ_ASSERT(ok);
52
53 nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
54 if (os) {
55 os->AddObserver(bridge, "content-child-shutdown", false);
56 }
57
58 // Initialize the message manager (and load delayed scripts) now that we
59 // have established communications with the child.
60 bridge->mMessageManager->InitWithCallback(bridge);
61
62 return bridge.get();
63 }
64
65 void
DeferredDestroy()66 ContentBridgeParent::DeferredDestroy()
67 {
68 mSelfRef = nullptr;
69 // |this| was just destroyed, hands off
70 }
71
72 bool
RecvSyncMessage(const nsString & aMsg,const ClonedMessageData & aData,InfallibleTArray<jsipc::CpowEntry> && aCpows,const IPC::Principal & aPrincipal,nsTArray<StructuredCloneData> * aRetvals)73 ContentBridgeParent::RecvSyncMessage(const nsString& aMsg,
74 const ClonedMessageData& aData,
75 InfallibleTArray<jsipc::CpowEntry>&& aCpows,
76 const IPC::Principal& aPrincipal,
77 nsTArray<StructuredCloneData>* aRetvals)
78 {
79 return nsIContentParent::RecvSyncMessage(aMsg, aData, Move(aCpows),
80 aPrincipal, aRetvals);
81 }
82
83 bool
RecvAsyncMessage(const nsString & aMsg,InfallibleTArray<jsipc::CpowEntry> && aCpows,const IPC::Principal & aPrincipal,const ClonedMessageData & aData)84 ContentBridgeParent::RecvAsyncMessage(const nsString& aMsg,
85 InfallibleTArray<jsipc::CpowEntry>&& aCpows,
86 const IPC::Principal& aPrincipal,
87 const ClonedMessageData& aData)
88 {
89 return nsIContentParent::RecvAsyncMessage(aMsg, Move(aCpows),
90 aPrincipal, aData);
91 }
92
93 PBlobParent*
SendPBlobConstructor(PBlobParent * actor,const BlobConstructorParams & params)94 ContentBridgeParent::SendPBlobConstructor(PBlobParent* actor,
95 const BlobConstructorParams& params)
96 {
97 return PContentBridgeParent::SendPBlobConstructor(actor, params);
98 }
99
100 PBrowserParent*
SendPBrowserConstructor(PBrowserParent * aActor,const TabId & aTabId,const IPCTabContext & aContext,const uint32_t & aChromeFlags,const ContentParentId & aCpID,const bool & aIsForApp,const bool & aIsForBrowser)101 ContentBridgeParent::SendPBrowserConstructor(PBrowserParent* aActor,
102 const TabId& aTabId,
103 const IPCTabContext& aContext,
104 const uint32_t& aChromeFlags,
105 const ContentParentId& aCpID,
106 const bool& aIsForApp,
107 const bool& aIsForBrowser)
108 {
109 return PContentBridgeParent::SendPBrowserConstructor(aActor,
110 aTabId,
111 aContext,
112 aChromeFlags,
113 aCpID,
114 aIsForApp,
115 aIsForBrowser);
116 }
117
118 PBlobParent*
AllocPBlobParent(const BlobConstructorParams & aParams)119 ContentBridgeParent::AllocPBlobParent(const BlobConstructorParams& aParams)
120 {
121 return nsIContentParent::AllocPBlobParent(aParams);
122 }
123
124 bool
DeallocPBlobParent(PBlobParent * aActor)125 ContentBridgeParent::DeallocPBlobParent(PBlobParent* aActor)
126 {
127 return nsIContentParent::DeallocPBlobParent(aActor);
128 }
129
130 mozilla::jsipc::PJavaScriptParent *
AllocPJavaScriptParent()131 ContentBridgeParent::AllocPJavaScriptParent()
132 {
133 return nsIContentParent::AllocPJavaScriptParent();
134 }
135
136 bool
DeallocPJavaScriptParent(PJavaScriptParent * parent)137 ContentBridgeParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
138 {
139 return nsIContentParent::DeallocPJavaScriptParent(parent);
140 }
141
142 PBrowserParent*
AllocPBrowserParent(const TabId & aTabId,const IPCTabContext & aContext,const uint32_t & aChromeFlags,const ContentParentId & aCpID,const bool & aIsForApp,const bool & aIsForBrowser)143 ContentBridgeParent::AllocPBrowserParent(const TabId& aTabId,
144 const IPCTabContext &aContext,
145 const uint32_t& aChromeFlags,
146 const ContentParentId& aCpID,
147 const bool& aIsForApp,
148 const bool& aIsForBrowser)
149 {
150 return nsIContentParent::AllocPBrowserParent(aTabId,
151 aContext,
152 aChromeFlags,
153 aCpID,
154 aIsForApp,
155 aIsForBrowser);
156 }
157
158 bool
DeallocPBrowserParent(PBrowserParent * aParent)159 ContentBridgeParent::DeallocPBrowserParent(PBrowserParent* aParent)
160 {
161 return nsIContentParent::DeallocPBrowserParent(aParent);
162 }
163
164 void
NotifyTabDestroyed()165 ContentBridgeParent::NotifyTabDestroyed()
166 {
167 int32_t numLiveTabs = ManagedPBrowserParent().Count();
168 if (numLiveTabs == 1) {
169 MessageLoop::current()->PostTask(NewRunnableMethod(this, &ContentBridgeParent::Close));
170 }
171 }
172
173 // This implementation is identical to ContentParent::GetCPOWManager but we can't
174 // move it to nsIContentParent because it calls ManagedPJavaScriptParent() which
175 // only exists in PContentParent and PContentBridgeParent.
176 jsipc::CPOWManager*
GetCPOWManager()177 ContentBridgeParent::GetCPOWManager()
178 {
179 if (PJavaScriptParent* p = LoneManagedOrNullAsserts(ManagedPJavaScriptParent())) {
180 return CPOWManagerFor(p);
181 }
182 return nullptr;
183 }
184
185 NS_IMETHODIMP
Observe(nsISupports * aSubject,const char * aTopic,const char16_t * aData)186 ContentBridgeParent::Observe(nsISupports* aSubject,
187 const char* aTopic,
188 const char16_t* aData)
189 {
190 if (!strcmp(aTopic, "content-child-shutdown")) {
191 Close();
192 }
193 return NS_OK;
194 }
195
196 PFileDescriptorSetParent*
AllocPFileDescriptorSetParent(const FileDescriptor & aFD)197 ContentBridgeParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
198 {
199 return nsIContentParent::AllocPFileDescriptorSetParent(aFD);
200 }
201
202 bool
DeallocPFileDescriptorSetParent(PFileDescriptorSetParent * aActor)203 ContentBridgeParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
204 {
205 return nsIContentParent::DeallocPFileDescriptorSetParent(aActor);
206 }
207
208 PSendStreamParent*
AllocPSendStreamParent()209 ContentBridgeParent::AllocPSendStreamParent()
210 {
211 return nsIContentParent::AllocPSendStreamParent();
212 }
213
214 bool
DeallocPSendStreamParent(PSendStreamParent * aActor)215 ContentBridgeParent::DeallocPSendStreamParent(PSendStreamParent* aActor)
216 {
217 return nsIContentParent::DeallocPSendStreamParent(aActor);
218 }
219
220 } // namespace dom
221 } // namespace mozilla
222