mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
refactor(apple): Use static reference for TunnelManager instance (#7555)
Since we need to react to state on this instance changing, we need an instance of TunnelManager to last the lifetime of the app process. Thus, it makes more sense to use the `.shared` public static pattern to maintain an instance of it we can use from anywhere instead of having to store it in various other classes.
This commit is contained in:
@@ -82,6 +82,8 @@ public enum TunnelMessage: Codable {
|
||||
}
|
||||
|
||||
public class TunnelManager {
|
||||
public static let shared = TunnelManager()
|
||||
|
||||
// Expose closures that someone else can use to respond to events
|
||||
// for this manager.
|
||||
var statusChangeHandler: ((NEVPNStatus) async -> Void)?
|
||||
@@ -109,10 +111,6 @@ public class TunnelManager {
|
||||
public static let bundleIdentifier: String = "\(Bundle.main.bundleIdentifier!).network-extension"
|
||||
private let bundleDescription = "Firezone"
|
||||
|
||||
init() {
|
||||
manager = nil
|
||||
}
|
||||
|
||||
// Initialize and save a new VPN profile in system Preferences
|
||||
func create() async throws -> Settings {
|
||||
let protocolConfiguration = NETunnelProviderProtocol()
|
||||
|
||||
@@ -28,7 +28,6 @@ public final class Store: ObservableObject {
|
||||
// we could periodically update it if we need to.
|
||||
@Published private(set) var decision: UNAuthorizationStatus
|
||||
|
||||
public let tunnelManager: TunnelManager
|
||||
private var sessionNotification: SessionNotification
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
private var resourcesTimer: Timer?
|
||||
@@ -38,7 +37,6 @@ public final class Store: ObservableObject {
|
||||
self.decision = .authorized
|
||||
self.settings = Settings.defaultValue
|
||||
|
||||
self.tunnelManager = TunnelManager()
|
||||
self.sessionNotification = SessionNotification()
|
||||
|
||||
initNotifications()
|
||||
@@ -46,7 +44,7 @@ public final class Store: ObservableObject {
|
||||
}
|
||||
|
||||
public func internetResourceEnabled() -> Bool {
|
||||
tunnelManager.internetResourceEnabled
|
||||
TunnelManager.shared.internetResourceEnabled
|
||||
}
|
||||
|
||||
private func initNotifications() {
|
||||
@@ -65,11 +63,11 @@ public final class Store: ObservableObject {
|
||||
}
|
||||
|
||||
private func initTunnelManager() {
|
||||
// Subscribe to status updates from the tunnelManager
|
||||
tunnelManager.statusChangeHandler = handleVPNStatusChange
|
||||
// Subscribe to status updates from the tunnel manager
|
||||
TunnelManager.shared.statusChangeHandler = handleVPNStatusChange
|
||||
|
||||
// Load our existing VPN profile and initialize our state
|
||||
tunnelManager.load() { loadedStatus, loadedSettings, loadedActorName in
|
||||
TunnelManager.shared.load() { loadedStatus, loadedSettings, loadedActorName in
|
||||
DispatchQueue.main.async {
|
||||
self.status = loadedStatus
|
||||
|
||||
@@ -98,7 +96,7 @@ public final class Store: ObservableObject {
|
||||
func createVPNProfile() {
|
||||
DispatchQueue.main.async {
|
||||
Task {
|
||||
self.settings = try await self.tunnelManager.create()
|
||||
self.settings = try await TunnelManager.shared.create()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,25 +112,25 @@ public final class Store: ObservableObject {
|
||||
return
|
||||
}
|
||||
|
||||
tunnelManager.start(token: token)
|
||||
TunnelManager.shared.start(token: token)
|
||||
}
|
||||
|
||||
func stop(clearToken: Bool = false) {
|
||||
guard [.connected, .connecting, .reasserting].contains(status)
|
||||
else { return }
|
||||
|
||||
tunnelManager.stop(clearToken: clearToken)
|
||||
TunnelManager.shared.stop(clearToken: clearToken)
|
||||
}
|
||||
|
||||
func signIn(authResponse: AuthResponse) async throws {
|
||||
// Save actorName
|
||||
DispatchQueue.main.async { self.actorName = authResponse.actorName }
|
||||
|
||||
try await tunnelManager.saveSettings(settings)
|
||||
try await tunnelManager.saveActorName(authResponse.actorName)
|
||||
try await TunnelManager.shared.saveSettings(settings)
|
||||
try await TunnelManager.shared.saveActorName(authResponse.actorName)
|
||||
|
||||
// Bring the tunnel up and send it a token to start
|
||||
tunnelManager.start(token: authResponse.token)
|
||||
TunnelManager.shared.start(token: authResponse.token)
|
||||
}
|
||||
|
||||
func signOut() async throws {
|
||||
@@ -145,11 +143,11 @@ public final class Store: ObservableObject {
|
||||
func beginUpdatingResources(callback: @escaping (ResourceList) -> Void) {
|
||||
Log.app.log("\(#function)")
|
||||
|
||||
tunnelManager.fetchResources(callback: callback)
|
||||
TunnelManager.shared.fetchResources(callback: callback)
|
||||
let intervalInSeconds: TimeInterval = 1
|
||||
let timer = Timer(timeInterval: intervalInSeconds, repeats: true) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
tunnelManager.fetchResources(callback: callback)
|
||||
TunnelManager.shared.fetchResources(callback: callback)
|
||||
}
|
||||
RunLoop.main.add(timer, forMode: .common)
|
||||
resourcesTimer = timer
|
||||
@@ -163,7 +161,7 @@ public final class Store: ObservableObject {
|
||||
func save(_ newSettings: Settings) async throws {
|
||||
Task {
|
||||
do {
|
||||
try await tunnelManager.saveSettings(newSettings)
|
||||
try await TunnelManager.shared.saveSettings(newSettings)
|
||||
DispatchQueue.main.async { self.settings = newSettings }
|
||||
} catch {
|
||||
Log.app.error("\(#function): \(error)")
|
||||
@@ -172,9 +170,9 @@ public final class Store: ObservableObject {
|
||||
}
|
||||
|
||||
func toggleInternetResource(enabled: Bool) {
|
||||
tunnelManager.toggleInternetResource(enabled: enabled)
|
||||
TunnelManager.shared.toggleInternetResource(enabled: enabled)
|
||||
var newSettings = settings
|
||||
newSettings.internetResourceEnabled = tunnelManager.internetResourceEnabled
|
||||
newSettings.internetResourceEnabled = TunnelManager.shared.internetResourceEnabled
|
||||
Task {
|
||||
try await save(newSettings)
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public final class SettingsViewModel: ObservableObject {
|
||||
|
||||
do {
|
||||
#if os(macOS)
|
||||
let providerLogFolderSize = try await store.tunnelManager.getLogFolderSize()
|
||||
let providerLogFolderSize = try await TunnelManager.shared.getLogFolderSize()
|
||||
let totalSize = logFolderSize + providerLogFolderSize
|
||||
#else
|
||||
let totalSize = logFolderSize
|
||||
@@ -105,7 +105,7 @@ public final class SettingsViewModel: ObservableObject {
|
||||
try Log.clear(in: SharedAccess.logFolderURL)
|
||||
|
||||
#if os(macOS)
|
||||
try await store.tunnelManager.clearLogs()
|
||||
try await TunnelManager.shared.clearLogs()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
|
||||
try await adapter.start()
|
||||
|
||||
// Tell the system the tunnel is up, moving the tunnelManager status to
|
||||
// Tell the system the tunnel is up, moving the tunnel manager status to
|
||||
// `connected`.
|
||||
completionHandler(nil)
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user