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

Unify Adblock engines into 1 engine #22127

Merged
merged 10 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,11 @@ extension BrowserViewController: WKNavigationDelegate {
{
let domain = Domain.getOrCreate(forUrl: requestURL, persistent: !isPrivateBrowsing)

let shouldBlock = await AdBlockStats.shared.shouldBlock(
let shouldBlock = await AdBlockGroupsManager.shared.shouldBlock(
requestURL: requestURL,
sourceURL: requestURL,
resourceType: .document,
isAggressiveMode: domain.blockAdsAndTrackingLevel.isAggressive
domain: domain
)

if shouldBlock, let url = requestURL.encodeEmbeddedInternalURL(for: .blocked) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ public class BrowserViewController: UIViewController {
ScriptFactory.shared.clearCaches()

Task {
await AdBlockStats.shared.didReceiveMemoryWarning()
await AdBlockGroupsManager.shared.didReceiveMemoryWarning()
}

for tab in tabManager.tabsForCurrentMode where tab.id != tabManager.selectedTab?.id {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ public actor LaunchHelper {

// Load cached data
// This is done first because compileResources need their results
async let filterListCache: Void = FilterListResourceDownloader.shared
.loadFilterListSettingsAndCachedData()
await FilterListStorage.shared.loadFilterListSettings()
await AdBlockGroupsManager.shared.loadResourcesFromCache()
async let loadEngines: Void = AdBlockGroupsManager.shared.loadEnginesFromCache()
async let adblockResourceCache: Void = AdblockResourceDownloader.shared
.loadCachedAndBundledDataIfNeeded(allowedModes: launchBlockModes)
_ = await (filterListCache, adblockResourceCache)
_ = await (loadEngines, adblockResourceCache)
Self.signpost.emitEvent("loadedCachedData", id: signpostID, "Loaded cached data")

ContentBlockerManager.log.debug("Loaded blocking launch data")
Expand Down Expand Up @@ -101,22 +102,10 @@ public actor LaunchHelper {
let signpostID = Self.signpost.makeSignpostID()
let state = Self.signpost.beginInterval("nonBlockingLaunchTask", id: signpostID)
await FilterListResourceDownloader.shared.start(with: adBlockService)
Self.signpost.emitEvent(
"FilterListResourceDownloader.shared.start",
id: signpostID,
"Started filter list downloader"
)
await AdblockResourceDownloader.shared.loadCachedAndBundledDataIfNeeded(
allowedModes: Set(remainingModes)
)
Self.signpost.emitEvent(
"loadCachedAndBundledDataIfNeeded",
id: signpostID,
"Reloaded data for remaining modes"
)
await AdblockResourceDownloader.shared.startFetching()
Self.signpost.emitEvent("startFetching", id: signpostID, "Started fetching ad-block data")

/// Cleanup rule lists so we don't have dead rule lists
let validBlocklistTypes = await self.getAllValidBlocklistTypes()
await ContentBlockerManager.shared.cleaupInvalidRuleLists(validTypes: validBlocklistTypes)
Expand Down Expand Up @@ -153,20 +142,17 @@ extension FilterListStorage {
// If we don't have filter lists yet loaded, use the settings
return Set(
allFilterListSettings.compactMap { setting -> ContentBlockerManager.BlocklistType? in
guard let componentId = setting.componentId else { return nil }
return .filterList(
componentId: componentId,
return setting.engineSource?.blocklistType(
isAlwaysAggressive: setting.isAlwaysAggressive
)
}
)
} else {
// If we do have filter lists yet loaded, use them as they are always the most up to date and accurate
return Set(
filterLists.map { filterList in
return .filterList(
componentId: filterList.entry.componentId,
isAlwaysAggressive: filterList.isAlwaysAggressive
filterLists.compactMap { filterList in
return filterList.engineSource.blocklistType(
isAlwaysAggressive: filterList.engineType.isAlwaysAggressive
)
}
)
Expand Down
12 changes: 6 additions & 6 deletions ios/brave-ios/Sources/Brave/Frontend/Browser/PageData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ struct PageData {
/// These are loaded dyncamically as the user scrolls through the page
private(set) var allSubframeURLs: Set<URL> = []
/// The stats class to get the engine data from
private var adBlockStats: AdBlockStats
private var groupsManager: AdBlockGroupsManager

init(mainFrameURL: URL, adBlockStats: AdBlockStats = AdBlockStats.shared) {
init(mainFrameURL: URL, groupsManager: AdBlockGroupsManager = AdBlockGroupsManager.shared) {
self.mainFrameURL = mainFrameURL
self.adBlockStats = adBlockStats
self.groupsManager = groupsManager
}

/// This method builds all the user scripts that should be included for this page
Expand Down Expand Up @@ -120,7 +120,7 @@ struct PageData {
domain: Domain,
isDeAmpEnabled: Bool
) async -> Set<UserScriptType> {
return await adBlockStats.makeEngineScriptTypes(
return await groupsManager.makeEngineScriptTypes(
frameURL: mainFrameURL,
isMainFrame: true,
isDeAmpEnabled: isDeAmpEnabled,
Expand All @@ -130,7 +130,7 @@ struct PageData {

func makeAllEngineScripts(for domain: Domain, isDeAmpEnabled: Bool) async -> Set<UserScriptType> {
// Add engine scripts for the main frame
async let engineScripts = adBlockStats.makeEngineScriptTypes(
async let engineScripts = groupsManager.makeEngineScriptTypes(
frameURL: mainFrameURL,
isMainFrame: true,
isDeAmpEnabled: isDeAmpEnabled,
Expand All @@ -139,7 +139,7 @@ struct PageData {

// Add engine scripts for all of the known sub-frames
async let additionalScriptTypes = allSubframeURLs.asyncConcurrentCompactMap({ frameURL in
return await self.adBlockStats.makeEngineScriptTypes(
return await self.groupsManager.makeEngineScriptTypes(
frameURL: frameURL,
isMainFrame: false,
isDeAmpEnabled: isDeAmpEnabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,25 @@ import os
@Published var cookieConsentBlocking: Bool {
didSet {
FilterListStorage.shared.ensureFilterList(
for: FilterList.cookieConsentNoticesComponentID,
for: AdblockFilterListCatalogEntry.cookieConsentNoticesComponentID,
isEnabled: cookieConsentBlocking
)

Task {
await AdBlockGroupsManager.shared.compileEnginesIfNeeded()
}
}
}
@Published var blockMobileAnnoyances: Bool {
didSet {
FilterListStorage.shared.ensureFilterList(
for: FilterList.mobileAnnoyancesComponentID,
for: AdblockFilterListCatalogEntry.mobileAnnoyancesComponentID,
isEnabled: blockMobileAnnoyances
)

Task {
await AdBlockGroupsManager.shared.compileEnginesIfNeeded()
}
}
}
@Published var isP3AEnabled: Bool {
Expand Down Expand Up @@ -101,11 +109,11 @@ import os
self.isDebounceEnabled = debounceService?.isEnabled ?? false

cookieConsentBlocking = FilterListStorage.shared.isEnabled(
for: FilterList.cookieConsentNoticesComponentID
for: AdblockFilterListCatalogEntry.cookieConsentNoticesComponentID
)

blockMobileAnnoyances = FilterListStorage.shared.isEnabled(
for: FilterList.mobileAnnoyancesComponentID
for: AdblockFilterListCatalogEntry.mobileAnnoyancesComponentID
)

var clearableSettings = [
Expand Down Expand Up @@ -232,11 +240,11 @@ import os
.sink { filterLists in
for filterList in filterLists {
switch filterList.entry.componentId {
case FilterList.cookieConsentNoticesComponentID:
case AdblockFilterListCatalogEntry.cookieConsentNoticesComponentID:
if filterList.isEnabled != self.cookieConsentBlocking {
self.cookieConsentBlocking = filterList.isEnabled
}
case FilterList.mobileAnnoyancesComponentID:
case AdblockFilterListCatalogEntry.mobileAnnoyancesComponentID:
if filterList.isEnabled != self.blockMobileAnnoyances {
self.blockMobileAnnoyances = filterList.isEnabled
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ struct FilterListsView: View {
@ObservedObject private var customFilterListStorage = CustomFilterListStorage.shared
@Environment(\.editMode) private var editMode
@State private var showingAddSheet = false
@State private var expectedEnabledSources: Set<CachedAdBlockEngine.Source> = Set(
AdBlockStats.shared.enabledSources
)
private let dateFormatter = RelativeDateTimeFormatter()

var body: some View {
Expand Down Expand Up @@ -67,14 +64,30 @@ struct FilterListsView: View {
)
}
.onDisappear {
Task.detached {
await AdBlockStats.shared.removeDisabledEngines()
await AdBlockStats.shared.ensureEnabledEngines()
Task {
await AdBlockGroupsManager.shared.compileEnginesIfNeeded()
}
}
}

@ViewBuilder private var filterListView: some View {
#if DEBUG
let allEnabled = Binding {
filterListStorage.filterLists.allSatisfy({ $0.isEnabled })
} set: { isEnabled in
filterListStorage.filterLists.enumerated().forEach { index, filterList in
let isEnabled = filterList.entry.hidden ? filterList.entry.defaultEnabled : isEnabled
filterListStorage.filterLists[index].isEnabled = isEnabled
}
}

Toggle(isOn: allEnabled) {
VStack(alignment: .leading) {
Text("All").foregroundColor(Color(.bravePrimary))
}
}
#endif

ForEach($filterListStorage.filterLists) { $filterList in
if !filterList.isHidden {
Toggle(isOn: $filterList.isEnabled) {
Expand All @@ -86,13 +99,6 @@ struct FilterListsView: View {
.foregroundColor(Color(.secondaryBraveLabel))
}
}
.onChange(of: filterList.isEnabled) { isEnabled in
if isEnabled {
expectedEnabledSources.insert(filterList.engineSource)
} else {
expectedEnabledSources.remove(filterList.engineSource)
}
}
}
}
}
Expand Down Expand Up @@ -129,12 +135,6 @@ struct FilterListsView: View {
}
}
.onChange(of: filterListURL.setting.isEnabled) { isEnabled in
if isEnabled {
expectedEnabledSources.insert(filterListURL.setting.engineSource)
} else {
expectedEnabledSources.remove(filterListURL.setting.engineSource)
}

Task {
CustomFilterListSetting.save(inMemory: !customFilterListStorage.persistChanges)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ extension ContentBlockerHelper: TabContentScript {
let data: [ContentblockerDTOData]
}

enum BlockedType: Hashable {
case image
case ad
}

static let scriptName = "TrackingProtectionStats"
static let scriptId = UUID().uuidString
static let messageHandlerName = "\(scriptName)_\(messageUUID)"
Expand Down Expand Up @@ -94,12 +99,12 @@ extension ContentBlockerHelper: TabContentScript {
guard let domainURLString = domain.url else { return }
let genericTypes = ContentBlockerManager.shared.validGenericTypes(for: domain)

let blockedType = await TPStatsBlocklistChecker.shared.blockedTypes(
let blockedType = await blockedTypes(
requestURL: requestURL,
sourceURL: sourceURL,
enabledRuleTypes: genericTypes,
resourceType: dto.resourceType,
isAggressiveMode: domain.blockAdsAndTrackingLevel.isAggressive
domain: domain
)

guard let blockedType = blockedType else { return }
Expand Down Expand Up @@ -148,4 +153,34 @@ extension ContentBlockerHelper: TabContentScript {
Logger.module.error("\(error.localizedDescription)")
}
}

@MainActor func blockedTypes(
requestURL: URL,
sourceURL: URL,
enabledRuleTypes: Set<ContentBlockerManager.GenericBlocklistType>,
resourceType: AdblockEngine.ResourceType,
domain: Domain
) async -> BlockedType? {
guard let host = requestURL.host, !host.isEmpty else {
// TP Stats init isn't complete yet
return nil
}

if resourceType == .image && Preferences.Shields.blockImages.value {
return .image
}

if enabledRuleTypes.contains(.blockAds) || enabledRuleTypes.contains(.blockTrackers) {
if await AdBlockGroupsManager.shared.shouldBlock(
requestURL: requestURL,
sourceURL: sourceURL,
resourceType: resourceType,
domain: domain
) {
return .ad
}
}

return nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ class CosmeticFiltersScriptHandler: TabContentScript {
forUrl: frameURL,
persistent: self.tab?.isPrivate == true ? false : true
)
let cachedEngines = await AdBlockStats.shared.cachedEngines(for: domain)
let cachedEngines = AdBlockGroupsManager.shared.cachedEngines(for: domain)

let selectorArrays = await cachedEngines.asyncConcurrentCompactMap {
let selectorArrays = await cachedEngines.asyncCompactMap {
cachedEngine -> (selectors: Set<String>, isAlwaysAggressive: Bool)? in
do {
guard
Expand All @@ -76,7 +76,7 @@ class CosmeticFiltersScriptHandler: TabContentScript {
return nil
}

return (selectors, cachedEngine.isAlwaysAggressive)
return (selectors, cachedEngine.type.isAlwaysAggressive)
} catch {
Logger.module.error("\(error.localizedDescription)")
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ class RequestBlockingContentScriptHandler: TabContentScript {
Task { @MainActor in
let domain = Domain.getOrCreate(forUrl: currentTabURL, persistent: !isPrivateBrowsing)
guard let domainURLString = domain.url else { return }
let shouldBlock = await AdBlockStats.shared.shouldBlock(
let shouldBlock = await AdBlockGroupsManager.shared.shouldBlock(
requestURL: requestURL,
sourceURL: sourceURL,
resourceType: dto.data.resourceType,
isAggressiveMode: domain.blockAdsAndTrackingLevel.isAggressive
domain: domain
)

// Ensure we check that the stats we're tracking is still for the same page
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class SiteStateListenerScriptHandler: TabContentScript {
return
}

let models = await AdBlockStats.shared.cosmeticFilterModels(
let models = await AdBlockGroupsManager.shared.cosmeticFilterModels(
forFrameURL: frameURL,
domain: domain
)
Expand All @@ -102,7 +102,7 @@ class SiteStateListenerScriptHandler: TabContentScript {
}

@MainActor private func makeSetup(
from modelTuples: [AdBlockStats.CosmeticFilterModelTuple],
from modelTuples: [AdBlockGroupsManager.CosmeticFilterModelTuple],
isAggressive: Bool
) throws -> UserScriptType.SelectorsPollerSetup {
var standardSelectors: Set<String> = []
Expand Down
Loading
Loading