Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fire experiment pixels #3622

Merged
merged 8 commits into from
Dec 5, 2024
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
16 changes: 15 additions & 1 deletion DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1689,6 +1689,8 @@
562984712AC469E400AC20EB /* SyncPreferencesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5629846E2AC4610100AC20EB /* SyncPreferencesTests.swift */; };
56406D4B2C636A8900BF8FA2 /* SpecialPagesUserScriptExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56406D4A2C636A8900BF8FA2 /* SpecialPagesUserScriptExtension.swift */; };
56406D4C2C636A8900BF8FA2 /* SpecialPagesUserScriptExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56406D4A2C636A8900BF8FA2 /* SpecialPagesUserScriptExtension.swift */; };
5641734B2CFE168700F4B716 /* PixelExperimentKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5641734A2CFE168700F4B716 /* PixelExperimentKit */; };
5641734D2CFE169400F4B716 /* PixelExperimentKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5641734C2CFE169400F4B716 /* PixelExperimentKit */; };
56534DED29DF252C00121467 /* CapturingDefaultBrowserProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56534DEC29DF252C00121467 /* CapturingDefaultBrowserProvider.swift */; };
56534DEE29DF252C00121467 /* CapturingDefaultBrowserProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56534DEC29DF252C00121467 /* CapturingDefaultBrowserProvider.swift */; };
565E46E02B2725DD0013AC2A /* CriticalPathsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565E46DF2B2725DD0013AC2A /* CriticalPathsTests.swift */; };
Expand Down Expand Up @@ -5083,6 +5085,7 @@
567A23C52C7F75BB0010F66C /* SpecialErrorPages in Frameworks */,
372217822B33380700B8E9C2 /* TestUtils in Frameworks */,
3706FCAA293F65D500E42796 /* UserScript in Frameworks */,
5641734D2CFE169400F4B716 /* PixelExperimentKit in Frameworks */,
85E2BBD02B8F534A00DBEC7A /* History in Frameworks */,
4BF97AD52B43C43F00EB4240 /* NetworkProtection in Frameworks */,
560EB9372C78974C0080DBC8 /* Onboarding in Frameworks */,
Expand Down Expand Up @@ -5317,6 +5320,7 @@
CD3301242C8870DF009AA127 /* MaliciousSiteProtection in Frameworks */,
C18BF9CC2C73678500ED6B8A /* Freemium in Frameworks */,
F1DF95E32BD1807C0045E591 /* Crashes in Frameworks */,
5641734B2CFE168700F4B716 /* PixelExperimentKit in Frameworks */,
560EB9352C7897370080DBC8 /* Onboarding in Frameworks */,
85E2BBCE2B8F534000DBEC7A /* History in Frameworks */,
1EA7B8D32B7E078C000330A4 /* SubscriptionUI in Frameworks */,
Expand Down Expand Up @@ -10034,6 +10038,7 @@
CBECDB8D2CDBD62C005B8B87 /* PageRefreshMonitor */,
CBECDB8F2CDBD631005B8B87 /* BrokenSitePrompt */,
37DF37062CF38B9F005ED34B /* PrivacyStats */,
5641734C2CFE169400F4B716 /* PixelExperimentKit */,
);
productName = DuckDuckGo;
productReference = 3706FD05293F65D500E42796 /* DuckDuckGo App Store.app */;
Expand Down Expand Up @@ -10514,6 +10519,7 @@
CBECDB892CDBD616005B8B87 /* PageRefreshMonitor */,
CBECDB8B2CDBD61C005B8B87 /* BrokenSitePrompt */,
37DF37042CF38B96005ED34B /* PrivacyStats */,
5641734A2CFE168700F4B716 /* PixelExperimentKit */,
);
productName = DuckDuckGo;
productReference = AA585D7E248FD31100E9A3E2 /* DuckDuckGo.app */;
Expand Down Expand Up @@ -15365,7 +15371,7 @@
repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit";
requirement = {
kind = exactVersion;
version = 217.0.2;
version = 218.0.0;
};
};
9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = {
Expand Down Expand Up @@ -15820,6 +15826,14 @@
package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */;
productName = Onboarding;
};
5641734A2CFE168700F4B716 /* PixelExperimentKit */ = {
isa = XCSwiftPackageProductDependency;
productName = PixelExperimentKit;
};
5641734C2CFE169400F4B716 /* PixelExperimentKit */ = {
isa = XCSwiftPackageProductDependency;
productName = PixelExperimentKit;
};
567A23C02C7F71570010F66C /* SpecialErrorPages */ = {
isa = XCSwiftPackageProductDependency;
package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/duckduckgo/BrowserServicesKit",
"state" : {
"revision" : "f0755fbb3309c93c8490dc8bbdfb7e2e7613bef6",
"version" : "217.0.2"
"revision" : "e5d390c8559fbe7b1ca67fd3982c91bcc0437d60",
"version" : "218.0.0"
}
},
{
Expand Down Expand Up @@ -75,7 +75,7 @@
{
"identity" : "lottie-spm",
"kind" : "remoteSourceControl",
"location" : "https://github.com/airbnb/lottie-spm",
"location" : "https://github.com/airbnb/lottie-spm.git",
"state" : {
"revision" : "1d29eccc24cc8b75bff9f6804155112c0ffc9605",
"version" : "4.4.3"
Expand Down
4 changes: 3 additions & 1 deletion DuckDuckGo/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import MetricKit
import Networking
import Persistence
import PixelKit
import PixelExperimentKit
import ServiceManagement
import SyncDataProviders
import UserNotifications
Expand Down Expand Up @@ -282,7 +283,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
keyValueStore: UserDefaults.appConfiguration,
actionHandler: FeatureFlagOverridesPublishingHandler<FeatureFlag>()
),
experimentManager: ExperimentCohortsManager(store: ExperimentsDataStore()),
experimentManager: ExperimentCohortsManager(store: ExperimentsDataStore(), fireCohortAssigned: PixelKit.fireExperimentEnrollmentPixel(subfeatureID:experiment:)),
for: FeatureFlag.self
)

Expand Down Expand Up @@ -331,6 +332,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
#else
privacyStats = PrivacyStats(databaseProvider: PrivacyStatsDatabase())
#endif
PixelKit.configureExperimentKit(featureFlagger: featureFlagger, eventTracker: ExperimentEventTracker(store: UserDefaults.appConfiguration))
}

func applicationWillFinishLaunching(_ notification: Notification) {
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/HomePage/View/ContinueSetUpView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ extension HomePage.Views {
.onAppear {
if featureType == .dock {
PixelKit.fire(GeneralPixel.addToDockNewTabPageCardPresented,
frequency: .unique,
frequency: .uniqueByName,
includeAppVersionParameter: false)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ final class NetworkProtectionTunnelController: TunnelController, TunnelSessionPr

PixelKit.fire(
NetworkProtectionPixelEvent.networkProtectionNewUser,
frequency: .unique,
frequency: .uniqueByName,
includeAppVersionParameter: true) { [weak self] fired, error in
guard let self, error == nil, fired else { return }
self.defaults.vpnFirstEnabled = PixelKit.pixelLastFireDate(event: NetworkProtectionPixelEvent.networkProtectionNewUser)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extension HomePage.Models.ContinueSetUpModel: NewTabPageNextStepsCardsProviding
return
}
PixelKit.fire(GeneralPixel.addToDockNewTabPageCardPresented,
frequency: .unique,
frequency: .uniqueByName,
includeAppVersionParameter: false)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,35 +57,35 @@ final class OnboardingPixelReporter: OnboardingSearchSuggestionsPixelReporting,
}

func trackSiteSuggetionOptionTapped() {
fire(ContextualOnboardingPixel.siteSuggetionOptionTapped, .unique)
fire(ContextualOnboardingPixel.siteSuggetionOptionTapped, .uniqueByName)
}

func trackSearchSuggetionOptionTapped() {
fire(ContextualOnboardingPixel.searchSuggetionOptionTapped, .unique)
fire(ContextualOnboardingPixel.searchSuggetionOptionTapped, .uniqueByName)
}
}

extension OnboardingPixelReporter: OnboardingAddressBarReporting {
func trackPrivacyDashboardOpened() {
if onboardingStateProvider.state != .onboardingCompleted {
fire(ContextualOnboardingPixel.onboardingPrivacyDashboardOpened, .unique)
fire(ContextualOnboardingPixel.onboardingPrivacyDashboardOpened, .uniqueByName)
}
}

func trackAddressBarTypedIn() {
if onboardingStateProvider.state == .showTryASearch {
fire(ContextualOnboardingPixel.onboardingSearchCustom, .unique)
fire(ContextualOnboardingPixel.onboardingSearchCustom, .uniqueByName)
}
if onboardingStateProvider.state == .showTryASite {
fire(ContextualOnboardingPixel.onboardingVisitSiteCustom, .unique)
fire(ContextualOnboardingPixel.onboardingVisitSiteCustom, .uniqueByName)
}
}

func trackSiteVisited() {
let key = "onboarding.website-visited"
let siteVisited = userDefaults.bool(forKey: key)
if siteVisited {
fire(ContextualOnboardingPixel.secondSiteVisited, .unique)
fire(ContextualOnboardingPixel.secondSiteVisited, .uniqueByName)
} else {
userDefaults.set(true, forKey: key)
}
Expand All @@ -95,21 +95,21 @@ extension OnboardingPixelReporter: OnboardingAddressBarReporting {
extension OnboardingPixelReporter: OnboardingFireReporting {
func trackFireButtonPressed() {
if onboardingStateProvider.state != .onboardingCompleted {
fire(ContextualOnboardingPixel.onboardingFireButtonPressed, .unique)
fire(ContextualOnboardingPixel.onboardingFireButtonPressed, .uniqueByName)
}
}
}

extension OnboardingPixelReporter: OnboardingDialogsReporting {
func trackLastDialogShown() {
fire(ContextualOnboardingPixel.onboardingFinished, .unique)
fire(ContextualOnboardingPixel.onboardingFinished, .uniqueByName)
}

func trackFireButtonSkipped() {
fire(ContextualOnboardingPixel.onboardingFireButtonPromptSkipPressed, .unique)
fire(ContextualOnboardingPixel.onboardingFireButtonPromptSkipPressed, .uniqueByName)
}

func trackFireButtonTryIt() {
fire(ContextualOnboardingPixel.onboardingFireButtonTryItPressed, .unique)
fire(ContextualOnboardingPixel.onboardingFireButtonTryItPressed, .uniqueByName)
}
}
2 changes: 1 addition & 1 deletion DuckDuckGo/Preferences/View/PreferencesRootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ enum Preferences {
case .activateAddEmailClick:
PixelKit.fire(PrivacyProPixel.privacyProRestorePurchaseEmailStart, frequency: .legacyDailyAndCount)
case .postSubscriptionAddEmailClick:
PixelKit.fire(PrivacyProPixel.privacyProWelcomeAddDevice, frequency: .unique)
PixelKit.fire(PrivacyProPixel.privacyProWelcomeAddDevice, frequency: .uniqueByName)
case .restorePurchaseStoreClick:
PixelKit.fire(PrivacyProPixel.privacyProRestorePurchaseStoreStart, frequency: .legacyDailyAndCount)
case .addDeviceEnterEmail:
Expand Down
12 changes: 11 additions & 1 deletion DuckDuckGo/Statistics/ATB/StatisticsLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Foundation
import BrowserServicesKit
import Networking
import PixelKit
import PixelExperimentKit
import os.log

final class StatisticsLoader {
Expand All @@ -34,15 +35,21 @@ final class StatisticsLoader {
private let attributionPixelHandler: InstallationAttributionsPixelHandler
private let parser = AtbParser()
private var isAppRetentionRequestInProgress = false
private let fireSearchExperimentPixels: () -> Void
private let fireAppRetentionExperimentPixels: () -> Void

init(
statisticsStore: StatisticsStore = LocalStatisticsStore(),
emailManager: EmailManager = EmailManager(),
attributionPixelHandler: InstallationAttributionsPixelHandler = AppInstallationAttributionPixelHandler()
attributionPixelHandler: InstallationAttributionsPixelHandler = AppInstallationAttributionPixelHandler(),
fireAppRetentionExperimentPixels: @escaping () -> Void = PixelKit.fireAppRetentionExperimentPixels,
fireSearchExperimentPixels: @escaping () -> Void = PixelKit.fireSearchExperimentPixels
) {
self.statisticsStore = statisticsStore
self.emailManager = emailManager
self.attributionPixelHandler = attributionPixelHandler
self.fireSearchExperimentPixels = fireSearchExperimentPixels
self.fireAppRetentionExperimentPixels = fireAppRetentionExperimentPixels
}

func refreshRetentionAtb(isSearch: Bool, completion: @escaping Completion = {}) {
Expand All @@ -57,13 +64,16 @@ final class StatisticsLoader {
}
PixelExperiment.fireSerpPixel()
PixelExperiment.fireOnboardingSearchPerformed5to7Pixel()
self.fireSearchExperimentPixels()
if NSApp.runType == .normal {
self.fireDailyOsVersionCounterPixel()
}
self.fireDockPixel()
} else if !self.statisticsStore.isAppRetentionFiredToday {
self.refreshAppRetentionAtb(completion: completion)
self.fireAppRetentionExperimentPixels()
} else {
self.fireAppRetentionExperimentPixels()
completion()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ final class SubscriptionPagesUseSubscriptionFeature: Subfeature {
PixelKit.fire(PrivacyProPixel.privacyProPurchaseSuccess, frequency: .legacyDailyAndCount)
sendFreemiumSubscriptionPixelIfFreemiumActivated()
saveSubscriptionUpgradeTimestampIfFreemiumActivated()
PixelKit.fire(PrivacyProPixel.privacyProSubscriptionActivated, frequency: .unique)
PixelKit.fire(PrivacyProPixel.privacyProSubscriptionActivated, frequency: .uniqueByName)
subscriptionSuccessPixelHandler.fireSuccessfulSubscriptionAttributionPixel()
sendSubscriptionUpgradeFromFreemiumNotificationIfFreemiumActivated()
await pushPurchaseUpdate(originalMessage: message, purchaseUpdate: purchaseUpdate)
Expand Down Expand Up @@ -354,14 +354,14 @@ final class SubscriptionPagesUseSubscriptionFeature: Subfeature {

switch featureSelection.productFeature {
case .networkProtection:
PixelKit.fire(PrivacyProPixel.privacyProWelcomeVPN, frequency: .unique)
PixelKit.fire(PrivacyProPixel.privacyProWelcomeVPN, frequency: .uniqueByName)
notificationCenter.post(name: .ToggleNetworkProtectionInMainWindow, object: self, userInfo: nil)
case .dataBrokerProtection:
PixelKit.fire(PrivacyProPixel.privacyProWelcomePersonalInformationRemoval, frequency: .unique)
PixelKit.fire(PrivacyProPixel.privacyProWelcomePersonalInformationRemoval, frequency: .uniqueByName)
notificationCenter.post(name: .openPersonalInformationRemoval, object: self, userInfo: nil)
await uiHandler.showTab(with: .dataBrokerProtection)
case .identityTheftRestoration, .identityTheftRestorationGlobal:
PixelKit.fire(PrivacyProPixel.privacyProWelcomeIdentityRestoration, frequency: .unique)
PixelKit.fire(PrivacyProPixel.privacyProWelcomeIdentityRestoration, frequency: .uniqueByName)
let url = subscriptionManager.url(for: .identityTheftRestoration)
await uiHandler.showTab(with: .identityTheftRestoration(url))
case .unknown:
Expand Down Expand Up @@ -402,12 +402,12 @@ final class SubscriptionPagesUseSubscriptionFeature: Subfeature {
}

func subscriptionsAddEmailSuccess(params: Any, original: WKScriptMessage) async -> Encodable? {
PixelKit.fire(PrivacyProPixel.privacyProAddEmailSuccess, frequency: .unique)
PixelKit.fire(PrivacyProPixel.privacyProAddEmailSuccess, frequency: .uniqueByName)
return nil
}

func subscriptionsWelcomeFaqClicked(params: Any, original: WKScriptMessage) async -> Encodable? {
PixelKit.fire(PrivacyProPixel.privacyProWelcomeFAQClick, frequency: .unique)
PixelKit.fire(PrivacyProPixel.privacyProWelcomeFAQClick, frequency: .uniqueByName)
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion LocalPackages/DataBrokerProtection/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ let package = Package(
targets: ["DataBrokerProtection"])
],
dependencies: [
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "217.0.2"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "218.0.0"),
.package(path: "../SwiftUIExtensions"),
.package(path: "../AppKitExtensions"),
.package(path: "../XPCHelper"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ public class FreemiumDBPExperimentPixelHandler: EventMapping<FreemiumDBPExperime
super.init { event, _, params, _ in
switch event {
case .subscription:
PixelKit.fire(event, frequency: .unique, withAdditionalParameters: params)
PixelKit.fire(event, frequency: .uniqueByName, withAdditionalParameters: params)
default:
PixelKit.fire(event, frequency: .unique)
PixelKit.fire(event, frequency: .uniqueByName)
}

}
Expand Down
2 changes: 1 addition & 1 deletion LocalPackages/FeatureFlags/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ let package = Package(
targets: ["FeatureFlags"]),
],
dependencies: [
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "217.0.2"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "218.0.0"),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
Expand Down
2 changes: 1 addition & 1 deletion LocalPackages/NetworkProtectionMac/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ let package = Package(
.library(name: "VPNAppLauncher", targets: ["VPNAppLauncher"]),
],
dependencies: [
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "217.0.2"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "218.0.0"),
.package(url: "https://github.com/airbnb/lottie-spm", exact: "4.4.3"),
.package(path: "../AppLauncher"),
.package(path: "../UDSHelper"),
Expand Down
2 changes: 1 addition & 1 deletion LocalPackages/SubscriptionUI/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ let package = Package(
targets: ["SubscriptionUI"]),
],
dependencies: [
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "217.0.2"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "218.0.0"),
.package(path: "../SwiftUIExtensions"),
.package(path: "../FeatureFlags")
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ final class NetworkProtectionPixelEventTests: XCTestCase {
file: #filePath,
line: #line)
fire(NetworkProtectionPixelEvent.networkProtectionNewUser,
frequency: .unique,
frequency: .uniqueByName,
and: .expect(pixelName: "m_mac_netp_daily_active_u"),
file: #filePath,
line: #line)
Expand Down
Loading
Loading