Skip to content
This repository was archived by the owner on Feb 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,8 @@
7B1E819E27C8874900FF0E60 /* ContentOverlayPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1E819B27C8874900FF0E60 /* ContentOverlayPopover.swift */; };
7B1E819F27C8874900FF0E60 /* ContentOverlay.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B1E819C27C8874900FF0E60 /* ContentOverlay.storyboard */; };
7B1E81A027C8874900FF0E60 /* ContentOverlayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */; };
7B2DDD0B2A93EA570039D884 /* NetworkProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDD0A2A93EA570039D884 /* NetworkProtectionAppEvents.swift */; };
7B2DDD0D2A93EB630039D884 /* NetworkProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDD0A2A93EA570039D884 /* NetworkProtectionAppEvents.swift */; };
7B2E52252A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2E52242A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift */; };
7B430EA12A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; };
7B430EA22A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; };
Expand Down Expand Up @@ -2586,6 +2588,7 @@
7B1E819B27C8874900FF0E60 /* ContentOverlayPopover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentOverlayPopover.swift; sourceTree = "<group>"; };
7B1E819C27C8874900FF0E60 /* ContentOverlay.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ContentOverlay.storyboard; sourceTree = "<group>"; };
7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentOverlayViewController.swift; sourceTree = "<group>"; };
7B2DDD0A2A93EA570039D884 /* NetworkProtectionAppEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionAppEvents.swift; sourceTree = "<group>"; };
7B2E52242A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionAgentNotificationsPresenter.swift; sourceTree = "<group>"; };
7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionSimulateFailureMenu.swift; sourceTree = "<group>"; };
7B4CE8DA26F02108009134B1 /* UI Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "UI Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -4004,6 +4007,7 @@
4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */,
4B4D606B2A0B29FA00BCD287 /* Invite */,
4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */,
7B2DDD0A2A93EA570039D884 /* NetworkProtectionAppEvents.swift */,
);
path = BothAppTargets;
sourceTree = "<group>";
Expand Down Expand Up @@ -7585,6 +7589,7 @@
3706FAD2293F65D500E42796 /* Atb.swift in Sources */,
3706FAD3293F65D500E42796 /* DownloadsViewController.swift in Sources */,
3706FAD4293F65D500E42796 /* DataExtension.swift in Sources */,
7B2DDD0D2A93EB630039D884 /* NetworkProtectionAppEvents.swift in Sources */,
3706FAD6293F65D500E42796 /* ConfigurationStore.swift in Sources */,
3706FAD7293F65D500E42796 /* Feedback.swift in Sources */,
3707C722294B5D2900682A9F /* WKWebViewExtension.swift in Sources */,
Expand Down Expand Up @@ -8604,6 +8609,7 @@
4B9292A426670D2A00AD2C21 /* PasteboardWriting.swift in Sources */,
4B92928D26670D1700AD2C21 /* BookmarkOutlineViewCell.swift in Sources */,
B604085C274B8FBA00680351 /* UnprotectedDomains.xcdatamodeld in Sources */,
7B2DDD0B2A93EA570039D884 /* NetworkProtectionAppEvents.swift in Sources */,
4BB88B5025B7BA2B006F6B06 /* TabInstrumentation.swift in Sources */,
4B59024326B35F7C00489384 /* BrowserImportViewController.swift in Sources */,
4B9292D72667124000AD2C21 /* NSPopUpButtonExtension.swift in Sources */,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 3 additions & 77 deletions DuckDuckGo/AppDelegate/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel
UserDefaultsWrapper<Any>.clearRemovedKeys()

#if NETWORK_PROTECTION
startupNetworkProtection()
if #available(macOS 11.4, *) {
NetworkProtectionAppEvents().applicationDidFinishLaunching()
}
#endif
}

Expand Down Expand Up @@ -311,82 +313,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate, FileDownloadManagerDel
}
}

// MARK: - Network Protection

#if NETWORK_PROTECTION
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wanted to remove all this logic from the app delegate, because it looks awful here.

I'm purposedly avoiding any changes to make the comparison of the old code and new code easy. We can do follow up PRs to make this better if we want.


private func startupNetworkProtection() {
guard #available(macOS 11.4, *) else { return }

let loginItemsManager = NetworkProtectionLoginItemsManager()
let networkProtectionFeatureVisibility = NetworkProtectionKeychainTokenStore()

guard networkProtectionFeatureVisibility.isFeatureActivated else {
loginItemsManager.disableLoginItems()
LocalPinningManager.shared.unpin(.networkProtection)
return
}

restartNetworkProtectionIfVersionChanged(using: loginItemsManager)
refreshNetworkProtectionServers()
}

@available(macOS 11.4, *)
private func restartNetworkProtectionIfVersionChanged(using loginItemsManager: NetworkProtectionLoginItemsManager) {
let currentVersion = AppVersion.shared.versionNumber
let versionStore = NetworkProtectionLastVersionRunStore()
defer {
versionStore.lastVersionRun = currentVersion
}

// should‘ve been run at least once with NetP enabled
guard let lastVersionRun = versionStore.lastVersionRun else {
os_log(.info, log: .networkProtection, "No last version found for the NetP login items, skipping update")
return
}

if lastVersionRun != currentVersion {
os_log(.info, log: .networkProtection, "App updated from %{public}s to %{public}s: updating login items", lastVersionRun, currentVersion)
restartNetworkProtectionTunnelAndMenu(using: loginItemsManager)
} else {
// If login items failed to launch (e.g. because of the App bundle rename), launch using NSWorkspace
loginItemsManager.ensureLoginItemsAreRunning(.ifLoginItemsAreEnabled, after: 1)
}
}

@available(macOS 11.4, *)
private func restartNetworkProtectionTunnelAndMenu(using loginItemsManager: NetworkProtectionLoginItemsManager) {
loginItemsManager.restartLoginItems()

Task {
let provider = NetworkProtectionTunnelController()

// Restart NetP SysEx on app update
if await provider.isConnected {
await provider.stop()
await provider.start()
}
}
}

/// Fetches a new list of Network Protection servers, and updates the existing set.
@available(macOS 11.4, *)
private func refreshNetworkProtectionServers() {
Task {
let serverCount: Int
do {
serverCount = try await NetworkProtectionDeviceManager.create().refreshServerList().count
} catch {
os_log("Failed to update Network Protection servers", log: .networkProtection, type: .error)
return
}

os_log("Successfully updated Network Protection servers; total server count = %{public}d", log: .networkProtection, serverCount)
}
}

#endif

private func subscribeToEmailProtectionStatusNotifications() {
NotificationCenter.default.addObserver(self,
selector: #selector(emailDidSignInNotification(_:)),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//
// NetworkProtectionAppEvents.swift
//
// Copyright © 2023 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Common
import Foundation

#if NETWORK_PROTECTION
import NetworkProtection

/// Implements the sequence of steps that Network Protection needs to execute when the App starts up.
///
@available(macOS 11.4, *)
final class NetworkProtectionAppEvents {

/// Call this method when the app finishes launching, to run the startup logic for NetP.
///
func applicationDidFinishLaunching() {
let loginItemsManager = NetworkProtectionLoginItemsManager()
let keychainStore = NetworkProtectionKeychainTokenStore()
Comment on lines +33 to +34
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we‘re doing this, could you move these dependencies to the instance init with default values provided?


guard keychainStore.isFeatureActivated else {
loginItemsManager.disableLoginItems()
LocalPinningManager.shared.unpin(.networkProtection)
return
}

restartNetworkProtectionIfVersionChanged(using: loginItemsManager)
refreshNetworkProtectionServers()
}

private func restartNetworkProtectionIfVersionChanged(using loginItemsManager: NetworkProtectionLoginItemsManager) {
let currentVersion = AppVersion.shared.versionNumber
let versionStore = NetworkProtectionLastVersionRunStore()
defer {
versionStore.lastVersionRun = currentVersion
}

// should‘ve been run at least once with NetP enabled
guard let lastVersionRun = versionStore.lastVersionRun else {
os_log(.info, log: .networkProtection, "No last version found for the NetP login items, skipping update")
return
}

if lastVersionRun != currentVersion {
os_log(.info, log: .networkProtection, "App updated from %{public}s to %{public}s: updating login items", lastVersionRun, currentVersion)
restartNetworkProtectionTunnelAndMenu(using: loginItemsManager)
} else {
// If login items failed to launch (e.g. because of the App bundle rename), launch using NSWorkspace
loginItemsManager.ensureLoginItemsAreRunning(.ifLoginItemsAreEnabled, after: 1)
}
}

private func restartNetworkProtectionTunnelAndMenu(using loginItemsManager: NetworkProtectionLoginItemsManager) {
loginItemsManager.restartLoginItems()

Task {
let provider = NetworkProtectionTunnelController()

// Restart NetP SysEx on app update
if await provider.isConnected {
await provider.stop()
await provider.start()
}
}
}

/// Fetches a new list of Network Protection servers, and updates the existing set.
///
private func refreshNetworkProtectionServers() {
Task {
let serverCount: Int
do {
serverCount = try await NetworkProtectionDeviceManager.create().refreshServerList().count
} catch {
os_log("Failed to update Network Protection servers", log: .networkProtection, type: .error)
return
}

os_log("Successfully updated Network Protection servers; total server count = %{public}d", log: .networkProtection, serverCount)
}
}
}

#endif