Skip to content

Commit

Permalink
Merge branch 'main' into sam/vpn-snooze-initial-support
Browse files Browse the repository at this point in the history
# By Mariusz Śpiewak (7) and others
# Via Diego Rey Mendez (1) and GitHub (1)
* main:
  Bump BSK to 181.1.0 (sets Privacy Dashboard to 5.0.0) (#3166)
  Animate transition between New Tab Page and tab switcher (#3196)
  Fix New Tab Page UI issues on iOS 15 (#3198)
  Push domain exclusions to internal release (#3195)
  Show shortcuts for enabled features only (#3193)
  Translate strings introduced in New Tab Page improvements (#3174)
  Update release workflow to use S3 bucket name from secrets (#3120)
  Handle contingency settings state on remote config (#3190)
  Add UI for displaying Duck Player contingency message #3065 (#3181)
  Open keyboard on New Tab Page based on Settings (#3187)
  Integrated macOS VPN Domain exclusion (internal release) changes into iOS. (#3164)
  Release 7.132.0-0 (#3194)
  Increase testPixelDebouncePreventsFiringWithinInterval test timeout (#3192)
  Update toolbar items for New Tab Page (#3185)
  new pixel and parameter for monitoring clearing of data stores (#3186)
  ensure new data clearing api is being used (#3191)
  If no App Store subscriptions option are available return empty options object (#3188)
  Show Intro message for existing users on New Tab Page (#3173)
  Experiment Contextual onboarding (#3160)

# Conflicts:
#	DuckDuckGo.xcodeproj/project.pbxproj
#	DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
  • Loading branch information
samsymons committed Aug 7, 2024
2 parents 6454939 + ad328f4 commit 12195f4
Show file tree
Hide file tree
Showing 177 changed files with 21,957 additions and 3,111 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ jobs:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }}
DSYM_S3_PATH: s3://${{ vars.DSYM_BUCKET_NAME }}/${{ vars.DSYM_BUCKET_PREFIX }}/
DSYM_S3_PATH: s3://${{ secrets.DSYM_BUCKET_NAME }}/${{ secrets.DSYM_BUCKET_PREFIX }}/
run: |
if [[ -f ${{ env.dsyms_path }} ]]; then
aws s3 cp "${{ env.dsyms_path }}" ${{ env.DSYM_S3_PATH }}
Expand Down
2 changes: 1 addition & 1 deletion Configuration/Version.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1 @@
MARKETING_VERSION = 7.131.0
MARKETING_VERSION = 7.132.0
4 changes: 2 additions & 2 deletions Core/AppPrivacyConfigurationDataProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import BrowserServicesKit
final public class AppPrivacyConfigurationDataProvider: EmbeddedDataProvider {

public struct Constants {
public static let embeddedDataETag = "\"fe3d3799b2bb2167720194f93ada4e43\""
public static let embeddedDataSHA = "4039eb5c4fcaa8806f0058b70c96e25db5d21c481e3ad607393726eb9cb0c361"
public static let embeddedDataETag = "\"c2739bfb56babbdfb6c1bfaf2446ab76\""
public static let embeddedDataSHA = "76782f36ca36d0eb14bd73944ab76f5fa718af4e099f5e6e00edcec5a7ee4a04"
}

public var embeddedDataEtag: String {
Expand Down
4 changes: 2 additions & 2 deletions Core/AppTrackerDataSetProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import BrowserServicesKit
final public class AppTrackerDataSetProvider: EmbeddedDataProvider {

public struct Constants {
public static let embeddedDataETag = "\"ea184137cdaa19ca5de76352215a9e0e\""
public static let embeddedDataSHA = "faa4dfbef4903710374b153c9a87e09b713fc19d64fa0bcfd1fd392fff93af21"
public static let embeddedDataETag = "\"077374b1c16cef9527d8bf11f59374a8\""
public static let embeddedDataSHA = "6a9794936a6f569cc7c442a3b03802e220a7b194d6ab07e0459feb456fba92a1"
}

public var embeddedDataEtag: String {
Expand Down
4 changes: 4 additions & 0 deletions Core/Pixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ public struct PixelParameters {

// Autofill
public static let countBucket = "count_bucket"

// Privacy Dashboard
public static let daysSinceInstall = "daysSinceInstall"
public static let fromOnboarding = "from_onboarding"
}

public struct PixelValues {
Expand Down
74 changes: 48 additions & 26 deletions Core/PixelEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ extension Pixel {
case forgetAllDataCleared

case privacyDashboardOpened

case privacyDashboardFirstTimeOpenedUnique

case dashboardProtectionAllowlistAdd
case dashboardProtectionAllowlistRemove

Expand Down Expand Up @@ -142,18 +143,27 @@ extension Pixel {
case onboardingIntroShownUnique
case onboardingIntroComparisonChartShownUnique
case onboardingIntroChooseBrowserCTAPressed

case daxDialogsSerp
case daxDialogsWithoutTrackers
case onboardingContextualSearchOptionTappedUnique
case onboardingContextualSearchCustomUnique
case onboardingContextualSiteOptionTappedUnique
case onboardingContextualSiteCustomUnique
case onboardingContextualSecondSiteVisitUnique
case onboardingContextualTrySearchUnique
case onboardingContextualTryVisitSiteUnique

case daxDialogsSerpUnique
case daxDialogsWithoutTrackersUnique
case daxDialogsWithoutTrackersFollowUp
case daxDialogsWithTrackers
case daxDialogsSiteIsMajor
case daxDialogsSiteOwnedByMajor
case daxDialogsHidden
case daxDialogsFireEducationShown
case daxDialogsFireEducationConfirmed
case daxDialogsFireEducationCancelled

case daxDialogsWithTrackersUnique
case daxDialogsSiteIsMajorUnique
case daxDialogsSiteOwnedByMajorUnique
case daxDialogsHiddenUnique
case daxDialogsFireEducationShownUnique
case daxDialogsFireEducationConfirmedUnique
case daxDialogsFireEducationCancelledUnique
case daxDialogsEndOfJourneyTabUnique
case daxDialogsEndOfJourneyNewTabUnique

case widgetsOnboardingCTAPressed
case widgetsOnboardingDeclineOptionPressed
case widgetsOnboardingMovedToBackground
Expand Down Expand Up @@ -525,7 +535,8 @@ extension Pixel {
case debugCannotClearObservationsDatabase
case debugWebsiteDataStoresNotClearedMultiple
case debugWebsiteDataStoresNotClearedOne

case debugWebsiteDataStoresCleared

case debugBookmarksMigratedMoreThanOnce

// Return user measurement
Expand Down Expand Up @@ -759,7 +770,8 @@ extension Pixel.Event {
case .forgetAllDataCleared: return "mf_dc"

case .privacyDashboardOpened: return "mp"

case .privacyDashboardFirstTimeOpenedUnique: return "m_privacy_dashboard_first_time_used_unique"

case .dashboardProtectionAllowlistAdd: return "mp_wla"
case .dashboardProtectionAllowlistRemove: return "mp_wlr"

Expand Down Expand Up @@ -865,18 +877,27 @@ extension Pixel.Event {
case .onboardingIntroShownUnique: return "m_preonboarding_intro_shown_unique"
case .onboardingIntroComparisonChartShownUnique: return "m_preonboarding_comparison_chart_shown_unique"
case .onboardingIntroChooseBrowserCTAPressed: return "m_preonboarding_choose_browser_pressed"

case .daxDialogsSerp: return "m_dx_s"
case .daxDialogsWithoutTrackers: return "m_dx_wo"
case .onboardingContextualSearchOptionTappedUnique: return "m_onboarding_search_option_tapped_unique"
case .onboardingContextualSiteOptionTappedUnique: return "m_onboarding_visit_site_option_tapped_unique"
case .onboardingContextualSecondSiteVisitUnique: return "m_second_sitevisit_unique"
case .onboardingContextualSearchCustomUnique: return "m_onboarding_search_custom_unique"
case .onboardingContextualSiteCustomUnique: return "m_onboarding_visit_site_custom_unique"
case .onboardingContextualTrySearchUnique: return "m_dx_try_a_search_unique"
case .onboardingContextualTryVisitSiteUnique: return "m_dx_try_visit_site_unique"

case .daxDialogsSerpUnique: return "m_dx_s_unique"
case .daxDialogsWithoutTrackersUnique: return "m_dx_wo_unique"
case .daxDialogsWithoutTrackersFollowUp: return "m_dx_wof"
case .daxDialogsWithTrackers: return "m_dx_wt"
case .daxDialogsSiteIsMajor: return "m_dx_sm"
case .daxDialogsSiteOwnedByMajor: return "m_dx_so"
case .daxDialogsHidden: return "m_dx_h"
case .daxDialogsFireEducationShown: return "m_dx_fe_s"
case .daxDialogsFireEducationConfirmed: return "m_dx_fe_co"
case .daxDialogsFireEducationCancelled: return "m_dx_fe_ca"

case .daxDialogsWithTrackersUnique: return "m_dx_wt_unique"
case .daxDialogsSiteIsMajorUnique: return "m_dx_sm_unique"
case .daxDialogsSiteOwnedByMajorUnique: return "m_dx_so_unique"
case .daxDialogsHiddenUnique: return "m_dx_h_unique"
case .daxDialogsFireEducationShownUnique: return "m_dx_fe_s_unique"
case .daxDialogsFireEducationConfirmedUnique: return "m_dx_fe_co_unique"
case .daxDialogsFireEducationCancelledUnique: return "m_dx_fe_ca_unique"
case .daxDialogsEndOfJourneyTabUnique: return "m_dx_end_tab_unique"
case .daxDialogsEndOfJourneyNewTabUnique: return "m_dx_end_new_tab_unique"

case .widgetsOnboardingCTAPressed: return "m_o_w_a"
case .widgetsOnboardingDeclineOptionPressed: return "m_o_w_d"
case .widgetsOnboardingMovedToBackground: return "m_o_w_b"
Expand Down Expand Up @@ -1223,7 +1244,8 @@ extension Pixel.Event {
case .debugCannotClearObservationsDatabase: return "m_d_cannot_clear_observations_database"
case .debugWebsiteDataStoresNotClearedMultiple: return "m_d_wkwebsitedatastoresnotcleared_multiple"
case .debugWebsiteDataStoresNotClearedOne: return "m_d_wkwebsitedatastoresnotcleared_one"

case .debugWebsiteDataStoresCleared: return "m_d_wkwebsitedatastorescleared"

// MARK: Ad Attribution

case .adAttributionGlobalAttributedRulesDoNotExist: return "m_attribution_global_attributed_rules_do_not_exist"
Expand Down
16 changes: 13 additions & 3 deletions Core/TimerInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,25 @@ public protocol TimerInterface: AnyObject {
extension Timer: TimerInterface {}

public protocol TimerCreating: AnyObject {
func makeTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping @Sendable (TimerInterface) -> Void) -> TimerInterface
func makeTimer(withTimeInterval interval: TimeInterval, repeats: Bool, on runLoop: RunLoop, block: @escaping @Sendable (TimerInterface) -> Void) -> TimerInterface
}

public extension TimerCreating {

func makeTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping @Sendable (TimerInterface) -> Void) -> TimerInterface {
makeTimer(withTimeInterval: interval, repeats: repeats, on: .main, block: block)
}

}

public final class TimerFactory: TimerCreating {

public init() {}

public func makeTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping @Sendable (TimerInterface) -> Void) -> TimerInterface {
Timer.scheduledTimer(withTimeInterval: interval, repeats: repeats, block: block)
public func makeTimer(withTimeInterval interval: TimeInterval, repeats: Bool, on runLoop: RunLoop, block: @escaping @Sendable (TimerInterface) -> Void) -> TimerInterface {
let timer = Timer(timeInterval: interval, repeats: repeats, block: block)
runLoop.add(timer, forMode: .common)
return timer
}

}
7 changes: 7 additions & 0 deletions Core/UserDefaultsPropertyWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ public struct UserDefaultsWrapper<T> {
case daxBrowsingMajorTrackingSiteShown = "com.duckduckgo.ios.daxOnboardingBrowsingMajorTrackingSiteShown"
case daxBrowsingOwnedByMajorTrackingSiteShown = "com.duckduckgo.ios.daxOnboardingBrowsingOwnedByMajorTrackingSiteShown"
case daxFireButtonEducationShownOrExpired = "com.duckduckgo.ios.daxfireButtonEducationShownOrExpired"
case daxFireMessageExperimentShown = "com.duckduckgo.ios.fireMessageShown"
case fireButtonPulseDateShown = "com.duckduckgo.ios.fireButtonPulseDateShown"
case privacyButtonPulseShown = "com.duckduckgo.ios.privacyButtonPulseShown"
case daxBrowsingFinalDialogShown = "com.duckduckgo.ios.daxOnboardingFinalDialogSeen"
case daxLastVisitedOnboardingWebsite = "com.duckduckgo.ios.daxOnboardingLastVisitedWebsite"
case daxLastShownContextualOnboardingDialogType = "com.duckduckgo.ios.daxLastShownContextualOnboardingDialogType"

case notFoundCache = "com.duckduckgo.ios.favicons.notFoundCache"
case faviconSizeNeedsMigration = "com.duckduckgo.ios.favicons.sizeNeedsMigration"
Expand Down Expand Up @@ -156,6 +161,8 @@ public struct UserDefaultsWrapper<T> {

case newTabPageSectionsSettings = "com.duckduckgo.ios.newTabPage.sections.settings"
case newTabPageShortcutsSettings = "com.duckduckgo.ios.newTabPage.shortcuts.settings"
case newTabPageIntroMessageEnabled = "com.duckduckgo.ios.newTabPage.introMessageEnabled"
case newTabPageIntroMessageSeenCount = "com.duckduckgo.ios.newTabPage.introMessageSeenCount"

// Debug keys

Expand Down
14 changes: 11 additions & 3 deletions Core/WKWebViewConfigurationExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,29 @@ extension WKWebViewConfiguration {

}

public class DataStoreIdManager {
public protocol DataStoreIdManaging {

var id: UUID? { get }
var hasId: Bool { get }
func allocateNewContainerId()

}

public class DataStoreIdManager: DataStoreIdManaging {

public static let shared = DataStoreIdManager()

@UserDefaultsWrapper(key: .webContainerId, defaultValue: nil)
private var containerId: String?

var id: UUID? {
public var id: UUID? {
if let containerId {
return UUID(uuidString: containerId)
}
return nil
}

var hasId: Bool {
public var hasId: Bool {
return containerId != nil
}

Expand Down
24 changes: 17 additions & 7 deletions Core/WebCacheManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public class WebCacheManager {

public func clear(cookieStorage: CookieStorage = CookieStorage(),
logins: PreserveLogins = PreserveLogins.shared,
dataStoreIdManager: DataStoreIdManager = .shared) async {
dataStoreIdManager: DataStoreIdManaging = DataStoreIdManager.shared) async {

var cookiesToUpdate = [HTTPCookie]()
if #available(iOS 17, *), dataStoreIdManager.hasId {
Expand All @@ -88,6 +88,10 @@ public class WebCacheManager {
// Perform legacy clearing to migrate to new container
cookiesToUpdate += await legacyDataClearing() ?? []

if #available(iOS 17, *) {
dataStoreIdManager.allocateNewContainerId()
}

cookieStorage.updateCookies(cookiesToUpdate, keepingPreservedLogins: logins)
}

Expand All @@ -96,29 +100,35 @@ public class WebCacheManager {
extension WebCacheManager {

@available(iOS 17, *)
private func checkForLeftBehindDataStores() async {
private func checkForLeftBehindDataStores(previousLeftOversCount: Int) async {
let params = [
"left_overs_count": "\(previousLeftOversCount)"
]

let ids = await WKWebsiteDataStore.allDataStoreIdentifiers
if ids.count > 1 {
Pixel.fire(pixel: .debugWebsiteDataStoresNotClearedMultiple)
Pixel.fire(pixel: .debugWebsiteDataStoresNotClearedMultiple, withAdditionalParameters: params)
} else if ids.count > 0 {
Pixel.fire(pixel: .debugWebsiteDataStoresNotClearedOne)
Pixel.fire(pixel: .debugWebsiteDataStoresNotClearedOne, withAdditionalParameters: params)
} else if previousLeftOversCount > 0 {
Pixel.fire(pixel: .debugWebsiteDataStoresCleared, withAdditionalParameters: params)
}
}

@available(iOS 17, *)
private func containerBasedClearing(storeIdManager: DataStoreIdManager) async -> [HTTPCookie]? {
private func containerBasedClearing(storeIdManager: DataStoreIdManaging) async -> [HTTPCookie]? {
guard let containerId = storeIdManager.id else { return [] }
var dataStore: WKWebsiteDataStore? = WKWebsiteDataStore(forIdentifier: containerId)
let cookies = await dataStore?.httpCookieStore.allCookies()
dataStore = nil

let uuids = await WKWebsiteDataStore.allDataStoreIdentifiers
let previousLeftOversCount = max(0, uuids.count - 1) // -1 because there should be a current store
for uuid in uuids {
try? await WKWebsiteDataStore.remove(forIdentifier: uuid)
}
await checkForLeftBehindDataStores()
await checkForLeftBehindDataStores(previousLeftOversCount: previousLeftOversCount)

storeIdManager.allocateNewContainerId()
return cookies
}

Expand Down
Loading

0 comments on commit 12195f4

Please sign in to comment.