ublock list management initial

This commit is contained in:
Fabian Freund
2026-04-30 10:44:49 +02:00
parent 28dc4e93f1
commit d2bd36b1ed
43 changed files with 2894 additions and 65 deletions
@@ -36,7 +36,9 @@ import mozilla.components.browser.state.action.RestoreCompleteAction
import mozilla.components.browser.state.action.TabListAction
import mozilla.components.browser.state.action.CustomTabListAction
import mozilla.components.browser.state.selector.findCustomTab
import mozilla.components.ExperimentalAndroidComponentsApi
import mozilla.components.concept.engine.selection.SelectionActionDelegate
import mozilla.components.concept.engine.preferences.Branch
import mozilla.components.feature.addons.update.GlobalAddonDependencyProvider
import mozilla.components.support.base.facts.Facts
import mozilla.components.support.base.facts.processor.LogFactProcessor
@@ -50,6 +52,7 @@ import java.util.concurrent.TimeUnit
private const val HISTORY_METADATA_MAX_AGE_IN_MS = 14L * 24 * 60 * 60 * 1000 // 14 days
private const val DEFAULT_QUERY_PARAMETER_STRIPPING_STRIP_LIST =
"__hsfp __hssc __hstc __s _bhlid _branch_match_id _branch_referrer _gl _hsenc _kx _openstat at_recipient_id at_recipient_list bbeml bsft_clkid bsft_uid dclid et_rid fb_action_ids fb_comment_id fbclid gbraid gclid guce_referrer guce_referrer_sig hsCtaTracking igshid irclickid mc_eid mkt_tok ml_subscriber ml_subscriber_hash msclkid mtm_cid oft_c oft_ck oft_d oft_id oft_ids oft_k oft_lk oft_sk oly_anon_id oly_enc_id pk_cid rb_clickid s_cid sc_customer sc_eh sc_uid sms_click sms_source sms_uph srsltid ss_email_id syclid ttclid twclid unicorn_click_id vero_conv vero_id vgo_ee wbraid wickedid yclid ymclid ysclid"
private const val UBLOCK_FILTER_LISTS_PREF = "browser.weblibre.uBO.filterLists"
object GlobalComponents {
private var _components: Components? = null
@@ -87,6 +90,10 @@ object GlobalComponents {
// Startup settings for builder-only GeckoRuntimeSettings (fission, process isolation, etc.)
var startupSettings: GeckoEngineSettings? = null
// Startup pref written before web extensions initialize.
var startupUBlockFilterListsPref: String? = null
var clearStartupUBlockFilterListsPref: Boolean = false
fun shouldOpenLinksInApp(isExternalSession: Boolean = false): Boolean {
return when (engineSettingsApi!!.getAppLinksMode()) {
eu.weblibre.flutter_mozilla_components.pigeons.AppLinksMode.ALWAYS -> true
@@ -142,6 +149,40 @@ object GlobalComponents {
newComponents.useCases.downloadsUseCases.restoreDownloads()
}
// Submits the uBO managed-storage pref before web extensions register.
// Called from setUp() on the main thread; we do not block awaiting the
// ack callback because the engine dispatches it back to the main thread
// (which is held by setUp), and waiting would deadlock. The underlying
// GeckoView pref store accepts the new value before the callback fires,
// so by the time WebExtensionSupport.initialize installs uBO and the
// extension reads storage.managed, the pref is already present.
@OptIn(ExperimentalAndroidComponentsApi::class)
private fun applyStartupUBlockFilterListsPref(newComponents: Components) {
if (!clearStartupUBlockFilterListsPref && startupUBlockFilterListsPref == null) {
return
}
val onError: (Throwable) -> Unit = {
Logger.warn("Failed applying startup uBlock filter list pref", it)
}
if (clearStartupUBlockFilterListsPref) {
newComponents.core.engine.clearBrowserUserPref(
pref = UBLOCK_FILTER_LISTS_PREF,
onSuccess = {},
onError = onError,
)
} else {
newComponents.core.engine.setBrowserPref(
UBLOCK_FILTER_LISTS_PREF,
requireNotNull(startupUBlockFilterListsPref),
Branch.USER,
onSuccess = {},
onError = onError,
)
}
}
@OptIn(DelicateCoroutinesApi::class)
fun setUp(
applicationContext: ProfileContext,
@@ -206,6 +247,7 @@ object GlobalComponents {
if (mode == ComponentsMode.FULL) {
newComponents.core.engine.warmUp()
applyStartupUBlockFilterListsPref(newComponents)
}
fun restorePreviousCustomTabs() {
@@ -180,6 +180,8 @@ class GeckoBrowserApiImpl : GeckoBrowserApi {
fxaServerOverride: String?,
syncTokenServerOverride: String?,
startupSettings: GeckoEngineSettings?,
startupUBlockFilterListsPref: String?,
clearStartupUBlockFilterListsPref: Boolean,
) {
synchronized(this) {
if (!isGeckoInitialized) {
@@ -196,6 +198,9 @@ class GeckoBrowserApiImpl : GeckoBrowserApi {
// Store startup settings before runtime creation
GlobalComponents.startupSettings = startupSettings
GlobalComponents.startupUBlockFilterListsPref = startupUBlockFilterListsPref
GlobalComponents.clearStartupUBlockFilterListsPref =
clearStartupUBlockFilterListsPref
setupGeckoEngine(
profileFolder,
@@ -6282,7 +6282,7 @@ private open class GeckoPigeonCodec : StandardMessageCodec() {
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
interface GeckoBrowserApi {
fun getGeckoVersion(): String
fun initialize(profileFolder: String, logLevel: LogLevel, contentBlocking: ContentBlocking, addonCollection: AddonCollection?, fxaServerOverride: String?, syncTokenServerOverride: String?, startupSettings: GeckoEngineSettings?)
fun initialize(profileFolder: String, logLevel: LogLevel, contentBlocking: ContentBlocking, addonCollection: AddonCollection?, fxaServerOverride: String?, syncTokenServerOverride: String?, startupSettings: GeckoEngineSettings?, startupUBlockFilterListsPref: String?, clearStartupUBlockFilterListsPref: Boolean)
fun showNativeFragment(): Boolean
fun onTrimMemory(level: Long)
fun openInCustomTab(url: String, private: Boolean, contextId: String?)
@@ -6327,8 +6327,10 @@ interface GeckoBrowserApi {
val fxaServerOverrideArg = args[4] as String?
val syncTokenServerOverrideArg = args[5] as String?
val startupSettingsArg = args[6] as GeckoEngineSettings?
val startupUBlockFilterListsPrefArg = args[7] as String?
val clearStartupUBlockFilterListsPrefArg = args[8] as Boolean
val wrapped: List<Any?> = try {
api.initialize(profileFolderArg, logLevelArg, contentBlockingArg, addonCollectionArg, fxaServerOverrideArg, syncTokenServerOverrideArg, startupSettingsArg)
api.initialize(profileFolderArg, logLevelArg, contentBlockingArg, addonCollectionArg, fxaServerOverrideArg, syncTokenServerOverrideArg, startupSettingsArg, startupUBlockFilterListsPrefArg, clearStartupUBlockFilterListsPrefArg)
listOf(null)
} catch (exception: Throwable) {
GeckoPigeonUtils.wrapError(exception)
@@ -25,6 +25,8 @@ class GeckoBrowserService {
String? fxaServerOverride,
String? syncTokenServerOverride, [
GeckoEngineSettings? startupSettings,
String? startupUBlockFilterListsPref,
bool clearStartupUBlockFilterListsPref = false,
]) {
return _api.initialize(
profileFolder,
@@ -34,6 +36,8 @@ class GeckoBrowserService {
fxaServerOverride,
syncTokenServerOverride,
startupSettings,
startupUBlockFilterListsPref,
clearStartupUBlockFilterListsPref,
);
}
@@ -6394,6 +6394,8 @@ class GeckoBrowserApi {
String? fxaServerOverride,
String? syncTokenServerOverride,
GeckoEngineSettings? startupSettings,
String? startupUBlockFilterListsPref,
bool clearStartupUBlockFilterListsPref,
) async {
final pigeonVar_channelName =
'dev.flutter.pigeon.flutter_mozilla_components.GeckoBrowserApi.initialize$pigeonVar_messageChannelSuffix';
@@ -6411,6 +6413,8 @@ class GeckoBrowserApi {
fxaServerOverride,
syncTokenServerOverride,
startupSettings,
startupUBlockFilterListsPref,
clearStartupUBlockFilterListsPref,
]);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
@@ -1328,6 +1328,13 @@ class AddonCollection {
@HostApi()
abstract class GeckoBrowserApi {
String getGeckoVersion();
// [startupUBlockFilterListsPref] is the JSON-encoded value to write to the
// managed-storage pref read by uBlock Origin at extension startup. The pref
// must be written before the extension registers, so it is plumbed through
// initialize rather than set later.
// If [clearStartupUBlockFilterListsPref] is true, the pref is cleared and
// [startupUBlockFilterListsPref] is ignored. If both are unset/false, the
// pref is left untouched.
void initialize(
String profileFolder,
LogLevel logLevel,
@@ -1336,6 +1343,8 @@ abstract class GeckoBrowserApi {
String? fxaServerOverride,
String? syncTokenServerOverride,
GeckoEngineSettings? startupSettings,
String? startupUBlockFilterListsPref,
bool clearStartupUBlockFilterListsPref,
);
bool showNativeFragment();
void onTrimMemory(int level);