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

Freemium PIR: Refactor Freemium PIR State to Remove Dependency on AccountManager #3197

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions DuckDuckGo/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {

dataBrokerProtectionSubscriptionEventHandler.registerForSubscriptionAccountManagerEvents()

let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp, accountManager: subscriptionManager.accountManager)
let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp)
let pirGatekeeper = DefaultDataBrokerProtectionFeatureGatekeeper(accountManager:
subscriptionManager.accountManager,
freemiumPIRUserStateManager: freemiumPIRUserStateManager)
Expand Down Expand Up @@ -429,7 +429,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {

NetworkProtectionAppEvents(featureGatekeeper: DefaultVPNFeatureGatekeeper(subscriptionManager: subscriptionManager)).applicationDidBecomeActive()

let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp, accountManager: subscriptionManager.accountManager)
let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp)
let pirGatekeeper = DefaultDataBrokerProtectionFeatureGatekeeper(accountManager:
subscriptionManager.accountManager,
freemiumPIRUserStateManager: freemiumPIRUserStateManager)
Expand Down
5 changes: 2 additions & 3 deletions DuckDuckGo/DBP/DataBrokerProtectionFeatureGatekeeper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ struct DefaultDataBrokerProtectionFeatureGatekeeper: DataBrokerProtectionFeature
/// - Returns: Bool indicating prerequisites are satisfied
func arePrerequisitesSatisfied() async -> Bool {

if freemiumPIRUserStateManager.isActiveUser { return true }
let isAuthenticated = accountManager.isUserAuthenticated
if !isAuthenticated && freemiumPIRUserStateManager.didOnboard { return true }

let entitlements = await accountManager.hasEntitlement(forProductName: .dataBrokerProtection,
cachePolicy: .reloadIgnoringLocalCacheData)
Expand All @@ -98,8 +99,6 @@ struct DefaultDataBrokerProtectionFeatureGatekeeper: DataBrokerProtectionFeature
hasEntitlements = false
}

let isAuthenticated = accountManager.accessToken != nil

firePrerequisitePixelsAndLogIfNecessary(hasEntitlements: hasEntitlements, isAuthenticatedResult: isAuthenticated)

return hasEntitlements && isAuthenticated
Expand Down
4 changes: 2 additions & 2 deletions DuckDuckGo/Freemium/FreemiumDebugMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ final class FreemiumDebugMenu: NSMenuItem {

@objc
func setFreemiumPIROnboardStateEnabled() {
DefaultFreemiumPIRUserStateManager(userDefaults: .dbp, accountManager: Application.appDelegate.subscriptionManager.accountManager).didOnboard = true
DefaultFreemiumPIRUserStateManager(userDefaults: .dbp).didOnboard = true
}

@objc
func setFreemiumPIROnboardStateDisabled() {
DefaultFreemiumPIRUserStateManager(userDefaults: .dbp, accountManager: Application.appDelegate.subscriptionManager.accountManager).didOnboard = false
DefaultFreemiumPIRUserStateManager(userDefaults: .dbp).didOnboard = false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ final class NavigationBarViewController: NSViewController {

@IBAction func optionsButtonAction(_ sender: NSButton) {
let internalUserDecider = NSApp.delegateTyped.internalUserDecider
let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp, accountManager: subscriptionManager.accountManager)
let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp)
let freemiumPIRFeature = DefaultFreemiumPIRFeature(subscriptionManager: subscriptionManager, accountManager: subscriptionManager.accountManager)
let menu = MoreOptionsMenu(tabCollectionViewModel: tabCollectionViewModel,
passwordManagerCoordinator: PasswordManagerCoordinator.shared,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ final class RemoteMessagingConfigMatcherProvider: RemoteMessagingConfigMatcherPr

let deprecatedRemoteMessageStorage = DefaultSurveyRemoteMessagingStorage.surveys()

let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp, accountManager: subscriptionManager.accountManager)
let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp)
let isCurrentFreemiumPIRUser = !subscriptionManager.accountManager.isUserAuthenticated && freemiumPIRUserStateManager.didOnboard

return RemoteMessagingConfigMatcher(
appAttributeMatcher: AppAttributeMatcher(statisticsStore: statisticsStore,
Expand All @@ -164,7 +165,7 @@ final class RemoteMessagingConfigMatcherProvider: RemoteMessagingConfigMatcherPr
hasCustomHomePage: startupPreferencesPersistor().launchToCustomHomePage,
isDuckPlayerOnboarded: duckPlayerPreferencesPersistor.youtubeOverlayAnyButtonPressed,
isDuckPlayerEnabled: duckPlayerPreferencesPersistor.duckPlayerModeBool != false,
isCurrentFreemiumPIRUser: freemiumPIRUserStateManager.isActiveUser,
isCurrentFreemiumPIRUser: isCurrentFreemiumPIRUser,
dismissedDeprecatedMacRemoteMessageIds: deprecatedRemoteMessageStorage.dismissedMessageIDs()
),
percentileStore: RemoteMessagingPercentileUserDefaultsStore(keyValueStore: UserDefaults.standard),
Expand Down
2 changes: 1 addition & 1 deletion DuckDuckGo/Tab/View/BrowserTabViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ final class BrowserTabViewController: NSViewController {
return homePageViewController ?? {
let subscriptionManager = Application.appDelegate.subscriptionManager
let freemiumPIRFeature = DefaultFreemiumPIRFeature(subscriptionManager: subscriptionManager, accountManager: subscriptionManager.accountManager)
let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp, accountManager: subscriptionManager.accountManager)
let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp)
let homePageViewController = HomePageViewController(tabCollectionViewModel: tabCollectionViewModel, bookmarkManager: bookmarkManager,
freemiumPIRFeature: freemiumPIRFeature,
freemiumPIRUserStateManager: freemiumPIRUserStateManager)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class DataBrokerProtectionAgentManagerProvider {
emailService: emailService,
captchaService: captchaService)

let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp, accountManager: accountManager)
let freemiumPIRUserStateManager = DefaultFreemiumPIRUserStateManager(userDefaults: .dbp)

let agentstopper = DefaultDataBrokerProtectionAgentStopper(dataManager: dataManager,
entitlementMonitor: DataBrokerProtectionEntitlementMonitor(),
Expand All @@ -100,6 +100,7 @@ public class DataBrokerProtectionAgentManagerProvider {
operationDependencies: operationDependencies,
pixelHandler: pixelHandler,
agentStopper: agentstopper,
authenticationManager: authenticationManager,
freemiumPIRUserStateManager: freemiumPIRUserStateManager)
}
}
Expand All @@ -114,6 +115,7 @@ public final class DataBrokerProtectionAgentManager {
private let operationDependencies: DataBrokerOperationDependencies
private let pixelHandler: EventMapping<DataBrokerProtectionPixels>
private let agentStopper: DataBrokerProtectionAgentStopper
private let authenticationManager: DataBrokerProtectionAuthenticationManaging
private let freemiumPIRUserStateManager: FreemiumPIRUserStateManager

// Used for debug functions only, so not injected
Expand All @@ -129,6 +131,7 @@ public final class DataBrokerProtectionAgentManager {
operationDependencies: DataBrokerOperationDependencies,
pixelHandler: EventMapping<DataBrokerProtectionPixels>,
agentStopper: DataBrokerProtectionAgentStopper,
authenticationManager: DataBrokerProtectionAuthenticationManaging,
freemiumPIRUserStateManager: FreemiumPIRUserStateManager
) {
self.userNotificationService = userNotificationService
Expand All @@ -139,6 +142,7 @@ public final class DataBrokerProtectionAgentManager {
self.operationDependencies = operationDependencies
self.pixelHandler = pixelHandler
self.agentStopper = agentStopper
self.authenticationManager = authenticationManager
self.freemiumPIRUserStateManager = freemiumPIRUserStateManager

self.activityScheduler.delegate = self
Expand Down Expand Up @@ -189,18 +193,18 @@ extension DataBrokerProtectionAgentManager {

private extension DataBrokerProtectionAgentManager {

/// Starts either Freemium (scan-only) or Subscription (scan and opt-out) scheduled operations
/// Starts either Subscription (scan and opt-out) or Freemium (scan-only) scheduled operations
/// - Parameters:
/// - showWebView: Whether to show the web view or not
/// - operationDependencies: Operation dependencies
/// - completion: Completion handler
func startFreemiumOrSubscriptionScheduledOperations(showWebView: Bool,
operationDependencies: DataBrokerOperationDependencies,
completion: ((DataBrokerProtectionAgentErrorCollection?) -> Void)?) {
if freemiumPIRUserStateManager.isActiveUser {
queueManager.startScheduledScanOperationsIfPermitted(showWebView: showWebView, operationDependencies: operationDependencies, completion: completion)
} else {
if authenticationManager.isUserAuthenticated {
queueManager.startScheduledAllOperationsIfPermitted(showWebView: showWebView, operationDependencies: operationDependencies, completion: completion)
} else {
queueManager.startScheduledScanOperationsIfPermitted(showWebView: showWebView, operationDependencies: operationDependencies, completion: completion)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ struct DefaultDataBrokerProtectionAgentStopper: DataBrokerProtectionAgentStopper
do {
let hasProfile = try dataManager.fetchProfile() != nil
let isAuthenticated = authenticationManager.isUserAuthenticated
let isFreemium = freemiumPIRUserStateManager.isActiveUser
let didOnboardToFreemium = freemiumPIRUserStateManager.didOnboard

if !hasProfile || (!isAuthenticated && !isFreemium) {
if !hasProfile || (!isAuthenticated && !didOnboardToFreemium) {
os_log("Prerequisites are invalid", log: .dataBrokerProtection)
stopAgent()
return
}

if !isAuthenticated && isFreemium {
if satisfiesFreemiumPrerequisites() {
os_log("User is Freemium", log: .dataBrokerProtection)
return
}
Expand All @@ -86,11 +86,18 @@ struct DefaultDataBrokerProtectionAgentStopper: DataBrokerProtectionAgentStopper
public func monitorEntitlementAndStopAgentIfEntitlementIsInvalidAndUserIsNotFreemium(interval: TimeInterval) {
entitlementMonitor.start(checkEntitlementFunction: authenticationManager.hasValidEntitlement,
interval: interval) { result in
guard !self.freemiumPIRUserStateManager.isActiveUser else { return }

if satisfiesFreemiumPrerequisites() { return }
stopAgentBasedOnEntitlementCheckResult(result)
}
}

private func satisfiesFreemiumPrerequisites() -> Bool {
let isAuthenticated = authenticationManager.isUserAuthenticated
let didOnboardToFreemium = freemiumPIRUserStateManager.didOnboard
return !isAuthenticated && didOnboardToFreemium
}

private func stopAgent() {
stopAction.stopAgent()
}
Expand Down
Loading
Loading