diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index ca8c019e43..6143c3a653 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -13021,7 +13021,7 @@ repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 146.1.0; + version = 146.2.0; }; }; 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4a74ac2fd1..6dd57e77a0 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/BrowserServicesKit", "state" : { - "revision" : "65f3ccadd0118bcef112e3f5fff03e491b3261cd", - "version" : "146.1.0" + "revision" : "e1e436422bc167933baa0f90838958f2ac7119f3", + "version" : "146.2.0" } }, { diff --git a/DuckDuckGo/Application/AppDelegate.swift b/DuckDuckGo/Application/AppDelegate.swift index 2b734be8f9..4ef995e23e 100644 --- a/DuckDuckGo/Application/AppDelegate.swift +++ b/DuckDuckGo/Application/AppDelegate.swift @@ -76,6 +76,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate { let featureFlagger: FeatureFlagger private var appIconChanger: AppIconChanger! private var autoClearHandler: AutoClearHandler! + private(set) var autofillPixelReporter: AutofillPixelReporter? private(set) var syncDataProviders: SyncDataProviders! private(set) var syncService: DDGSyncing? @@ -321,6 +322,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate { #endif setUpAutoClearHandler() + + setUpAutofillPixelReporter() } func applicationDidBecomeActive(_ notification: Notification) { @@ -587,6 +590,27 @@ final class AppDelegate: NSObject, NSApplicationDelegate { } } } + + private func setUpAutofillPixelReporter() { + autofillPixelReporter = AutofillPixelReporter( + userDefaults: .standard, + eventMapping: EventMapping {event, _, params, _ in + switch event { + case .autofillActiveUser: + PixelKit.fire(GeneralPixel.autofillActiveUser) + case .autofillEnabledUser: + PixelKit.fire(GeneralPixel.autofillEnabledUser) + case .autofillOnboardedUser: + PixelKit.fire(GeneralPixel.autofillOnboardedUser) + case .autofillLoginsStacked: + PixelKit.fire(GeneralPixel.autofillLoginsStacked, withAdditionalParameters: params) + case .autofillCreditCardsStacked: + PixelKit.fire(GeneralPixel.autofillCreditCardsStacked, withAdditionalParameters: params) + } + }, + passwordManager: PasswordManagerCoordinator.shared, + installDate: AppDelegate.firstLaunchDate) + } } extension AppDelegate: UNUserNotificationCenterDelegate { diff --git a/DuckDuckGo/Autofill/ContentOverlayViewController.swift b/DuckDuckGo/Autofill/ContentOverlayViewController.swift index 5033f96ac5..12a087e0ad 100644 --- a/DuckDuckGo/Autofill/ContentOverlayViewController.swift +++ b/DuckDuckGo/Autofill/ContentOverlayViewController.swift @@ -296,6 +296,7 @@ extension ContentOverlayViewController: SecureVaultManagerDelegate { public func secureVaultManager(_: SecureVaultManager, didAutofill type: AutofillType, withObjectId objectId: String) { PixelKit.fire(GeneralPixel.formAutofilled(kind: type.formAutofillKind)) + NotificationCenter.default.post(name: .autofillFillEvent, object: nil) if type.formAutofillKind == .password && passwordManagerCoordinator.isEnabled { @@ -326,7 +327,11 @@ extension ContentOverlayViewController: SecureVaultManagerDelegate { self.emailManager.updateLastUseDate() PixelKit.fire(NonStandardEvent(GeneralPixel.jsPixel(pixel)), withAdditionalParameters: pixelParameters) + NotificationCenter.default.post(name: .autofillFillEvent, object: nil) } else { + if pixel.isIdentityPixel { + NotificationCenter.default.post(name: .autofillFillEvent, object: nil) + } PixelKit.fire(GeneralPixel.jsPixel(pixel), withAdditionalParameters: pixel.pixelParameters) } } diff --git a/DuckDuckGo/DataImport/Logins/SecureVault/SecureVaultLoginImporter.swift b/DuckDuckGo/DataImport/Logins/SecureVault/SecureVaultLoginImporter.swift index 193806cef0..eb3cdd03d9 100644 --- a/DuckDuckGo/DataImport/Logins/SecureVault/SecureVaultLoginImporter.swift +++ b/DuckDuckGo/DataImport/Logins/SecureVault/SecureVaultLoginImporter.swift @@ -60,6 +60,10 @@ final class SecureVaultLoginImporter: LoginImporter { } } + if successful.count > 0 { + NotificationCenter.default.post(name: .autofillSaveEvent, object: nil, userInfo: nil) + } + return .init(successful: successful.count, duplicate: duplicates.count, failed: failed.count) } diff --git a/DuckDuckGo/Menus/MainMenuActions.swift b/DuckDuckGo/Menus/MainMenuActions.swift index 103b90bc81..cef3e05a90 100644 --- a/DuckDuckGo/Menus/MainMenuActions.swift +++ b/DuckDuckGo/Menus/MainMenuActions.swift @@ -743,6 +743,9 @@ extension MainViewController { try? vault?.deleteNoteFor(noteId: noteID) } UserDefaults.standard.set(false, forKey: UserDefaultsWrapper.Key.homePageContinueSetUpImport.rawValue) + + let autofillPixelReporter = AutofillPixelReporter(userDefaults: .standard, eventMapping: EventMapping { _, _, _, _ in }, installDate: nil) + autofillPixelReporter.resetStoreDefaults() } @objc func resetBookmarks(_ sender: Any?) { diff --git a/DuckDuckGo/SecureVault/View/PasswordManagementViewController.swift b/DuckDuckGo/SecureVault/View/PasswordManagementViewController.swift index f18a2478de..bb8bd46046 100644 --- a/DuckDuckGo/SecureVault/View/PasswordManagementViewController.swift +++ b/DuckDuckGo/SecureVault/View/PasswordManagementViewController.swift @@ -539,6 +539,7 @@ final class PasswordManagementViewController: NSViewController { refetchWithText(searchField.stringValue) { [weak self] in self?.syncModelsOnCredentials(savedCredentials, select: true) } + NotificationCenter.default.post(name: .autofillSaveEvent, object: nil, userInfo: nil) } else { syncModelsOnCredentials(savedCredentials) } diff --git a/DuckDuckGo/SecureVault/View/SaveCredentialsViewController.swift b/DuckDuckGo/SecureVault/View/SaveCredentialsViewController.swift index e9f565bb9b..0d7bc4bc6d 100644 --- a/DuckDuckGo/SecureVault/View/SaveCredentialsViewController.swift +++ b/DuckDuckGo/SecureVault/View/SaveCredentialsViewController.swift @@ -241,6 +241,8 @@ final class SaveCredentialsViewController: NSViewController { PixelKit.fire(DebugEvent(GeneralPixel.secureVaultError(error: error))) } + NotificationCenter.default.post(name: .autofillSaveEvent, object: nil, userInfo: nil) + evaluateCredentialsAndFirePixels(for: .confirmed, credentials: existingCredentials) PixelKit.fire(GeneralPixel.autofillItemSaved(kind: .password)) diff --git a/DuckDuckGo/Statistics/ATB/StatisticsLoader.swift b/DuckDuckGo/Statistics/ATB/StatisticsLoader.swift index 19e7c70108..1d3cfb1be3 100644 --- a/DuckDuckGo/Statistics/ATB/StatisticsLoader.swift +++ b/DuckDuckGo/Statistics/ATB/StatisticsLoader.swift @@ -167,6 +167,7 @@ final class StatisticsLoader { if let data = response?.data, let atb = try? self.parser.convert(fromJsonData: data) { self.statisticsStore.searchRetentionAtb = atb.version self.storeUpdateVersionIfPresent(atb) + NotificationCenter.default.post(name: .searchDAU, object: nil, userInfo: nil) } completion() diff --git a/DuckDuckGo/Statistics/GeneralPixel.swift b/DuckDuckGo/Statistics/GeneralPixel.swift index fd7e8dafa3..6184263d85 100644 --- a/DuckDuckGo/Statistics/GeneralPixel.swift +++ b/DuckDuckGo/Statistics/GeneralPixel.swift @@ -61,6 +61,12 @@ enum GeneralPixel: PixelKitEventV2 { case autofillLoginsUpdateUsernameInlineConfirmed case autofillLoginsUpdateUsernameInlineDismissed + case autofillActiveUser + case autofillEnabledUser + case autofillOnboardedUser + case autofillLoginsStacked + case autofillCreditCardsStacked + case bitwardenPasswordAutofilled case bitwardenPasswordSaved @@ -414,6 +420,17 @@ enum GeneralPixel: PixelKitEventV2 { case .autofillLoginsUpdateUsernameInlineDismissed: return "m_mac_autofill_logins_update_username_inline_dismissed" + case .autofillActiveUser: + return "m_mac_autofill_activeuser" + case .autofillEnabledUser: + return "m_mac_autofill_enableduser" + case .autofillOnboardedUser: + return "m_mac_autofill_onboardeduser" + case .autofillLoginsStacked: + return "m_mac_autofill_logins_stacked" + case .autofillCreditCardsStacked: + return "m_mac_autofill_creditcards_stacked" + case .bitwardenPasswordAutofilled: return "m_mac_bitwarden_autofill_password" diff --git a/LocalPackages/DataBrokerProtection/Package.swift b/LocalPackages/DataBrokerProtection/Package.swift index 5c788ad63f..1fa39e2681 100644 --- a/LocalPackages/DataBrokerProtection/Package.swift +++ b/LocalPackages/DataBrokerProtection/Package.swift @@ -29,7 +29,7 @@ let package = Package( targets: ["DataBrokerProtection"]) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "146.1.0"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "146.2.0"), .package(path: "../SwiftUIExtensions"), .package(path: "../XPCHelper"), ], diff --git a/LocalPackages/NetworkProtectionMac/Package.swift b/LocalPackages/NetworkProtectionMac/Package.swift index 24722fef2b..041e3d6cd1 100644 --- a/LocalPackages/NetworkProtectionMac/Package.swift +++ b/LocalPackages/NetworkProtectionMac/Package.swift @@ -31,7 +31,7 @@ let package = Package( .library(name: "NetworkProtectionUI", targets: ["NetworkProtectionUI"]), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "146.1.0"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "146.2.0"), .package(url: "https://github.com/airbnb/lottie-spm", exact: "4.4.1"), .package(path: "../XPCHelper"), .package(path: "../SwiftUIExtensions"), diff --git a/LocalPackages/SubscriptionUI/Package.swift b/LocalPackages/SubscriptionUI/Package.swift index a33802799a..57655ffe08 100644 --- a/LocalPackages/SubscriptionUI/Package.swift +++ b/LocalPackages/SubscriptionUI/Package.swift @@ -12,7 +12,7 @@ let package = Package( targets: ["SubscriptionUI"]), ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "146.1.0"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "146.2.0"), .package(path: "../SwiftUIExtensions") ], targets: [ diff --git a/UnitTests/DataExport/MockSecureVault.swift b/UnitTests/DataExport/MockSecureVault.swift index 5f07ac42f2..97cacafde5 100644 --- a/UnitTests/DataExport/MockSecureVault.swift +++ b/UnitTests/DataExport/MockSecureVault.swift @@ -161,6 +161,10 @@ final class MockSecureVault: AutofillSecureVault { return storedCards } + func creditCardsCount() throws -> Int { + return storedCards.count + } + func creditCardFor(id: Int64) throws -> SecureVaultModels.CreditCard? { return storedCards.first { $0.id == id } } @@ -408,6 +412,10 @@ class MockDatabaseProvider: AutofillDatabaseProvider { return Array(_creditCards.values) } + func creditCardsCount() throws -> Int { + return _creditCards.count + } + func creditCardForCardId(_ cardId: Int64) throws -> SecureVaultModels.CreditCard? { return _creditCards[cardId] }