summaryrefslogtreecommitdiffhomepage
path: root/ios
diff options
context:
space:
mode:
authorAndrew Bulhak <andrew.bulhak@mullvad.net>2025-07-15 17:14:46 +0200
committerJon Petersson <jon.petersson@mullvad.net>2025-08-12 14:49:43 +0200
commit6210557bbb92934be1e0697a2129642ef95c5dd3 (patch)
treebbdd14a370c7d38b183d5f8e1901404ec4d32f2b /ios
parentcf0cb9934d732b045803c0affce291d11c6251fa (diff)
downloadmullvadvpn-6210557bbb92934be1e0697a2129642ef95c5dd3.tar.xz
mullvadvpn-6210557bbb92934be1e0697a2129642ef95c5dd3.zip
Feed access method UUID back from Rust to Swift, and save it
Diffstat (limited to 'ios')
-rw-r--r--ios/MullvadRustRuntime/MullvadApiContext.swift23
-rw-r--r--ios/MullvadRustRuntime/include/mullvad_rust_runtime.h15
-rw-r--r--ios/MullvadSettings/AccessMethodRepository.swift10
-rw-r--r--ios/MullvadSettings/MullvadAccessMethodChangeListening.swift12
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj4
-rw-r--r--ios/MullvadVPN/AppDelegate.swift1
6 files changed, 58 insertions, 7 deletions
diff --git a/ios/MullvadRustRuntime/MullvadApiContext.swift b/ios/MullvadRustRuntime/MullvadApiContext.swift
index 7600b79e70..1f1712c624 100644
--- a/ios/MullvadRustRuntime/MullvadApiContext.swift
+++ b/ios/MullvadRustRuntime/MullvadApiContext.swift
@@ -6,18 +6,28 @@
// Copyright © 2025 Mullvad VPN AB. All rights reserved.
//
+import MullvadSettings
import MullvadTypes
-public struct MullvadApiContext: @unchecked Sendable {
+func onAccessChangeCallback(selfPtr: UnsafeRawPointer?, bytes: UnsafePointer<UInt8>?) {
+ guard let selfPtr, let bytes else { return }
+ let context = selfPtr.assumingMemoryBound(to: MullvadApiContext.self).pointee
+
+ let uuid = NSUUID(uuidBytes: bytes) as UUID
+ context.accessMethodChangeListener?.accessMethodChangedTo(uuid)
+}
+
+public class MullvadApiContext: @unchecked Sendable {
enum Error: Swift.Error {
case failedToConstructApiClient
}
- public let context: SwiftApiContext
+ public private(set) var context: SwiftApiContext!
private let shadowsocksBridgeProvider: SwiftShadowsocksBridgeProviding!
private let shadowsocksBridgeProviderWrapper: SwiftShadowsocksLoaderWrapper!
private let addressCacheWrapper: SwiftAddressCacheWrapper!
private let addressCacheProvider: AddressCacheProviding!
+ public var accessMethodChangeListener: MullvadAccessMethodChangeListening?
public init(
host: String,
@@ -36,6 +46,7 @@ public struct MullvadApiContext: @unchecked Sendable {
self.addressCacheProvider = defaultAddressCache
self.addressCacheWrapper = iniSwiftAddressCacheWrapper(provider: defaultAddressCache)
+ context = nil
context = switch disableTls {
case true:
mullvad_api_init_new_tls_disabled(
@@ -44,7 +55,9 @@ public struct MullvadApiContext: @unchecked Sendable {
domain,
shadowsocksBridgeProviderWrapper,
accessMethodWrapper,
- addressCacheWrapper
+ addressCacheWrapper,
+ onAccessChangeCallback,
+ Unmanaged.passRetained(self).toOpaque()
)
case false:
mullvad_api_init_new(
@@ -53,7 +66,9 @@ public struct MullvadApiContext: @unchecked Sendable {
domain,
shadowsocksBridgeProviderWrapper,
accessMethodWrapper,
- addressCacheWrapper
+ addressCacheWrapper,
+ onAccessChangeCallback,
+ Unmanaged.passRetained(self).toOpaque()
)
}
diff --git a/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h b/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h
index 751e58aae0..36b49ea915 100644
--- a/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h
+++ b/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h
@@ -169,7 +169,10 @@ struct SwiftApiContext mullvad_api_init_new_tls_disabled(const char *host,
const char *domain,
struct SwiftShadowsocksLoaderWrapper bridge_provider,
struct SwiftAccessMethodSettingsWrapper settings_provider,
- struct SwiftAddressCacheWrapper address_cache);
+ struct SwiftAddressCacheWrapper address_cache,
+ void (*access_method_change_callback)(const void*,
+ const uint8_t*),
+ const void *access_method_change_context);
/**
* # Safety
@@ -190,7 +193,10 @@ struct SwiftApiContext mullvad_api_init_new(const char *host,
const char *domain,
struct SwiftShadowsocksLoaderWrapper bridge_provider,
struct SwiftAccessMethodSettingsWrapper settings_provider,
- struct SwiftAddressCacheWrapper address_cache);
+ struct SwiftAddressCacheWrapper address_cache,
+ void (*access_method_change_callback)(const void*,
+ const uint8_t*),
+ const void *access_method_change_context);
/**
* # Safety
@@ -212,7 +218,10 @@ struct SwiftApiContext mullvad_api_init_inner(const char *host,
bool disable_tls,
struct SwiftShadowsocksLoaderWrapper bridge_provider,
struct SwiftAccessMethodSettingsWrapper settings_provider,
- struct SwiftAddressCacheWrapper address_cache);
+ struct SwiftAddressCacheWrapper address_cache,
+ void (*access_method_change_callback)(const void*,
+ const uint8_t*),
+ const void *access_method_change_context);
/**
* Converts parameters into a `Box<AccessMethodSetting>` raw representation that
diff --git a/ios/MullvadSettings/AccessMethodRepository.swift b/ios/MullvadSettings/AccessMethodRepository.swift
index 72cfc0668e..32c7ba4e5c 100644
--- a/ios/MullvadSettings/AccessMethodRepository.swift
+++ b/ios/MullvadSettings/AccessMethodRepository.swift
@@ -175,3 +175,13 @@ public class AccessMethodRepository: AccessMethodRepositoryProtocol, @unchecked
SettingsParser(decoder: JSONDecoder(), encoder: JSONEncoder())
}
}
+
+extension AccessMethodRepository: MullvadAccessMethodChangeListening {
+ public func accessMethodChangedTo(_ uuid: UUID) {
+ guard let method = accessMethodsSubject.value.first(where: { $0.id == uuid }) else {
+ logger.warning("Change reported to method with unknown ID: \(uuid)")
+ return
+ }
+ save(method)
+ }
+}
diff --git a/ios/MullvadSettings/MullvadAccessMethodChangeListening.swift b/ios/MullvadSettings/MullvadAccessMethodChangeListening.swift
new file mode 100644
index 0000000000..679d5e66fb
--- /dev/null
+++ b/ios/MullvadSettings/MullvadAccessMethodChangeListening.swift
@@ -0,0 +1,12 @@
+//
+// MullvadAccessMethodChangeListening.swift
+// MullvadVPN
+//
+// Created by Andrew Bulhak on 2025-07-03.
+// Copyright © 2025 Mullvad VPN AB. All rights reserved.
+//
+
+// A protocol that listens for notifications of when the current access method has changed. It receives only the UUID of the new method.
+public protocol MullvadAccessMethodChangeListening: AnyObject {
+ func accessMethodChangedTo(_ uuid: UUID)
+}
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index dcc97b34e1..9cd08dd97d 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -53,6 +53,7 @@
4424CDD32CDBD4A6009D8C9F /* SingleChoiceList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4424CDD22CDBD4A6009D8C9F /* SingleChoiceList.swift */; };
447F3D8A2CDE1853006E3462 /* ShadowsocksObfuscationSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 447F3D882CDE1852006E3462 /* ShadowsocksObfuscationSettingsViewModel.swift */; };
447F3D8B2CDE1853006E3462 /* ShadowsocksObfuscationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 447F3D892CDE1853006E3462 /* ShadowsocksObfuscationSettingsView.swift */; };
+ 4483EC372E26A53D007E5473 /* MullvadAccessMethodChangeListening.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4483EC352E2693D5007E5473 /* MullvadAccessMethodChangeListening.swift */; };
449275422C3570CA000526DE /* ICMP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 449275412C3570CA000526DE /* ICMP.swift */; };
4495ECD12D0B170700A7358B /* UDPOverTCPObfuscationSettingsPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4495ECD02D0B16F700A7358B /* UDPOverTCPObfuscationSettingsPage.swift */; };
4495ECD52D131A4800A7358B /* ShadowsocksObfuscationSettingsPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4495ECD42D131A3E00A7358B /* ShadowsocksObfuscationSettingsPage.swift */; };
@@ -1648,6 +1649,7 @@
4424CDD22CDBD4A6009D8C9F /* SingleChoiceList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleChoiceList.swift; sourceTree = "<group>"; };
447F3D882CDE1852006E3462 /* ShadowsocksObfuscationSettingsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShadowsocksObfuscationSettingsViewModel.swift; sourceTree = "<group>"; };
447F3D892CDE1853006E3462 /* ShadowsocksObfuscationSettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShadowsocksObfuscationSettingsView.swift; sourceTree = "<group>"; };
+ 4483EC352E2693D5007E5473 /* MullvadAccessMethodChangeListening.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MullvadAccessMethodChangeListening.swift; sourceTree = "<group>"; };
449275412C3570CA000526DE /* ICMP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICMP.swift; sourceTree = "<group>"; };
449275432C3C3029000526DE /* TunnelPinger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelPinger.swift; sourceTree = "<group>"; };
4495ECD02D0B16F700A7358B /* UDPOverTCPObfuscationSettingsPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UDPOverTCPObfuscationSettingsPage.swift; sourceTree = "<group>"; };
@@ -3785,6 +3787,7 @@
06410DFD292CE18F00AFC18C /* KeychainSettingsStore.swift */,
068CE5732927B7A400A068BB /* Migration.swift */,
A9D96B192A8247C100A5C673 /* MigrationManager.swift */,
+ 4483EC352E2693D5007E5473 /* MullvadAccessMethodChangeListening.swift */,
58B2FDD52AA71D2A003EB5C6 /* MullvadSettings.h */,
F0E61CA92BF2911D000C4A95 /* MultihopSettings.swift */,
44DD7D2C2B74E44A0005F67F /* QuantumResistanceSettings.swift */,
@@ -6207,6 +6210,7 @@
A93181A12B727ED700E341D2 /* TunnelSettingsV4.swift in Sources */,
58FE25BF2AA72311003D1918 /* MigrationManager.swift in Sources */,
58B2FDEF2AA720C4003EB5C6 /* ApplicationTarget.swift in Sources */,
+ 4483EC372E26A53D007E5473 /* MullvadAccessMethodChangeListening.swift in Sources */,
A988DF272ADE86ED00D807EF /* WireGuardObfuscationSettings.swift in Sources */,
58B2FDDE2AA71D5C003EB5C6 /* Migration.swift in Sources */,
F05769BB2C6661EE00D9778B /* TunnelSettingsStrategy.swift in Sources */,
diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift
index 2590e2f1e7..dee24eaa89 100644
--- a/ios/MullvadVPN/AppDelegate.swift
+++ b/ios/MullvadVPN/AppDelegate.swift
@@ -118,6 +118,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
accessMethodsDataSource: accessMethodRepository.accessMethodsPublisher,
lastReachableDataSource: accessMethodRepository.lastReachableAccessMethodPublisher
)
+ apiContext.accessMethodChangeListener = accessMethodRepository
setUpProxies(containerURL: containerURL)
let backgroundTaskProvider = BackgroundTaskProvider(