@@ -66,18 +66,8 @@ extension CoderVPNService: SystemExtensionAsyncRecorder {
66
66
}
67
67
68
68
func installSystemExtension( ) {
69
- logger. info ( " activating SystemExtension " )
70
- guard let bundleID = extensionBundle. bundleIdentifier else {
71
- logger. error ( " Bundle has no identifier " )
72
- return
73
- }
74
- let request = OSSystemExtensionRequest . activationRequest (
75
- forExtensionWithIdentifier: bundleID,
76
- queue: . main
77
- )
78
- request. delegate = systemExtnDelegate
79
- OSSystemExtensionManager . shared. submitRequest ( request)
80
- logger. info ( " submitted SystemExtension request with bundleID: \( bundleID) " )
69
+ systemExtnDelegate = SystemExtensionDelegate ( asyncDelegate: self )
70
+ systemExtnDelegate!. installSystemExtension ( )
81
71
}
82
72
}
83
73
@@ -91,14 +81,28 @@ class SystemExtensionDelegate<AsyncDelegate: SystemExtensionAsyncRecorder>:
91
81
// The `didFinishWithResult` function is called for both activation,
92
82
// deactivation, and replacement requests. The API provides no way to
93
83
// differentiate them. https://developer.apple.com/forums/thread/684021
94
- private var state : SystemExtensionDelegateState = . installing
84
+ // This tracks the last request type made, to handle them accordingly.
85
+ private var action : SystemExtensionDelegateAction = . none
95
86
96
87
init ( asyncDelegate: AsyncDelegate ) {
97
88
self . asyncDelegate = asyncDelegate
98
89
super. init ( )
99
90
logger. info ( " SystemExtensionDelegate initialized " )
100
91
}
101
92
93
+ func installSystemExtension( ) {
94
+ logger. info ( " activating SystemExtension " )
95
+ let bundleID = extensionBundle. bundleIdentifier!
96
+ let request = OSSystemExtensionRequest . activationRequest (
97
+ forExtensionWithIdentifier: bundleID,
98
+ queue: . main
99
+ )
100
+ request. delegate = self
101
+ action = . installing
102
+ OSSystemExtensionManager . shared. submitRequest ( request)
103
+ logger. info ( " submitted SystemExtension request with bundleID: \( bundleID) " )
104
+ }
105
+
102
106
func request(
103
107
_: OSSystemExtensionRequest ,
104
108
didFinishWithResult result: OSSystemExtensionRequest . Result
@@ -111,23 +115,24 @@ class SystemExtensionDelegate<AsyncDelegate: SystemExtensionAsyncRecorder>:
111
115
}
112
116
return
113
117
}
114
- switch state {
118
+ switch action {
115
119
case . installing:
116
120
logger. info ( " SystemExtension installed " )
117
121
Task { [ asyncDelegate] in
118
- await asyncDelegate. recordSystemExtensionState ( SystemExtensionState . installed)
122
+ await asyncDelegate. recordSystemExtensionState ( . installed)
119
123
}
124
+ action = . none
120
125
case . deleting:
121
126
logger. info ( " SystemExtension deleted " )
122
127
Task { [ asyncDelegate] in
123
- await asyncDelegate. recordSystemExtensionState ( SystemExtensionState . uninstalled)
128
+ await asyncDelegate. recordSystemExtensionState ( . uninstalled)
124
129
}
125
130
let request = OSSystemExtensionRequest . activationRequest (
126
131
forExtensionWithIdentifier: extensionBundle. bundleIdentifier!,
127
132
queue: . main
128
133
)
129
134
request. delegate = self
130
- state = . installing
135
+ action = . installing
131
136
OSSystemExtensionManager . shared. submitRequest ( request)
132
137
case . replacing:
133
138
logger. info ( " SystemExtension replaced " )
@@ -138,23 +143,26 @@ class SystemExtensionDelegate<AsyncDelegate: SystemExtensionAsyncRecorder>:
138
143
queue: . main
139
144
)
140
145
request. delegate = self
141
- state = . deleting
146
+ action = . deleting
142
147
OSSystemExtensionManager . shared. submitRequest ( request)
148
+ case . none:
149
+ logger. warning ( " Received an unexpected request result " )
150
+ break
143
151
}
144
152
}
145
153
146
154
func request( _: OSSystemExtensionRequest , didFailWithError error: Error ) {
147
155
logger. error ( " System extension request failed: \( error. localizedDescription) " )
148
156
Task { [ asyncDelegate] in
149
157
await asyncDelegate. recordSystemExtensionState (
150
- SystemExtensionState . failed ( error. localizedDescription) )
158
+ . failed( error. localizedDescription) )
151
159
}
152
160
}
153
161
154
162
func requestNeedsUserApproval( _ request: OSSystemExtensionRequest ) {
155
163
logger. error ( " Extension \( request. identifier) requires user approval " )
156
164
Task { [ asyncDelegate] in
157
- await asyncDelegate. recordSystemExtensionState ( SystemExtensionState . needsUserApproval)
165
+ await asyncDelegate. recordSystemExtensionState ( . needsUserApproval)
158
166
}
159
167
}
160
168
@@ -180,12 +188,13 @@ class SystemExtensionDelegate<AsyncDelegate: SystemExtensionAsyncRecorder>:
180
188
// There's no way to modify the deactivate request to use a different
181
189
// version string (i.e. `existing.bundleVersion`).
182
190
logger. info ( " App upgrade detected, replacing and then reinstalling " )
183
- state = . replacing
191
+ action = . replacing
184
192
return . replace
185
193
}
186
194
}
187
195
188
- enum SystemExtensionDelegateState {
196
+ enum SystemExtensionDelegateAction {
197
+ case none
189
198
case installing
190
199
case replacing
191
200
case deleting
0 commit comments