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

Autofill engagement KPIs for pixel reporting #2806

Merged
merged 16 commits into from
May 23, 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
2 changes: 1 addition & 1 deletion DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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" */ = {
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" : "65f3ccadd0118bcef112e3f5fff03e491b3261cd",
"version" : "146.1.0"
"revision" : "e1e436422bc167933baa0f90838958f2ac7119f3",
"version" : "146.2.0"
}
},
{
Expand Down
24 changes: 24 additions & 0 deletions DuckDuckGo/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -321,6 +322,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
#endif

setUpAutoClearHandler()

setUpAutofillPixelReporter()
}

func applicationDidBecomeActive(_ notification: Notification) {
Expand Down Expand Up @@ -587,6 +590,27 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
}
}
}

private func setUpAutofillPixelReporter() {
autofillPixelReporter = AutofillPixelReporter(
userDefaults: .standard,
eventMapping: EventMapping<AutofillPixelEvent> {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 {
Expand Down
5 changes: 5 additions & 0 deletions DuckDuckGo/Autofill/ContentOverlayViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/Menus/MainMenuActions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,9 @@ extension MainViewController {
try? vault?.deleteNoteFor(noteId: noteID)
}
UserDefaults.standard.set(false, forKey: UserDefaultsWrapper<Bool>.Key.homePageContinueSetUpImport.rawValue)

let autofillPixelReporter = AutofillPixelReporter(userDefaults: .standard, eventMapping: EventMapping<AutofillPixelEvent> { _, _, _, _ in }, installDate: nil)
autofillPixelReporter.resetStoreDefaults()
}

@objc func resetBookmarks(_ sender: Any?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
1 change: 1 addition & 0 deletions DuckDuckGo/Statistics/ATB/StatisticsLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
17 changes: 17 additions & 0 deletions DuckDuckGo/Statistics/GeneralPixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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"

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: "146.1.0"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "146.2.0"),
.package(path: "../SwiftUIExtensions"),
.package(path: "../XPCHelper"),
],
Expand Down
2 changes: 1 addition & 1 deletion LocalPackages/NetworkProtectionMac/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
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: "146.1.0"),
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "146.2.0"),
.package(path: "../SwiftUIExtensions")
],
targets: [
Expand Down
8 changes: 8 additions & 0 deletions UnitTests/DataExport/MockSecureVault.swift
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ final class MockSecureVault<T: AutofillDatabaseProvider>: AutofillSecureVault {
return storedCards
}

func creditCardsCount() throws -> Int {
return storedCards.count
}

func creditCardFor(id: Int64) throws -> SecureVaultModels.CreditCard? {
return storedCards.first { $0.id == id }
}
Expand Down Expand Up @@ -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]
}
Expand Down
Loading