Skip to content

Commit

Permalink
Add error pixels for Subscription keychain access errors (#3276)
Browse files Browse the repository at this point in the history
Task/Issue URL:
https://app.asana.com/0/1201037661562251/1208146974665104/f

**Description**:
Add missing pixel reporting for subscription related keychain access
errors.
  • Loading branch information
miasma13 authored Aug 28, 2024
1 parent fc0ea9b commit aeb6f67
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 9 deletions.
5 changes: 5 additions & 0 deletions Core/Pixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public struct PixelParameters {
public static let tabControllerCacheCount = "tab_controller_cache_count"

public static let count = "count"
public static let source = "source"

public static let textSizeInitial = "text_size_initial"
public static let textSizeUpdated = "text_size_updated"
Expand Down Expand Up @@ -147,6 +148,10 @@ public struct PixelParameters {
// Privacy Dashboard
public static let daysSinceInstall = "daysSinceInstall"
public static let fromOnboarding = "from_onboarding"

// Subscription
public static let privacyProKeychainAccessType = "access_type"
public static let privacyProKeychainError = "error"
}

public struct PixelValues {
Expand Down
2 changes: 2 additions & 0 deletions Core/PixelEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ extension Pixel {
case privacyProSubscriptionManagementRemoval
case privacyProTransactionProgressNotHiddenAfter60s
case privacyProSuccessfulSubscriptionAttribution
case privacyProKeychainAccessError

// MARK: Pixel Experiment
case pixelExperimentEnrollment
Expand Down Expand Up @@ -1460,6 +1461,7 @@ extension Pixel.Event {
case .privacyProSubscriptionManagementRemoval: return "m_privacy-pro_settings_remove-from-device_click"
case .privacyProTransactionProgressNotHiddenAfter60s: return "m_privacy-pro_progress_not_hidden_after_60s"
case .privacyProSuccessfulSubscriptionAttribution: return "m_subscribe"
case .privacyProKeychainAccessError: return "m_privacy-pro_keychain_access_error"

// MARK: Pixel Experiment
case .pixelExperimentEnrollment: return "pixel_experiment_enrollment"
Expand Down
6 changes: 5 additions & 1 deletion DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
1E4F4A5A297193DE00625985 /* MainViewController+CookiesManaged.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4F4A59297193DE00625985 /* MainViewController+CookiesManaged.swift */; };
1E4FAA6427D8DFB900ADC5B3 /* OngoingDownloadRowViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4FAA6327D8DFB900ADC5B3 /* OngoingDownloadRowViewModel.swift */; };
1E4FAA6627D8DFC800ADC5B3 /* CompleteDownloadRowViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E4FAA6527D8DFC800ADC5B3 /* CompleteDownloadRowViewModel.swift */; };
1E53508F2C7C9A1F00818DAA /* DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E53508E2C7C9A1F00818DAA /* DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift */; };
1E60989B290009C700A508F9 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 1E7060BD28F88EE200E4CCDB /* Common */; };
1E60989D290011E600A508F9 /* ContentBlocking in Frameworks */ = {isa = PBXBuildFile; productRef = 1E60989C290011E600A508F9 /* ContentBlocking */; };
1E6098A1290011E600A508F9 /* UserScript in Frameworks */ = {isa = PBXBuildFile; productRef = 1E6098A0290011E600A508F9 /* UserScript */; };
Expand Down Expand Up @@ -1312,6 +1313,7 @@
1E4F4A59297193DE00625985 /* MainViewController+CookiesManaged.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainViewController+CookiesManaged.swift"; sourceTree = "<group>"; };
1E4FAA6327D8DFB900ADC5B3 /* OngoingDownloadRowViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OngoingDownloadRowViewModel.swift; sourceTree = "<group>"; };
1E4FAA6527D8DFC800ADC5B3 /* CompleteDownloadRowViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompleteDownloadRowViewModel.swift; sourceTree = "<group>"; };
1E53508E2C7C9A1F00818DAA /* DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift"; sourceTree = "<group>"; };
1E61BC2927074BED00B2854D /* TextSizeUserScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextSizeUserScript.swift; sourceTree = "<group>"; };
1E6A4D682984208800A371D3 /* LocaleExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocaleExtension.swift; sourceTree = "<group>"; };
1E7A71162934EB6400B7EA19 /* OmniBarNotificationAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OmniBarNotificationAnimator.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -5079,6 +5081,7 @@
BDE91CD42C6292BF0005CB74 /* Feedback */,
F1FDC92F2BF4E0B3006B1435 /* SubscriptionEnvironment+Default.swift */,
D60170BB2BA32DD6001911B5 /* Subscription.swift */,
1E53508E2C7C9A1F00818DAA /* DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift */,
D6D95CE42B6DA3F200960317 /* AsyncHeadlessWebview */,
D664C7952B289AA000CBFA76 /* Subscription.storekit */,
D664C7932B289AA000CBFA76 /* ViewModel */,
Expand Down Expand Up @@ -7457,6 +7460,7 @@
B6CB93E5286445AB0090FEB4 /* Base64DownloadSession.swift in Sources */,
1EEF387D285B1A1100383393 /* TrackerImageCache.swift in Sources */,
3151F0EC27357FEE00226F58 /* VoiceSearchFeedbackViewModel.swift in Sources */,
1E53508F2C7C9A1F00818DAA /* DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift in Sources */,
1DDF402D2BA09482006850D9 /* SettingsMainSettingsView.swift in Sources */,
85010502292FB1000033978F /* FireproofFaviconUpdater.swift in Sources */,
F1C4A70E1E57725800A6CA1B /* OmniBar.swift in Sources */,
Expand Down Expand Up @@ -10627,7 +10631,7 @@
repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit";
requirement = {
kind = exactVersion;
version = 188.0.0;
version = 188.1.0;
};
};
9F8FE9472BAE50E50071E372 /* 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" : "faf25f57d1d61ff855216178c454616031585c07",
"version" : "188.0.0"
"revision" : "ce1b7228a38d2b18525590256051a012109cfee6",
"version" : "188.1.0"
}
},
{
Expand Down Expand Up @@ -138,7 +138,7 @@
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser",
"location" : "https://github.com/apple/swift-argument-parser.git",
"state" : {
"revision" : "0fbc8848e389af3bb55c182bc19ca9d5dc2f255b",
"version" : "1.4.0"
Expand Down
13 changes: 8 additions & 5 deletions DuckDuckGo/AppDependencyProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,14 @@ class AppDependencyProvider: DependencyProvider {
subscriptionEndpointService: subscriptionService,
authEndpointService: authService)

subscriptionManager = DefaultSubscriptionManager(storePurchaseManager: DefaultStorePurchaseManager(),
accountManager: accountManager,
subscriptionEndpointService: subscriptionService,
authEndpointService: authService,
subscriptionEnvironment: subscriptionEnvironment)
let subscriptionManager = DefaultSubscriptionManager(storePurchaseManager: DefaultStorePurchaseManager(),
accountManager: accountManager,
subscriptionEndpointService: subscriptionService,
authEndpointService: authService,
subscriptionEnvironment: subscriptionEnvironment)
accountManager.delegate = subscriptionManager

self.subscriptionManager = subscriptionManager

let subscriptionFeatureAvailability: SubscriptionFeatureAvailability = DefaultSubscriptionFeatureAvailability(
privacyConfigurationManager: ContentBlocking.shared.privacyConfigurationManager,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// DefaultSubscriptionManager+AccountManagerKeychainAccessDelegate.swift
// DuckDuckGo
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation
import Core
import Subscription

extension DefaultSubscriptionManager: AccountManagerKeychainAccessDelegate {

public func accountManagerKeychainAccessFailed(accessType: AccountKeychainAccessType, error: AccountKeychainAccessError) {
let parameters = [
PixelParameters.privacyProKeychainAccessType: accessType.rawValue,
PixelParameters.privacyProKeychainError: error.errorDescription,
PixelParameters.source: "browser"
]

DailyPixel.fireDailyAndCount(pixel: .privacyProKeychainAccessError,
withAdditionalParameters: parameters)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,8 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider {
defaults: .networkProtectionGroupDefaults,
isSubscriptionEnabled: true,
entitlementCheck: { return await Self.entitlementCheck(accountManager: accountManager) })

accountManager.delegate = self
startMonitoringMemoryPressureEvents()
observeServerChanges()
APIRequest.Headers.setUserAgent(DefaultUserAgentManager.duckDuckGoUserAgent)
Expand Down Expand Up @@ -476,3 +478,17 @@ final class DefaultWireGuardInterface: WireGuardInterface {
wgSetLogger(context, logFunction)
}
}

extension NetworkProtectionPacketTunnelProvider: AccountManagerKeychainAccessDelegate {

public func accountManagerKeychainAccessFailed(accessType: AccountKeychainAccessType, error: AccountKeychainAccessError) {
let parameters = [
PixelParameters.privacyProKeychainAccessType: accessType.rawValue,
PixelParameters.privacyProKeychainError: error.errorDescription,
PixelParameters.source: "vpn"
]

DailyPixel.fireDailyAndCount(pixel: .privacyProKeychainAccessError,
withAdditionalParameters: parameters)
}
}

0 comments on commit aeb6f67

Please sign in to comment.