diff --git a/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+P3A.swift b/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+P3A.swift index 33a11300543..8f0f1008c69 100644 --- a/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+P3A.swift +++ b/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+P3A.swift @@ -14,6 +14,30 @@ import os.log extension BrowserViewController { + func recordDefaultBrowserLikelyhoodP3A(openedHTTPLink: Bool = false) { + let isInstalledInThePastWeek: Bool = { + guard let installDate = Preferences.DAU.installationDate.value else { + // Pref is removed after 14 days + return false + } + return Date.now.timeIntervalSince(installDate) <= 7.days + }() + enum Answer: Int, CaseIterable { + case notEnoughInfo = 0 + case no = 1 + case yes = 2 + } + let isLikelyDefault = DefaultBrowserHelper.isBraveLikelyDefaultBrowser() + let answer: Answer = { + if !openedHTTPLink, isInstalledInThePastWeek { + // Hasn't been at least 7 days + return .notEnoughInfo + } + return isLikelyDefault ? .yes : .no + }() + UmaHistogramEnumeration("Brave.IOS.IsLikelyDefault", sample: answer) + } + func maybeRecordInitialShieldsP3A() { if Preferences.Shields.initialP3AStateReported.value { return } defer { Preferences.Shields.initialP3AStateReported.value = true } diff --git a/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController.swift b/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController.swift index 3fe3a79d5dc..593b29935fa 100644 --- a/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController.swift +++ b/Sources/Brave/Frontend/Browser/BrowserViewController/BrowserViewController.swift @@ -575,6 +575,7 @@ public class BrowserViewController: UIViewController { recordGeneralBottomBarLocationP3A() PlaylistP3A.recordHistogram() recordAdsUsageType() + recordDefaultBrowserLikelyhoodP3A() // Revised Review Handling AppReviewManager.shared.handleAppReview(for: .revisedCrossPlatform, using: self) @@ -3156,6 +3157,9 @@ extension BrowserViewController { // in case an external url is triggered if case .url(let navigatedURL, _) = path { if navigatedURL?.isWebPage(includeDataURIs: false) == true { + Preferences.General.lastHTTPURLOpenedDate.value = .now + recordDefaultBrowserLikelyhoodP3A(openedHTTPLink: true) + Preferences.General.defaultBrowserCalloutDismissed.value = true Preferences.DefaultBrowserIntro.defaultBrowserNotificationScheduled.value = true diff --git a/Sources/Brave/Frontend/ClientPreferences.swift b/Sources/Brave/Frontend/ClientPreferences.swift index bf0970b379c..cb65167d439 100644 --- a/Sources/Brave/Frontend/ClientPreferences.swift +++ b/Sources/Brave/Frontend/ClientPreferences.swift @@ -84,6 +84,9 @@ extension Preferences { static var defaultPageZoomLevel = Option(key: "general.default-page-zoom-level", default: 1.0) static let isUsingBottomBar = Option(key: "general.bottom-bar", default: false) + + /// The last time the app opened and handed a http or https url + static let lastHTTPURLOpenedDate = Option(key: "general.last-url-opened-date", default: nil) } final public class Search { diff --git a/Sources/Brave/Helpers/DefaultBrowserHelper.swift b/Sources/Brave/Helpers/DefaultBrowserHelper.swift new file mode 100644 index 00000000000..1970702666f --- /dev/null +++ b/Sources/Brave/Helpers/DefaultBrowserHelper.swift @@ -0,0 +1,15 @@ +// Copyright 2024 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +import Foundation +import Preferences + +enum DefaultBrowserHelper { + /// Whether or not its likely that Brave is the users default browser based on a 14 day usage period + static func isBraveLikelyDefaultBrowser() -> Bool { + guard let date = Preferences.General.lastHTTPURLOpenedDate.value else { return false } + return date >= Date.now.addingTimeInterval(-14.days) + } +} diff --git a/Tests/ClientTests/DefaultBrowserHelperTests.swift b/Tests/ClientTests/DefaultBrowserHelperTests.swift new file mode 100644 index 00000000000..a658ef8c548 --- /dev/null +++ b/Tests/ClientTests/DefaultBrowserHelperTests.swift @@ -0,0 +1,42 @@ +// Copyright 2024 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +import Foundation +@testable import Brave +import XCTest +import Preferences + +class DefaultBrowserHelperTests: XCTestCase { + override func setUp() async throws { + Preferences.General.lastHTTPURLOpenedDate.reset() + } + + func testUserRecentlyOpenedURL() { + let date = Date() + Preferences.General.lastHTTPURLOpenedDate.value = date + let isLikelyDefault = DefaultBrowserHelper.isBraveLikelyDefaultBrowser() + XCTAssertTrue(isLikelyDefault) + } + + func testUserNeverOpenedURL() { + // User never opened a link + let isLikelyDefault = DefaultBrowserHelper.isBraveLikelyDefaultBrowser() + XCTAssertFalse(isLikelyDefault) + } + + func testUserOpenedURL8DaysAgo() { + let date = Date() + Preferences.General.lastHTTPURLOpenedDate.value = date.addingTimeInterval(-8.days) + let isLikelyDefault = DefaultBrowserHelper.isBraveLikelyDefaultBrowser() + XCTAssertTrue(isLikelyDefault) + } + + func testUserOpenedURL30DaysAgo() { + let date = Date() + Preferences.General.lastHTTPURLOpenedDate.value = date.addingTimeInterval(-30.days) + let isLikelyDefault = DefaultBrowserHelper.isBraveLikelyDefaultBrowser() + XCTAssertFalse(isLikelyDefault) + } +}