Skip to content

Commit

Permalink
Adds documentation and improves some of the code by making proper use…
Browse files Browse the repository at this point in the history
… of injection
  • Loading branch information
diegoreymendez committed Feb 6, 2025
1 parent 9922c50 commit a6d0ad1
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ protocol ExcludedAppsModel {
}

final class DefaultExcludedAppsModel {
private let appInfoRetriever: AppInfoRetrieveing = AppInfoRetriever()
private let appInfoRetriever: AppInfoRetrieving = AppInfoRetriever()
let proxySettings = TransparentProxySettings(defaults: .netP)
private let pixelKit: PixelFiring?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,71 @@
import AppKit
import Foundation

public protocol AppInfoRetrieveing {
/// Protocol to provide a mechanism to query information about installed Applications.
///
public protocol AppInfoRetrieving {

/// Provides a structure featuring commonly-used app info.
/// Provides a structure featuring commonly-used app info given the Application's bundleID.
///
/// It's also possible to retrieve the individual information directly by calling other methods in this class.
/// - Parameters:
/// - bundleID: the bundleID of the target Application.
///
func getAppInfo(bundleID: String) -> AppInfo?

/// Provides a structure featuring commonly-used app info, given the Application's URL.
///
/// - Parameters:
/// - appURL: the URL where the target Application is installed.
///
func getAppInfo(appURL: URL) -> AppInfo?

/// Obtains the icon for a specified application.
///
/// - Parameters:
/// - bundleID: the bundleID of the target Application.
///
func getAppIcon(bundleID: String) -> NSImage?

/// Obtains the URL for a specified application.
///
/// - Parameters:
/// - bundleID: the bundleID of the target Application.
///
func getAppURL(bundleID: String) -> URL?

/// Obtains the visible name for a specified application.
///
/// - Parameters:
/// - bundleID: the bundleID of the target Application.
///
func getAppName(bundleID: String) -> String?

/// Obtains the bundleID for a specified application.
///
/// - Parameters:
/// - appURL: the URL where the target Application is installed.
///
func getBundleID(appURL: URL) -> String?

/// Obtains the bundleIDs for all Applications embedded within a speciried application.
///
/// - Parameters:
/// - bundleURL: the URL where the parent Application is installed.
///
func findEmbeddedBundleIDs(in bundleURL: URL) -> Set<String>
}

public class AppInfoRetriever: AppInfoRetrieveing {
/// Provides a mechanism to query information about installed Applications.
///
public class AppInfoRetriever: AppInfoRetrieving {

public init() {}

/// Provides a structure featuring commonly-used app info given the Application's bundleID.
///
/// - Parameters:
/// - bundleID: the bundleID of the target Application.
///
public func getAppInfo(bundleID: String) -> AppInfo? {
guard let appName = getAppName(bundleID: bundleID) else {
return nil
Expand All @@ -46,6 +93,11 @@ public class AppInfoRetriever: AppInfoRetrieveing {
return AppInfo(bundleID: bundleID, name: appName, icon: appIcon)
}

/// Provides a structure featuring commonly-used app info, given the Application's URL.
///
/// - Parameters:
/// - appURL: the URL where the target Application is installed.
///
public func getAppInfo(appURL: URL) -> AppInfo? {
guard let bundleID = getBundleID(appURL: appURL) else {
return nil
Expand All @@ -54,6 +106,11 @@ public class AppInfoRetriever: AppInfoRetrieveing {
return getAppInfo(bundleID: bundleID)
}

/// Obtains the icon for a specified application.
///
/// - Parameters:
/// - bundleID: the bundleID of the target Application.
///
public func getAppIcon(bundleID: String) -> NSImage? {
guard let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleID) else {
return nil
Expand All @@ -72,6 +129,11 @@ public class AppInfoRetriever: AppInfoRetrieveing {
return NSImage(contentsOf: iconURL)
}

/// Obtains the visible name for a specified application.
///
/// - Parameters:
/// - bundleID: the bundleID of the target Application.
///
public func getAppName(bundleID: String) -> String? {
if let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleID) {
// Try reading from Info.plist
Expand All @@ -86,10 +148,20 @@ public class AppInfoRetriever: AppInfoRetrieveing {
return nil
}

/// Obtains the URL for a specified application.
///
/// - Parameters:
/// - bundleID: the bundleID of the target Application.
///
public func getAppURL(bundleID: String) -> URL? {
NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleID)
}

/// Obtains the bundleID for a specified application.
///
/// - Parameters:
/// - appURL: the URL where the target Application is installed.
///
public func getBundleID(appURL: URL) -> String? {
let infoPlistURL = appURL.appendingPathComponent("Contents/Info.plist")
if let plist = NSDictionary(contentsOf: infoPlistURL),
Expand All @@ -101,6 +173,11 @@ public class AppInfoRetriever: AppInfoRetrieveing {

// MARK: - Embedded Bundle IDs

/// Obtains the bundleIDs for all Applications embedded within a speciried application.
///
/// - Parameters:
/// - bundleURL: the URL where the parent Application is installed.
///
public func findEmbeddedBundleIDs(in bundleURL: URL) -> Set<String> {
var bundleIDs: [String] = []
let fileManager = FileManager.default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,22 @@ import Combine
///
final class AppRoutingRulesManager {

private let appInfoRetriever: AppInfoRetrieving
private(set) var rules: VPNAppRoutingRules
private var cancellables = Set<AnyCancellable>()

init(settings: TransparentProxySettings) {
self.rules = Self.expandAppRoutingRules(settings.appRoutingRules)
init(settings: TransparentProxySettings,
appInfoRetriever: AppInfoRetrieving = AppInfoRetriever()) {

self.appInfoRetriever = appInfoRetriever
self.rules = Self.expandAppRoutingRules(settings.appRoutingRules, appInfoRetriever: appInfoRetriever)

subscribeToAppRoutingRulesChanges(settings)
}

static func expandAppRoutingRules(_ rules: VPNAppRoutingRules) -> VPNAppRoutingRules {
static func expandAppRoutingRules(_ rules: VPNAppRoutingRules,
appInfoRetriever: AppInfoRetrieving) -> VPNAppRoutingRules {

let appInfoRetriever = AppInfoRetriever()
var expandedRules = rules

for (bundleID, rule) in rules {
Expand All @@ -60,8 +64,8 @@ final class AppRoutingRulesManager {
private func subscribeToAppRoutingRulesChanges(_ settings: TransparentProxySettings) {
settings.appRoutingRulesPublisher
.receive(on: DispatchQueue.main)
.map { rules in
return Self.expandAppRoutingRules(rules)
.map { [appInfoRetriever] rules in
return Self.expandAppRoutingRules(rules, appInfoRetriever: appInfoRetriever)
}
.assign(to: \.rules, onWeaklyHeld: self)
.store(in: &cancellables)
Expand Down

0 comments on commit a6d0ad1

Please sign in to comment.