From 9823186de513d52f02fb190d947d518a5ae79b00 Mon Sep 17 00:00:00 2001 From: Sam Symons Date: Thu, 21 Dec 2023 09:47:43 -0800 Subject: [PATCH] Add PixelKit source parameter (#1989) Task/Issue URL: https://app.asana.com/0/0/1206203334750907/f Tech Design URL: CC: Description: This PR adds a source parameter to the PixelKit setUp function, to allow us to include which target is sending the pixel. --- .../MacPacketTunnelProvider.swift | 9 ++++++ ...kDuckGoDBPBackgroundAgentAppDelegate.swift | 1 + DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift | 7 +++- .../PixelKit/PixelKit+Parameters.swift | 1 + .../PixelKit/Sources/PixelKit/PixelKit.swift | 32 ++++++++++++++++--- 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift index 87c5614ecb..6bc1dfa909 100644 --- a/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift +++ b/DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift @@ -379,8 +379,17 @@ final class MacPacketTunnelProvider: PacketTunnelProvider { dryRun = false #endif + let source: String + +#if NETP_SYSTEM_EXTENSION + source = "vpnSystemExtension" +#else + source = "vpnAppExtension" +#endif + PixelKit.setUp(dryRun: dryRun, appVersion: AppVersion.shared.versionNumber, + source: source, defaultHeaders: defaultHeaders, log: .networkProtectionPixel, defaults: .netP) { (pixelName: String, headers: [String: String], parameters: [String: String], _, _, onComplete: @escaping PixelKit.CompletionBlock) in diff --git a/DuckDuckGoDBPBackgroundAgent/DuckDuckGoDBPBackgroundAgentAppDelegate.swift b/DuckDuckGoDBPBackgroundAgent/DuckDuckGoDBPBackgroundAgentAppDelegate.swift index f2ac32192a..9c8daa0d36 100644 --- a/DuckDuckGoDBPBackgroundAgent/DuckDuckGoDBPBackgroundAgentAppDelegate.swift +++ b/DuckDuckGoDBPBackgroundAgent/DuckDuckGoDBPBackgroundAgentAppDelegate.swift @@ -41,6 +41,7 @@ final class DuckDuckGoDBPBackgroundAgentApplication: NSApplication { PixelKit.setUp(dryRun: dryRun, appVersion: AppVersion.shared.versionNumber, + source: nil, defaultHeaders: [:], log: .dbpBackgroundAgentPixel, defaults: .standard) { (pixelName: String, headers: [String: String], parameters: [String: String], _, _, onComplete: @escaping (Bool, Error?) -> Void) in diff --git a/DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift b/DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift index bc3af58b03..71f37ea3ba 100644 --- a/DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift +++ b/DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift @@ -173,7 +173,12 @@ final class DuckDuckGoVPNAppDelegate: NSObject, NSApplicationDelegate { dryRun = false #endif - PixelKit.setUp(dryRun: dryRun, appVersion: AppVersion.shared.versionNumber, defaultHeaders: [:], log: .networkProtectionPixel, defaults: .netP) { (pixelName: String, headers: [String: String], parameters: [String: String], _, _, onComplete: @escaping PixelKit.CompletionBlock) in + PixelKit.setUp(dryRun: dryRun, + appVersion: AppVersion.shared.versionNumber, + source: "vpnAgent", + defaultHeaders: [:], + log: .networkProtectionPixel, + defaults: .netP) { (pixelName: String, headers: [String: String], parameters: [String: String], _, _, onComplete: @escaping PixelKit.CompletionBlock) in let url = URL.pixelUrl(forPixelNamed: pixelName) let apiHeaders = APIRequest.Headers(additionalHeaders: headers) // workaround - Pixel class should really handle APIRequest.Headers by itself diff --git a/LocalPackages/PixelKit/Sources/PixelKit/PixelKit+Parameters.swift b/LocalPackages/PixelKit/Sources/PixelKit/PixelKit+Parameters.swift index 9673f0dae0..70bf4aae8a 100644 --- a/LocalPackages/PixelKit/Sources/PixelKit/PixelKit+Parameters.swift +++ b/LocalPackages/PixelKit/Sources/PixelKit/PixelKit+Parameters.swift @@ -24,6 +24,7 @@ public extension PixelKit { public static let duration = "duration" public static let test = "test" public static let appVersion = "appVersion" + public static let pixelSource = "pixelSource" public static let osMajorVersion = "osMajorVersion" public static let errorCode = "e" diff --git a/LocalPackages/PixelKit/Sources/PixelKit/PixelKit.swift b/LocalPackages/PixelKit/Sources/PixelKit/PixelKit.swift index c8d165ad5f..b13aea7b17 100644 --- a/LocalPackages/PixelKit/Sources/PixelKit/PixelKit.swift +++ b/LocalPackages/PixelKit/Sources/PixelKit/PixelKit.swift @@ -87,10 +87,26 @@ public final class PixelKit { private let log: OSLog private let fireRequest: FireRequest - /// `dryRun`: if `true`, simulate requests and "send" them at an accelerated rate (once every 2 minutes instead of once a day) - /// `fireRequest`: this is not triggered when `dryRun` is `true` - public static func setUp(dryRun: Bool = false, appVersion: String, defaultHeaders: [String: String], log: OSLog, defaults: UserDefaults, fireRequest: @escaping FireRequest) { - shared = PixelKit(dryRun: dryRun, appVersion: appVersion, defaultHeaders: defaultHeaders, log: log, defaults: defaults, fireRequest: fireRequest) + /// Sets up PixelKit for the entire app. + /// + /// - Parameters: + /// - `dryRun`: if `true`, simulate requests and "send" them at an accelerated rate (once every 2 minutes instead of once a day) + /// - `source`: if set, adds a `pixelSource` parameter to the pixel call; this can be used to specify which target is sending the pixel + /// - `fireRequest`: this is not triggered when `dryRun` is `true` + public static func setUp(dryRun: Bool = false, + appVersion: String, + source: String? = nil, + defaultHeaders: [String: String], + log: OSLog, + defaults: UserDefaults, + fireRequest: @escaping FireRequest) { + shared = PixelKit(dryRun: dryRun, + appVersion: appVersion, + source: source, + defaultHeaders: defaultHeaders, + log: log, + defaults: defaults, + fireRequest: fireRequest) } static func tearDown() { @@ -98,10 +114,12 @@ public final class PixelKit { } private var dryRun: Bool + private let source: String? private let pixelCalendar: Calendar init(dryRun: Bool, appVersion: String, + source: String? = nil, defaultHeaders: [String: String], log: OSLog, dailyPixelCalendar: Calendar? = nil, @@ -111,6 +129,7 @@ public final class PixelKit { self.dryRun = dryRun self.appVersion = appVersion + self.source = source self.defaultHeaders = defaultHeaders self.log = log self.pixelCalendar = dailyPixelCalendar ?? Self.defaultDailyPixelCalendar @@ -119,6 +138,7 @@ public final class PixelKit { self.fireRequest = fireRequest } + // swiftlint:disable:next cyclomatic_complexity private func fire(pixelNamed pixelName: String, frequency: Frequency, withHeaders headers: [String: String]?, @@ -134,6 +154,10 @@ public final class PixelKit { newParams[Parameters.appVersion] = appVersion } + if let source { + newParams[Parameters.pixelSource] = source + } + if let error { newParams.appendErrorPixelParams(error: error) }