JSProcessActorProtocol.cpp (4713B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 3 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 4 /* This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 8 #include "mozilla/dom/JSProcessActorProtocol.h" 9 10 #include "JSActorProtocolUtils.h" 11 #include "mozilla/dom/ContentChild.h" 12 #include "mozilla/dom/ContentParent.h" 13 #include "mozilla/dom/InProcessChild.h" 14 #include "mozilla/dom/JSActorBinding.h" 15 #include "mozilla/dom/JSProcessActorBinding.h" 16 #include "mozilla/dom/PContent.h" 17 #include "nsContentUtils.h" 18 19 namespace mozilla::dom { 20 21 NS_IMPL_CYCLE_COLLECTING_ADDREF(JSProcessActorProtocol) 22 NS_IMPL_CYCLE_COLLECTING_RELEASE(JSProcessActorProtocol) 23 24 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JSProcessActorProtocol) 25 NS_INTERFACE_MAP_ENTRY(nsIObserver) 26 NS_INTERFACE_MAP_END 27 28 NS_IMPL_CYCLE_COLLECTION(JSProcessActorProtocol) 29 30 /* static */ already_AddRefed<JSProcessActorProtocol> 31 JSProcessActorProtocol::FromIPC(const JSProcessActorInfo& aInfo) { 32 MOZ_DIAGNOSTIC_ASSERT(XRE_IsContentProcess()); 33 34 RefPtr<JSProcessActorProtocol> proto = 35 new JSProcessActorProtocol(aInfo.name()); 36 JSActorProtocolUtils::FromIPCShared(proto, aInfo); 37 38 // Content processes aren't the parent process, so this flag is irrelevant and 39 // not propagated. 40 proto->mIncludeParent = false; 41 42 return proto.forget(); 43 } 44 45 JSProcessActorInfo JSProcessActorProtocol::ToIPC() { 46 MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess()); 47 48 JSProcessActorInfo info; 49 JSActorProtocolUtils::ToIPCShared(info, this); 50 51 return info; 52 } 53 54 already_AddRefed<JSProcessActorProtocol> 55 JSProcessActorProtocol::FromWebIDLOptions(const nsACString& aName, 56 const ProcessActorOptions& aOptions, 57 ErrorResult& aRv) { 58 MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess()); 59 60 RefPtr<JSProcessActorProtocol> proto = new JSProcessActorProtocol(aName); 61 if (!JSActorProtocolUtils::FromWebIDLOptionsShared(proto, aOptions, aRv)) { 62 return nullptr; 63 } 64 65 proto->mIncludeParent = aOptions.mIncludeParent; 66 67 proto->mLoadInDevToolsLoader = aOptions.mLoadInDevToolsLoader; 68 69 return proto.forget(); 70 } 71 72 NS_IMETHODIMP JSProcessActorProtocol::Observe(nsISupports* aSubject, 73 const char* aTopic, 74 const char16_t* aData) { 75 MOZ_ASSERT(nsContentUtils::IsSafeToRunScript()); 76 77 RefPtr<JSActorManager> manager; 78 if (XRE_IsParentProcess()) { 79 manager = InProcessChild::Singleton(); 80 } else { 81 manager = ContentChild::GetSingleton(); 82 } 83 84 // Ensure our actor is present. 85 AutoJSAPI jsapi; 86 jsapi.Init(); 87 RefPtr<JSActor> actor = manager->GetActor(jsapi.cx(), mName, IgnoreErrors()); 88 if (!actor || NS_WARN_IF(!actor->GetWrapperPreserveColor())) { 89 return NS_OK; 90 } 91 92 // Build a observer callback. 93 JS::Rooted<JSObject*> global(jsapi.cx(), 94 JS::GetNonCCWObjectGlobal(actor->GetWrapper())); 95 RefPtr<MozObserverCallback> observerCallback = 96 new MozObserverCallback(actor->GetWrapper(), global, nullptr, nullptr); 97 observerCallback->Observe(aSubject, nsDependentCString(aTopic), 98 aData ? nsDependentString(aData) : VoidString()); 99 return NS_OK; 100 } 101 102 void JSProcessActorProtocol::AddObservers() { 103 nsCOMPtr<nsIObserverService> os = services::GetObserverService(); 104 for (auto& topic : mChild.mObservers) { 105 // This makes the observer service hold an owning reference to the 106 // JSProcessActorProtocol. The JSWindowActorProtocol objects will be living 107 // for the full lifetime of the content process, thus the extra strong 108 // referencec doesn't have a negative impact. 109 os->AddObserver(this, topic.get(), false); 110 } 111 } 112 113 void JSProcessActorProtocol::RemoveObservers() { 114 nsCOMPtr<nsIObserverService> os = services::GetObserverService(); 115 for (auto& topic : mChild.mObservers) { 116 os->RemoveObserver(this, topic.get()); 117 } 118 } 119 120 bool JSProcessActorProtocol::Matches(const nsACString& aRemoteType, 121 ErrorResult& aRv) { 122 if (!mIncludeParent && aRemoteType.IsEmpty()) { 123 aRv.ThrowNotSupportedError(nsPrintfCString( 124 "Process protocol '%s' doesn't match the parent process", mName.get())); 125 return false; 126 } 127 128 if (!RemoteTypePrefixMatches(aRemoteType)) { 129 aRv.ThrowNotSupportedError(nsPrintfCString( 130 "Process protocol '%s' doesn't support remote type '%s'", mName.get(), 131 PromiseFlatCString(aRemoteType).get())); 132 return false; 133 } 134 135 return true; 136 } 137 138 } // namespace mozilla::dom