ExtensionKitUtils.mm (4869B)
1 /* -*- Mode: c++; c-basic-offset: 2; tab-width: 4; indent-tabs-mode: nil; -*- 2 * vim: set sw=2 ts=4 expandtab: 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 "ExtensionKitUtils.h" 8 #include "LaunchError.h" 9 10 #import <BrowserEngineKit/BrowserEngineKit.h> 11 12 #import "mozilla/widget/GeckoViewSupport.h" 13 14 using namespace mozilla::widget; 15 16 namespace mozilla::ipc { 17 18 void BEProcessCapabilityGrantDeleter::operator()(void* aGrant) const { 19 auto grant = static_cast<id<BEProcessCapabilityGrant>>(aGrant); 20 [grant invalidate]; 21 [grant release]; 22 } 23 24 void ExtensionKitProcess::StartProcess( 25 Kind aKind, 26 const std::function<void(Result<ExtensionKitProcess, LaunchError>&&)>& 27 aCompletion) { 28 auto callCompletion = [=](auto* aProcess, NSError* aError) { 29 if (aProcess) { 30 [aProcess retain]; 31 aCompletion(ExtensionKitProcess(aKind, aProcess)); 32 } else { 33 NSLog(@"Error launching process, description '%@', reason '%@'", 34 [aError localizedDescription], [aError localizedFailureReason]); 35 aCompletion(Err(LaunchError("ExtensionKitProcess::StartProcess"))); 36 } 37 }; 38 39 switch (aKind) { 40 case Kind::WebContent: { 41 [BEWebContentProcess 42 webContentProcessWithInterruptionHandler:^{ 43 } 44 completion:^(BEWebContentProcess* process, NSError* error) { 45 callCompletion(process, error); 46 }]; 47 return; 48 } 49 case Kind::Networking: { 50 [BENetworkingProcess 51 networkProcessWithInterruptionHandler:^{ 52 } 53 completion:^(BENetworkingProcess* process, NSError* error) { 54 callCompletion(process, error); 55 }]; 56 return; 57 } 58 case Kind::Rendering: { 59 [BERenderingProcess 60 renderingProcessWithInterruptionHandler:^{ 61 } 62 completion:^(BERenderingProcess* process, NSError* error) { 63 callCompletion(process, error); 64 }]; 65 return; 66 } 67 } 68 } 69 70 template <typename F> 71 static void SwitchObject(ExtensionKitProcess::Kind aKind, void* aProcessObject, 72 F&& aMatcher) { 73 switch (aKind) { 74 case ExtensionKitProcess::Kind::WebContent: 75 aMatcher(static_cast<BEWebContentProcess*>(aProcessObject)); 76 break; 77 case ExtensionKitProcess::Kind::Networking: 78 aMatcher(static_cast<BENetworkingProcess*>(aProcessObject)); 79 break; 80 case ExtensionKitProcess::Kind::Rendering: 81 aMatcher(static_cast<BERenderingProcess*>(aProcessObject)); 82 break; 83 } 84 } 85 86 DarwinObjectPtr<xpc_connection_t> ExtensionKitProcess::MakeLibXPCConnection() { 87 NSError* error = nullptr; 88 DarwinObjectPtr<xpc_connection_t> xpcConnection; 89 SwitchObject(mKind, mProcessObject, [&](auto* aProcessObject) { 90 xpcConnection = [aProcessObject makeLibXPCConnectionError:&error]; 91 }); 92 return xpcConnection; 93 } 94 95 void ExtensionKitProcess::Invalidate() { 96 SwitchObject(mKind, mProcessObject, 97 [&](auto* aProcessObject) { [aProcessObject invalidate]; }); 98 } 99 100 UniqueBEProcessCapabilityGrant 101 ExtensionKitProcess::GrantForegroundCapability() { 102 NSError* error = nullptr; 103 BEProcessCapability* cap = [BEProcessCapability foreground]; 104 id<BEProcessCapabilityGrant> grant = nil; 105 SwitchObject(mKind, mProcessObject, [&](auto* aProcessObject) { 106 grant = [aProcessObject grantCapability:cap error:&error]; 107 }); 108 return UniqueBEProcessCapabilityGrant(grant ? [grant retain] : nil); 109 } 110 111 ExtensionKitProcess::ExtensionKitProcess(const ExtensionKitProcess& aOther) 112 : mKind(aOther.mKind), mProcessObject(aOther.mProcessObject) { 113 SwitchObject(mKind, mProcessObject, 114 [&](auto* aProcessObject) { [aProcessObject retain]; }); 115 } 116 117 ExtensionKitProcess& ExtensionKitProcess::operator=( 118 const ExtensionKitProcess& aOther) { 119 Kind oldKind = std::exchange(mKind, aOther.mKind); 120 void* oldProcessObject = std::exchange(mProcessObject, aOther.mProcessObject); 121 SwitchObject(mKind, mProcessObject, 122 [&](auto* aProcessObject) { [aProcessObject retain]; }); 123 SwitchObject(oldKind, oldProcessObject, 124 [&](auto* aProcessObject) { [aProcessObject release]; }); 125 return *this; 126 } 127 128 ExtensionKitProcess::~ExtensionKitProcess() { 129 SwitchObject(mKind, mProcessObject, 130 [&](auto* aProcessObject) { [aProcessObject release]; }); 131 } 132 133 void LockdownExtensionKitProcess(ExtensionKitSandboxRevision aRevision) { 134 if (id<GeckoProcessExtension> process = GetCurrentProcessExtension()) { 135 switch (aRevision) { 136 case ExtensionKitSandboxRevision::Revision1: 137 [process lockdownSandbox:@"1.0"]; 138 return; 139 default: 140 NSLog(@"Unknown ExtensionKit sandbox revision"); 141 return; 142 } 143 } 144 } 145 146 } // namespace mozilla::ipc