File: ExtensionKitUtils.mm

package info (click to toggle)
firefox 147.0.4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,532 kB
  • sloc: cpp: 7,607,356; javascript: 6,533,348; ansic: 3,775,236; python: 1,415,508; xml: 634,561; asm: 438,949; java: 186,241; sh: 62,760; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (146 lines) | stat: -rw-r--r-- 4,869 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* -*- Mode: c++; c-basic-offset: 2; tab-width: 4; indent-tabs-mode: nil; -*-
 * vim: set sw=2 ts=4 expandtab:
 * 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 "ExtensionKitUtils.h"
#include "LaunchError.h"

#import <BrowserEngineKit/BrowserEngineKit.h>

#import "mozilla/widget/GeckoViewSupport.h"

using namespace mozilla::widget;

namespace mozilla::ipc {

void BEProcessCapabilityGrantDeleter::operator()(void* aGrant) const {
  auto grant = static_cast<id<BEProcessCapabilityGrant>>(aGrant);
  [grant invalidate];
  [grant release];
}

void ExtensionKitProcess::StartProcess(
    Kind aKind,
    const std::function<void(Result<ExtensionKitProcess, LaunchError>&&)>&
        aCompletion) {
  auto callCompletion = [=](auto* aProcess, NSError* aError) {
    if (aProcess) {
      [aProcess retain];
      aCompletion(ExtensionKitProcess(aKind, aProcess));
    } else {
      NSLog(@"Error launching process, description '%@', reason '%@'",
            [aError localizedDescription], [aError localizedFailureReason]);
      aCompletion(Err(LaunchError("ExtensionKitProcess::StartProcess")));
    }
  };

  switch (aKind) {
    case Kind::WebContent: {
      [BEWebContentProcess
          webContentProcessWithInterruptionHandler:^{
          }
          completion:^(BEWebContentProcess* process, NSError* error) {
            callCompletion(process, error);
          }];
      return;
    }
    case Kind::Networking: {
      [BENetworkingProcess
          networkProcessWithInterruptionHandler:^{
          }
          completion:^(BENetworkingProcess* process, NSError* error) {
            callCompletion(process, error);
          }];
      return;
    }
    case Kind::Rendering: {
      [BERenderingProcess
          renderingProcessWithInterruptionHandler:^{
          }
          completion:^(BERenderingProcess* process, NSError* error) {
            callCompletion(process, error);
          }];
      return;
    }
  }
}

template <typename F>
static void SwitchObject(ExtensionKitProcess::Kind aKind, void* aProcessObject,
                         F&& aMatcher) {
  switch (aKind) {
    case ExtensionKitProcess::Kind::WebContent:
      aMatcher(static_cast<BEWebContentProcess*>(aProcessObject));
      break;
    case ExtensionKitProcess::Kind::Networking:
      aMatcher(static_cast<BENetworkingProcess*>(aProcessObject));
      break;
    case ExtensionKitProcess::Kind::Rendering:
      aMatcher(static_cast<BERenderingProcess*>(aProcessObject));
      break;
  }
}

DarwinObjectPtr<xpc_connection_t> ExtensionKitProcess::MakeLibXPCConnection() {
  NSError* error = nullptr;
  DarwinObjectPtr<xpc_connection_t> xpcConnection;
  SwitchObject(mKind, mProcessObject, [&](auto* aProcessObject) {
    xpcConnection = [aProcessObject makeLibXPCConnectionError:&error];
  });
  return xpcConnection;
}

void ExtensionKitProcess::Invalidate() {
  SwitchObject(mKind, mProcessObject,
               [&](auto* aProcessObject) { [aProcessObject invalidate]; });
}

UniqueBEProcessCapabilityGrant
ExtensionKitProcess::GrantForegroundCapability() {
  NSError* error = nullptr;
  BEProcessCapability* cap = [BEProcessCapability foreground];
  id<BEProcessCapabilityGrant> grant = nil;
  SwitchObject(mKind, mProcessObject, [&](auto* aProcessObject) {
    grant = [aProcessObject grantCapability:cap error:&error];
  });
  return UniqueBEProcessCapabilityGrant(grant ? [grant retain] : nil);
}

ExtensionKitProcess::ExtensionKitProcess(const ExtensionKitProcess& aOther)
    : mKind(aOther.mKind), mProcessObject(aOther.mProcessObject) {
  SwitchObject(mKind, mProcessObject,
               [&](auto* aProcessObject) { [aProcessObject retain]; });
}

ExtensionKitProcess& ExtensionKitProcess::operator=(
    const ExtensionKitProcess& aOther) {
  Kind oldKind = std::exchange(mKind, aOther.mKind);
  void* oldProcessObject = std::exchange(mProcessObject, aOther.mProcessObject);
  SwitchObject(mKind, mProcessObject,
               [&](auto* aProcessObject) { [aProcessObject retain]; });
  SwitchObject(oldKind, oldProcessObject,
               [&](auto* aProcessObject) { [aProcessObject release]; });
  return *this;
}

ExtensionKitProcess::~ExtensionKitProcess() {
  SwitchObject(mKind, mProcessObject,
               [&](auto* aProcessObject) { [aProcessObject release]; });
}

void LockdownExtensionKitProcess(ExtensionKitSandboxRevision aRevision) {
  if (id<GeckoProcessExtension> process = GetCurrentProcessExtension()) {
    switch (aRevision) {
      case ExtensionKitSandboxRevision::Revision1:
        [process lockdownSandbox:@"1.0"];
        return;
      default:
        NSLog(@"Unknown ExtensionKit sandbox revision");
        return;
    }
  }
}

}  // namespace mozilla::ipc