Skip to content

Commit

Permalink
Merge branch 'release/7.87.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
afterxleep committed Aug 28, 2023
2 parents fa51486 + 8512ab1 commit 66ada8d
Show file tree
Hide file tree
Showing 83 changed files with 2,959 additions and 237 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ on:
push:
branches: [ develop, "release/**" ]
pull_request:
branches: [ develop, "release/**" ]


jobs:
swiftlint:
Expand Down
28 changes: 28 additions & 0 deletions Configuration/Configuration-Alpha.xcconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// Configuration-Alpha.xcconfig
// DuckDuckGo
//
// Copyright © 2023 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.
//

#include "DuckDuckGoDeveloper.xcconfig"
#include? "ExternalDeveloper.xcconfig"
#include? "Version.xcconfig"

// The app bundle identifier
APP_ID = com.duckduckgo.mobile.ios.alpha

// A prefix for group ids. Must start with "group.".
GROUP_ID_PREFIX = group.com.duckduckgo.alpha
2 changes: 1 addition & 1 deletion Configuration/Version.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1 @@
MARKETING_VERSION = 7.86.0
MARKETING_VERSION = 7.87.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 = "\"2308844373650298899d98be1f5e6766\""
public static let embeddedDataSHA = "160ffa9156640742a4be26a644354940ad0f3ea42e98e3cbfbe26e8d7a5c653a"
public static let embeddedDataETag = "\"c5c151e11d18bd98195388b7f8ce1911\""
public static let embeddedDataSHA = "973b19cd9b1e8801faf4892c952ff0bfc8cf944e8591a1738ce82f3a647c9391"
}

public var embeddedDataEtag: String {
Expand Down
12 changes: 8 additions & 4 deletions Core/BookmarksCleanupErrorHandling.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ public class BookmarksCleanupErrorHandling: EventMapping<BookmarksCleanupError>

public init() {
super.init { event, _, _, _ in
let domainEvent = Pixel.Event.bookmarksCleanupFailed
let processedErrors = CoreDataErrorsParser.parse(error: event.cleanupError as NSError)
let params = processedErrors.errorPixelParameters
if event.cleanupError is BookmarksCleanupCancelledError {
Pixel.fire(pixel: .bookmarksCleanupAttemptedWhileSyncWasEnabled)
} else {
let domainEvent = Pixel.Event.bookmarksCleanupFailed
let processedErrors = CoreDataErrorsParser.parse(error: event.cleanupError as NSError)
let params = processedErrors.errorPixelParameters

Pixel.fire(pixel: domainEvent, error: event.cleanupError, withAdditionalParameters: params)
Pixel.fire(pixel: domainEvent, error: event.cleanupError, withAdditionalParameters: params)
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion Core/ContentBlocking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ public final class ContentBlocking {

private init(privacyConfigurationManager: PrivacyConfigurationManaging? = nil) {
let internalUserDecider = DefaultInternalUserDecider(store: InternalUserStore())
let statisticsStore = StatisticsUserDefaults()
let privacyConfigurationManager = privacyConfigurationManager
?? PrivacyConfigurationManager(fetchedETag: UserDefaultsETagStorage().loadEtag(for: .privacyConfiguration),
fetchedData: FileStore().loadAsData(for: .privacyConfiguration),
embeddedDataProvider: AppPrivacyConfigurationDataProvider(),
localProtection: DomainsProtectionUserDefaultsStore(),
errorReporting: Self.debugEvents,
internalUserDecider: internalUserDecider)
internalUserDecider: internalUserDecider,
installDate: statisticsStore.installDate)
self.privacyConfigurationManager = privacyConfigurationManager

trackerDataManager = TrackerDataManager(etag: UserDefaultsETagStorage().loadEtag(for: .trackerDataSet),
Expand Down
12 changes: 8 additions & 4 deletions Core/CredentialsCleanupErrorHandling.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@ public class CredentialsCleanupErrorHandling: EventMapping<CredentialsCleanupErr

public init() {
super.init { event, _, _, _ in
let domainEvent = Pixel.Event.credentialsDatabaseCleanupFailed
let processedErrors = CoreDataErrorsParser.parse(error: event.cleanupError as NSError)
let params = processedErrors.errorPixelParameters
if event.cleanupError is CredentialsCleanupCancelledError {
Pixel.fire(pixel: .credentialsCleanupAttemptedWhileSyncWasEnabled)
} else {
let domainEvent = Pixel.Event.credentialsDatabaseCleanupFailed
let processedErrors = CoreDataErrorsParser.parse(error: event.cleanupError as NSError)
let params = processedErrors.errorPixelParameters

Pixel.fire(pixel: domainEvent, error: event.cleanupError, withAdditionalParameters: params)
Pixel.fire(pixel: domainEvent, error: event.cleanupError, withAdditionalParameters: params)
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions Core/FeatureFlag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public enum FeatureFlag: String {
case autofillInlineIconCredentials
case autofillAccessCredentialManagement
case autofillPasswordGeneration
case incontextSignup
case appTrackingProtection
case networkProtection
}
Expand All @@ -47,6 +48,8 @@ extension FeatureFlag: FeatureFlagSourceProviding {
return .remoteReleasable(.subfeature(AutofillSubfeature.accessCredentialManagement))
case .autofillPasswordGeneration:
return .remoteReleasable(.subfeature(AutofillSubfeature.autofillPasswordGeneration))
case .incontextSignup:
return .remoteReleasable(.feature(.incontextSignup))
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions Core/LocaleExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ extension Locale {
"MC", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT", "RO", "RS", "RU", "SE", "SI", "SK",
"SM", "TR", "UA", "GB", "VA"].contains(regionCode)
}

public var isEnglishLanguage: Bool {
return Locale.preferredLanguages.first?.lowercased().starts(with: "en") ?? false
}
}
2 changes: 2 additions & 0 deletions Core/Pixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public struct PixelParameters {
// Remote messaging
public static let message = "message"
public static let sheetResult = "success"

public static let defaultBrowser = "default_browser"
}

public struct PixelValues {
Expand Down
35 changes: 33 additions & 2 deletions Core/PixelEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ extension Pixel {
case lockScreenWidgetVoiceSearch
case lockScreenWidgetNewEmail

// MARK: Set as Default
case onboardingSetDefaultOpened
case onboardingSetDefaultSkipped

// MARK: debug pixels
case dbCrashDetected

Expand Down Expand Up @@ -435,6 +439,17 @@ extension Pixel {
case credentialsCleanupAttemptedWhileSyncWasEnabled

case invalidPayload(Configuration)

case dailyActiveUser

case emailIncontextPromptDisplayed
case emailIncontextPromptConfirmed
case emailIncontextPromptDismissed
case emailIncontextPromptDismissedPersistent
case emailIncontextModalDisplayed
case emailIncontextModalDismissed
case emailIncontextModalExitEarly
case emailIncontextModalExitEarlyContinue
}

}
Expand Down Expand Up @@ -724,13 +739,17 @@ extension Pixel.Event {
case .remoteMessageSecondaryActionClicked: return "m_remote_message_secondary_action_clicked"
case .remoteMessageSheet: return "m_remote_message_sheet"

// Lock Screen Widgets
// MARK: Lock Screen Widgets
case .lockScreenWidgetNewSearch: return "m_lockscreen_newsearch"
case .lockScreenWidgetFavorites: return "m_lockscreen_favorites"
case .lockScreenWidgetFireButton: return "m_lockscreen_fire"
case .lockScreenWidgetVoiceSearch: return "m_lockscreen_voicesearch"
case .lockScreenWidgetNewEmail: return "m_lockscreen_newemail"

// MARK: Set as default measuring
case .onboardingSetDefaultOpened: return "m_onboarding_set-default-opened"
case .onboardingSetDefaultSkipped: return "m_onboarding_set-default-skipped"

// MARK: debug pixels

case .dbCrashDetected: return "m_d_crash"
Expand Down Expand Up @@ -855,10 +874,22 @@ extension Pixel.Event {
case .bookmarksCleanupFailed: return "m_d_bookmarks_cleanup_failed"
case .bookmarksCleanupAttemptedWhileSyncWasEnabled: return "m_d_bookmarks_cleanup_attempted_while_sync_was_enabled"

case .credentialsDatabaseCleanupFailed: return "m_d_credentials_database_cleanup_failed"
case .credentialsDatabaseCleanupFailed: return "m_d_credentials_database_cleanup_failed_2"
case .credentialsCleanupAttemptedWhileSyncWasEnabled: return "m_d_credentials_cleanup_attempted_while_sync_was_enabled"

case .invalidPayload(let configuration): return "m_d_\(configuration.rawValue)_invalid_payload".lowercased()

case .dailyActiveUser: return "m_daily_active_user"

// MARK: - InContext Email Protection
case .emailIncontextPromptDisplayed: return "m_email_incontext_prompt_displayed"
case .emailIncontextPromptConfirmed: return "m_email_incontext_prompt_confirmed"
case .emailIncontextPromptDismissed: return "m_email_incontext_prompt_dismissed"
case .emailIncontextPromptDismissedPersistent: return "m_email_incontext_prompt_dismissed_persisted"
case .emailIncontextModalDisplayed: return "m_email_incontext_modal_displayed"
case .emailIncontextModalDismissed: return "m_email_incontext_modal_dismissed"
case .emailIncontextModalExitEarly: return "m_email_incontext_modal_exit_early"
case .emailIncontextModalExitEarlyContinue: return "m_email_incontext_modal_exit_early_continue"
}

}
Expand Down
55 changes: 55 additions & 0 deletions Core/SetAsDefaultStatistics.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// SetAsDefaultStatistics.swift
// DuckDuckGo
//
// Copyright © 2023 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

/// Measuring set as default usage. To be removed mid-end October.
public class SetAsDefaultStatistics {

@UserDefaultsWrapper(key: .defaultBrowserUsageLastSeen, defaultValue: nil)
var defaultBrowserUsageLastSeen: Date?

/// We assume we're default if we the app was launched with a URL in the last 7 days
public var isDefault: Bool {
guard let lastSeen = defaultBrowserUsageLastSeen,
let days = Calendar.current.numberOfDaysBetween(lastSeen, and: Date()) else { return false }
return (0...7).contains(days)
}

public init() { }

public func openedAsDefault() {
defaultBrowserUsageLastSeen = Date()
}

public func setAsDefaultOpened() {
Pixel.fire(pixel: .onboardingSetDefaultOpened)
}

public func setAsDefaultSkipped() {
Pixel.fire(pixel: .onboardingSetDefaultSkipped)
}

public func fireDailyActiveUser() {
DailyPixel.fire(pixel: .dailyActiveUser, withAdditionalParameters: [
PixelParameters.defaultBrowser: "\(isDefault)"
])
}

}
8 changes: 6 additions & 2 deletions Core/StatisticsLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ public class StatisticsLoader {
requestInstallStatistics(completion: completion)
return
}


SetAsDefaultStatistics().fireDailyActiveUser()

let configuration = APIRequest.Configuration(url: url)
let request = APIRequest(configuration: configuration, urlSession: .session())

Expand All @@ -109,7 +111,9 @@ public class StatisticsLoader {
requestInstallStatistics(completion: completion)
return
}


SetAsDefaultStatistics().fireDailyActiveUser()

let configuration = APIRequest.Configuration(url: url)
let request = APIRequest(configuration: configuration, urlSession: .session())

Expand Down
2 changes: 1 addition & 1 deletion Core/SyncBookmarksAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public final class SyncBookmarksAdapter {
}
}

public func updateDatabaseCleanupSchedule(shouldEnable: Bool) {
public func cleanUpDatabaseAndUpdateSchedule(shouldEnable: Bool) {
databaseCleaner.cleanUpDatabaseNow()
if shouldEnable {
databaseCleaner.scheduleRegularCleaning()
Expand Down
4 changes: 2 additions & 2 deletions Core/SyncCredentialsAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ public final class SyncCredentialsAdapter {
secureVaultFactory: secureVaultFactory,
secureVaultErrorReporter: secureVaultErrorReporter,
errorEvents: CredentialsCleanupErrorHandling(),
log: .passwordManager
log: .generalLog
)
}

public func updateDatabaseCleanupSchedule(shouldEnable: Bool) {
public func cleanUpDatabaseAndUpdateSchedule(shouldEnable: Bool) {
databaseCleaner.cleanUpDatabaseNow()
if shouldEnable {
databaseCleaner.scheduleRegularCleaning()
Expand Down
34 changes: 34 additions & 0 deletions Core/SyncDataProviders.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//

import BrowserServicesKit
import Combine
import Common
import DDGSync
import Persistence
Expand Down Expand Up @@ -46,6 +47,37 @@ public class SyncDataProviders: DataProvidersSource {
return providers.compactMap { $0 as? DataProviding }
}

public func setUpDatabaseCleanersIfNeeded(syncService: DDGSync) {
guard !isDatabaseCleanersSetUp else {
return
}

bookmarksAdapter.databaseCleaner.isSyncActive = { [weak syncService] in
syncService?.authState == .active
}
credentialsAdapter.databaseCleaner.isSyncActive = { [weak syncService] in
syncService?.authState == .active
}

let syncAuthStateDidChangePublisher = syncService.authStatePublisher
.dropFirst()
.map { $0 == .inactive }
.removeDuplicates()

syncAuthStateDidChangeCancellable = syncAuthStateDidChangePublisher
.sink { [weak self] isSyncDisabled in
self?.credentialsAdapter.cleanUpDatabaseAndUpdateSchedule(shouldEnable: isSyncDisabled)
self?.bookmarksAdapter.cleanUpDatabaseAndUpdateSchedule(shouldEnable: isSyncDisabled)
}

if syncService.authState == .inactive {
credentialsAdapter.cleanUpDatabaseAndUpdateSchedule(shouldEnable: true)
bookmarksAdapter.cleanUpDatabaseAndUpdateSchedule(shouldEnable: true)
}

isDatabaseCleanersSetUp = true
}

public init(
bookmarksDatabase: CoreDataDatabase,
secureVaultFactory: AutofillVaultFactory = AutofillSecureVaultFactory,
Expand Down Expand Up @@ -80,7 +112,9 @@ public class SyncDataProviders: DataProvidersSource {
}

private var isSyncMetadaDatabaseLoaded: Bool = false
private var isDatabaseCleanersSetUp: Bool = false
private var syncMetadata: SyncMetadataStore?
private var syncAuthStateDidChangeCancellable: AnyCancellable?

private let syncMetadataDatabase: CoreDataDatabase = SyncMetadataDatabase.make()
private let bookmarksDatabase: CoreDataDatabase
Expand Down
3 changes: 2 additions & 1 deletion Core/UserDefaultsPropertyWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ public struct UserDefaultsWrapper<T> {

case lastAppTrackingProtectionHistoryFetchTimestamp = "com.duckduckgo.ios.appTrackingProtection.lastTrackerHistoryFetchTimestamp"
case appTPUsed = "com.duckduckgo.ios.appTrackingProtection.appTPUsed"


case defaultBrowserUsageLastSeen = "com.duckduckgo.ios.default-browser-usage-last-seen"
}

private let key: Key
Expand Down
Loading

0 comments on commit 66ada8d

Please sign in to comment.