JSProcessActorChild.cpp (3179B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 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 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/dom/JSProcessActorChild.h" 8 9 #include "mozilla/dom/ContentChild.h" 10 #include "mozilla/dom/InProcessChild.h" 11 #include "mozilla/dom/InProcessParent.h" 12 #include "mozilla/dom/JSIPCValue.h" 13 #include "mozilla/dom/JSIPCValueUtils.h" 14 #include "mozilla/dom/JSProcessActorBinding.h" 15 16 namespace mozilla::dom { 17 18 NS_IMPL_CYCLE_COLLECTION_INHERITED(JSProcessActorChild, JSActor, mManager) 19 20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JSProcessActorChild) 21 NS_INTERFACE_MAP_END_INHERITING(JSActor) 22 23 NS_IMPL_ADDREF_INHERITED(JSProcessActorChild, JSActor) 24 NS_IMPL_RELEASE_INHERITED(JSProcessActorChild, JSActor) 25 26 JSObject* JSProcessActorChild::WrapObject(JSContext* aCx, 27 JS::Handle<JSObject*> aGivenProto) { 28 return JSProcessActorChild_Binding::Wrap(aCx, this, aGivenProto); 29 } 30 31 void JSProcessActorChild::SendRawMessage( 32 const JSActorMessageMeta& aMeta, JSIPCValue&& aData, 33 UniquePtr<ipc::StructuredCloneData> aStack, ErrorResult& aRv) { 34 if (NS_WARN_IF(!CanSend() || !mManager || !mManager->GetCanSend())) { 35 aRv.ThrowInvalidStateError("JSProcessActorChild cannot send at the moment"); 36 return; 37 } 38 39 // If the parent side is in the same process, we have a PInProcess manager, 40 // and can dispatch the message directly to the event loop. 41 ContentChild* contentChild = mManager->AsContentChild(); 42 if (!contentChild) { 43 SendRawMessageInProcess(aMeta, std::move(aData), std::move(aStack), []() { 44 return do_AddRef(InProcessParent::Singleton()); 45 }); 46 return; 47 } 48 49 // Cross-process case - send data over ContentChild to other side. 50 JSIPCValueUtils::SCDHolder holder; 51 if (NS_WARN_IF(!JSIPCValueUtils::PrepareForSending(holder, aData))) { 52 aRv.ThrowDataCloneError( 53 nsPrintfCString("JSProcessActorChild serialization error: cannot " 54 "clone, in actor '%s'", 55 PromiseFlatCString(aMeta.actorName()).get())); 56 return; 57 } 58 59 UniquePtr<ClonedMessageData> stackData; 60 if (aStack) { 61 stackData = MakeUnique<ClonedMessageData>(); 62 if (!aStack->BuildClonedMessageData(*stackData)) { 63 stackData.reset(); 64 } 65 } 66 67 if (NS_WARN_IF(!contentChild->SendRawMessage(aMeta, aData, stackData))) { 68 aRv.ThrowOperationError( 69 nsPrintfCString("JSProcessActorChild send error in actor '%s'", 70 PromiseFlatCString(aMeta.actorName()).get())); 71 return; 72 } 73 } 74 75 void JSProcessActorChild::Init(const nsACString& aName, 76 nsIDOMProcessChild* aManager) { 77 MOZ_ASSERT(!mManager, "Cannot Init() a JSProcessActorChild twice!"); 78 mManager = aManager; 79 bool sendTyped = 80 !!mManager->AsContentChild() && JSActorSupportsTypedSend(aName); 81 JSActor::Init(aName, sendTyped); 82 } 83 84 void JSProcessActorChild::ClearManager() { mManager = nullptr; } 85 86 } // namespace mozilla::dom