lists.torproject.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

tbb-commits

Thread Start a new thread
Threads by month
  • ----- 2026 -----
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2018 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2017 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2016 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2015 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2014 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
tbb-commits@lists.torproject.org

July 2026

  • 1 participants
  • 154 discussions
[Git][tpo/applications/mullvad-browser][mullvad-browser-153.0esr-16.0-1] fixup! MB 97: Remove UI cues to install new extensions.
by Pier Angelo Vendrame (@pierov) 29 Jul '26

29 Jul '26
Pier Angelo Vendrame pushed to branch mullvad-browser-153.0esr-16.0-1 at The Tor Project / Applications / Mullvad Browser Commits: da45097b by Pier Angelo Vendrame at 2026-07-29T15:58:52+02:00 fixup! MB 97: Remove UI cues to install new extensions. MB 565: Update the selector to hide the help button in about:addons. - - - - - 1 changed file: - toolkit/mozapps/extensions/content/aboutaddons.css Changes: ===================================== toolkit/mozapps/extensions/content/aboutaddons.css ===================================== @@ -739,7 +739,7 @@ addon-page-header .main-search { visibility: hidden; } -#help-button, +[support-page="addons-help"], #empty-addons-message { display: none; } View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/da4… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/da4… You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1 0
0 0
[Git][tpo/applications/tor-browser-build][main] Bug 41843: Avoid storing unused universal apks
by boklm (@boklm) 29 Jul '26

29 Jul '26
boklm pushed to branch main at The Tor Project / Applications / tor-browser-build Commits: 777d1539 by Nicolas Vigier at 2026-07-29T15:51:51+02:00 Bug 41843: Avoid storing unused universal apks - - - - - 1 changed file: - projects/geckoview/build_ac_fenix.sh Changes: ===================================== projects/geckoview/build_ac_fenix.sh ===================================== @@ -63,3 +63,6 @@ mv $objdir/gradle/build/mobile/android/fenix/app/outputs/apk/$variant/*.apk $out mv $objdir/gradle/build/mobile/android/fenix/app/outputs/apk/androidTest/$variant/*.apk $outdir/[% project %]/tests popd + +# Remove universal apk files, since we don't use them (tor-browser-build#41843) +find $outdir/[% project %] -name 'app-universal-*.apk' -delete View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/7… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/7… You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1 0
0 0
[Git][tpo/applications/mullvad-browser][mullvad-browser-153.0esr-16.0-1] 3 commits: fixup! BB 44711: Hide unwanted setting controls in Base Browser.
by Pier Angelo Vendrame (@pierov) 29 Jul '26

29 Jul '26
Pier Angelo Vendrame pushed to branch mullvad-browser-153.0esr-16.0-1 at The Tor Project / Applications / Mullvad Browser Commits: 72648d16 by Henry Wilkes at 2026-07-29T15:33:53+02:00 fixup! BB 44711: Hide unwanted setting controls in Base Browser. BB 45156: Hide "Customize Firefox Home" in appearance settings. - - - - - 81f0f262 by Henry Wilkes at 2026-07-29T15:34:02+02:00 fixup! BB 41916: Letterboxing preferences UI BB 44959: Swap about:manual link. - - - - - 6b39a131 by Henry Wilkes at 2026-07-29T15:34:17+02:00 fixup! BB 40925: Implemented the Security Level component BB 44959: Swap about:manual link. - - - - - 4 changed files: - browser/components/preferences/config/appearance.mjs - browser/components/preferences/letterboxing.inc.xhtml - browser/components/securitylevel/content/securityLevelPanel.inc.xhtml - browser/components/securitylevel/content/securityLevelPreferences.inc.xhtml Changes: ===================================== browser/components/preferences/config/appearance.mjs ===================================== @@ -90,6 +90,8 @@ Preferences.addSetting({ Preferences.addSetting({ id: "related-settings-home-link", + // Hide the "Customize Firefox Home" link. tor-browser#45156. + visible: () => false, onUserClick: e => { e.preventDefault(); window.gotoPref("paneHome"); ===================================== browser/components/preferences/letterboxing.inc.xhtml ===================================== @@ -10,7 +10,7 @@ <html:span data-l10n-id="letterboxing-overview"></html:span> <html:a is="moz-support-link" - support-page="tor-manual:anti-fingerprinting_letterboxing" + support-page="tor-manual:features__fingerprinting-protections___letterboxing" data-l10n-id="letterboxing-learn-more" ></html:a> </description> ===================================== browser/components/securitylevel/content/securityLevelPanel.inc.xhtml ===================================== @@ -18,7 +18,7 @@ <html:a is="moz-support-link" id="securityLevel-learnMore" - support-page="tor-manual:security-settings" + support-page="tor-manual:features__security-levels" data-l10n-id="security-level-panel-learn-more-link" ></html:a> <html:img id="securityLevel-background-image" alt="" /> ===================================== browser/components/securitylevel/content/securityLevelPreferences.inc.xhtml ===================================== @@ -13,7 +13,7 @@ ></html:span> <html:a is="moz-support-link" - support-page="tor-manual:security-settings" + support-page="tor-manual:features__security-levels" data-l10n-id="security-level-preferences-learn-more-link" ></html:a> </description> View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/7e… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/7e… You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-153.0esr-16.0-1] 4 commits: fixup! TB 40933: Add tor-launcher functionality
by henry (@henry) 29 Jul '26

29 Jul '26
henry pushed to branch tor-browser-153.0esr-16.0-1 at The Tor Project / Applications / Tor Browser Commits: e6adf55b by Henry Wilkes at 2026-07-29T11:02:33+01:00 fixup! TB 40933: Add tor-launcher functionality TB 43186: Stop using `TorProviderBuilder` to prompt users on desktop. Also replace `settledState` with `currentState` and `settled`. - - - - - dda5c0f2 by Henry Wilkes at 2026-07-29T11:05:04+01:00 fixup! TB 40597: Implement TorSettings module TB 43186: TorConnect handles TorProvider initialisation errors. + Add the `"ProviderStopped"` stage, which we enter whenever the current `TorProvider` needs replacing. + In the `init` method we check `TorProvider.settledState` to see if the current provider is still running at startup. After this, we listen for the `ProviderStateChanged` event to see if it stops running later on. + We expose a `restartProvider` method to request a new provider. The `ProviderStatusChange` event allow consumers to update the UI. - - - - - 3d9e8cbc by Henry Wilkes at 2026-07-29T11:05:05+01:00 fixup! TB 27476: Implement about:torconnect captive portal within Tor Browser TB 43186: Add a `"ProviderStopped"` page to about:torconnect. - - - - - 3dbd891f by Henry Wilkes at 2026-07-29T11:05:06+01:00 fixup! Tor Browser strings TB 43186 - Add strings for the new `"ProviderStopped"` stage. - - - - - 9 changed files: - browser/components/torconnect/TorConnectParent.sys.mjs - browser/components/torconnect/content/aboutTorConnect.css - browser/components/torconnect/content/aboutTorConnect.html - browser/components/torconnect/content/aboutTorConnect.js - toolkit/components/tor-launcher/TorProviderBuilder.sys.mjs - toolkit/components/tor-launcher/tor-launcher.manifest - toolkit/locales/en-US/toolkit/global/tor-browser.ftl - toolkit/modules/RemotePageAccessManager.sys.mjs - toolkit/modules/TorConnect.sys.mjs Changes: ===================================== browser/components/torconnect/TorConnectParent.sys.mjs ===================================== @@ -3,6 +3,7 @@ import { TorStrings } from "moz-src:///toolkit/modules/TorStrings.sys.mjs"; import { TorConnect, + TorConnectStage, TorConnectTopics, } from "moz-src:///toolkit/modules/TorConnect.sys.mjs"; @@ -26,9 +27,7 @@ and a particular about:torconnect page * It adapts and relays the messages from and to the TorConnect module. */ export class TorConnectParent extends JSWindowActorParent { - constructor(...args) { - super(...args); - + actorCreated() { const self = this; // JSWindowActiveParent derived objects cannot observe directly, so create a @@ -44,6 +43,9 @@ export class TorConnectParent extends JSWindowActorParent { case TorConnectTopics.StageChange: self.sendAsyncMessage("torconnect:stage-change", obj); break; + case TorConnectTopics.ProviderStatusChange: + self.sendAsyncMessage("torconnect:provider-status-change", obj); + break; case TorConnectTopics.BootstrapProgress: self.sendAsyncMessage("torconnect:bootstrap-progress", obj); break; @@ -64,6 +66,10 @@ export class TorConnectParent extends JSWindowActorParent { this.torConnectObserver, TorConnectTopics.StageChange ); + Services.obs.addObserver( + this.torConnectObserver, + TorConnectTopics.ProviderStatusChange + ); Services.obs.addObserver( this.torConnectObserver, TorConnectTopics.BootstrapProgress @@ -124,6 +130,9 @@ export class TorConnectParent extends JSWindowActorParent { Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit ); break; + case "torconnect:restart-provider": + TorConnect.restartProvider(); + break; case "torconnect:start-again": TorConnect.startAgain(); break; @@ -267,3 +276,13 @@ export class TorConnectParent extends JSWindowActorParent { ); } } + +Services.obs.addObserver((_subject, topic) => { + if (topic !== TorConnectTopics.StageChange) { + return; + } + if (TorConnect.stageName === TorConnectStage.ProviderStopped) { + // Make sure we have an open tab to show the ProviderStopped stage. + TorConnectParent.open(); + } +}, TorConnectTopics.StageChange); ===================================== browser/components/torconnect/content/aboutTorConnect.css ===================================== @@ -235,40 +235,57 @@ form#locationDropdown select { stroke: var(--icon-color); /* Make non-interactive (non-draggable). */ pointer-events: none; -} -.torconnect-icon.offline-icon { - content: url("chrome://browser/content/torconnect/network-broken.svg"); -} + &.offline-icon { + content: url("chrome://browser/content/torconnect/network-broken.svg"); + } -.torconnect-icon.assist-icon { - content: url("chrome://browser/content/torconnect/tor-connect-broken.svg"); -} + &.assist-icon { + content: url("chrome://browser/content/torconnect/tor-connect-broken.svg"); + } -.torconnect-icon.location-icon { - content: url("chrome://browser/content/torconnect/connection-location.svg"); - stroke: var(--icon-color-warning); + &.location-icon { + content: url("chrome://browser/content/torconnect/connection-location.svg"); + stroke: var(--icon-color-warning); + } } .torconnect-heading { grid-area: heading; /* Do not show the focus outline. */ outline: none; - font-size: var(--font-size-xxxlarge); + font-size: var(--font-size-xxlarge); margin: 0; margin-block-end: var(--space-xxlarge); } .torconnect-text-container { grid-area: text-container; + + & > *:not(:last-child) { + margin-block-end: var(--space-large); + } + + & :is(p, ul) { + margin: 0; + } + + & ul { + padding-inline-start: var(--space-xxlarge); + } + + & li:not(:last-child) { + margin-block-end: var(--space-medium); + } } -.torconnect-text-container p { - margin: 0; +.torconnect-list-intro { + font-weight: var(--font-weight-semibold); } -.torconnect-text-container > *:not(:last-child) { - margin-block-end: var(--space-large); +body.hide-provider-config-debugging .provider-config-debugging, +body:not(.hide-provider-config-debugging) .provider-generic-debugging { + display: none; } .torconnect-controls-container { @@ -281,11 +298,33 @@ form#locationDropdown select { align-items: center; /* Gap between children and rows. */ gap: var(--space-small) var(--space-small); + + & > * { + flex: 0 0 max-content; + margin: 0; + } } -.torconnect-controls-container > * { - flex: 0 0 max-content; - margin: 0; +#restart-provider-failed { + color: var(--text-color-error); + align-items: center; + gap: var(--space-xxsmall); + + &:not([hidden]) { + display: flex; + } + + & > * { + flex: 0 0 max-content; + } +} + +#restart-provider-failed-icon { + width: var(--icon-size); + height: var(--icon-size); + -moz-context-properties: fill; + fill: var(--icon-color-critical); + content: url("chrome://global/skin/icons/error.svg"); } /* Temporary hacks for the connectPageContainer. */ ===================================== browser/components/torconnect/content/aboutTorConnect.html ===================================== @@ -15,12 +15,22 @@ href="chrome://browser/content/torconnect/aboutTorConnect.css" /> + <link rel="localization" href="branding/brand.ftl" /> <link rel="localization" href="toolkit/global/tor-browser.ftl" /> + <link rel="localization" href="toolkit/global/mozSupportLink.ftl" /> + <script + type="module" + src="chrome://global/content/elements/moz-button.mjs" + ></script> <script type="module" src="chrome://global/content/elements/moz-toggle.mjs" ></script> + <script + type="module" + src="chrome://global/content/elements/moz-support-link.mjs" + ></script> </head> <body class="onion-pattern-background"> <div id="progressBar" hidden="hidden"> @@ -50,6 +60,86 @@ <span class="breadcrumb-label"></span> </span> </div> + <div class="torconnect-stage-content" data-stage-name="ProviderStopped"> + <img class="torconnect-icon assist-icon" alt="" /> + <h1 + class="torconnect-heading" + tabindex="-1" + data-l10n-id="tor-connect-tor-not-working-heading" + ></h1> + <div class="torconnect-text-container"> + <p data-l10n-id="tor-connect-tor-not-working-intro"></p> + <p + class="torconnect-list-intro" + data-l10n-id="tor-connect-tor-not-working-cause-intro" + ></p> + <ul> + <li + class="provider-config-debugging" + data-l10n-id="tor-connect-tor-not-working-cause-applications" + ></li> + <li + class="provider-config-debugging" + data-l10n-id="tor-connect-tor-not-working-cause-files" + ></li> + <li + class="provider-config-debugging" + data-l10n-id="tor-connect-tor-not-working-cause-other" + ></li> + <li + class="provider-generic-debugging" + data-l10n-id="tor-connect-tor-not-working-cause-generic" + ></li> + </ul> + <p + class="torconnect-list-intro" + data-l10n-id="tor-connect-tor-not-working-resolve-intro" + ></p> + <ul> + <li + class="provider-config-debugging" + data-l10n-id="tor-connect-tor-not-working-resolve-applications" + ></li> + <li + class="provider-config-debugging" + data-l10n-id="tor-connect-tor-not-working-resolve-files" + ></li> + <li + class="provider-config-debugging" + data-l10n-id="tor-connect-tor-not-working-resolve-restart-long" + ></li> + <li + class="provider-generic-debugging" + data-l10n-id="tor-connect-tor-not-working-resolve-restart-short" + ></li> + </ul> + <p data-l10n-id="tor-connect-tor-not-working-support"> + <a + is="moz-support-link" + data-l10n-name="support-link" + support-page="tor-manual:get-in-touch__bug-or-feedback" + > + </a> + </p> + <a + is="moz-support-link" + support-page="tor-manual:encountering-issues__troubleshooting" + ></a> + </div> + <div class="torconnect-controls-container"> + <div id="restart-provider-failed" role="alert"> + <img id="restart-provider-failed-icon" alt="" /> + <span + data-l10n-id="tor-connect-tor-not-working-restarting-failed" + ></span> + </div> + <moz-button + id="restart-provider-button" + type="primary" + data-l10n-id="tor-connect-tor-not-working-restart-button" + ></moz-button> + </div> + </div> <div id="connectPageContainer" class="torconnect-stage-content"> <img id="tor-connect-icon" class="torconnect-icon" alt="" /> <h1 ===================================== browser/components/torconnect/content/aboutTorConnect.js ===================================== @@ -134,6 +134,8 @@ class AboutTorConnect { "full-regions-option-group" ), tryBridgeButton: document.querySelector(this.selectors.buttons.tryBridge), + restartProviderButton: document.getElementById("restart-provider-button"), + restartProviderFailed: document.getElementById("restart-provider-failed"), }); /** @@ -418,6 +420,10 @@ class AboutTorConnect { console.warn("Page opened whilst loading"); isLoaded = false; break; + case "ProviderStopped": + this.hideBreadcrumbs(); + this.updateProviderStatus(stage.providerStatus, true); + break; case "Start": this.showStart(stage.tryAgain, stage.potentiallyBlocked); if (focusConnect) { @@ -479,6 +485,157 @@ class AboutTorConnect { moveFocus.focus(); } + /** + * The stored data for the `ProviderStopped` page content. `null` whilst + * uninitialized. + * + * @type {object} + */ + _providerStoppedData = null; + + /** + * Called whenever the tor provider status may have changed. Only relevant in + * the `ProviderStopped` stage. + * + * @param {ProviderStatus} providerStatus - The latest provider status. + * @param {boolean} enteringStage - Whether this is being called because we + * have just entered the `ProviderStopped` stage as the initial stage of the + * page, or transitioning from another stage. + */ + updateProviderStatus(providerStatus, enteringStage) { + if (this.shownStage !== "ProviderStopped") { + // Ignore. + return; + } + if (enteringStage) { + // Reset the data: + // + When entering the stage. + // + When opening the page in this initial stage. + this._providerStoppedData = { + // Set to `null` to make sure we don't early exit below. + isRestarting: null, + forceShowRestarting: false, + canShowFailedAlert: false, + // We set the maybeConfigIssue when entering the stage, but do not attempt + // to update it between failed attempts. + maybeConfigIssue: providerStatus.maybeConfigIssue, + }; + } + + // We show the UI as restarting if the state is not "Stopped", which + // includes both "Starting" and "Running". In the latter case (which is + // unexpected) we still want to show the state as loading before we enter a + // different shownStage. + const restarting = providerStatus.state !== "Stopped"; + + const data = this._providerStoppedData; + + if (restarting === data.isRestarting) { + // No change in the recorded state. Don't change the UI or adjust any + // timeouts. + return; + } + + data.isRestarting = restarting; + if (restarting) { + // Whilst we remain in this `ProviderStopped` stage, we will now show the + // failed alert when we re-enter the "Stopped" state. + data.canShowFailedAlert = true; + + if (!data.forceShowRestarting) { + // Force the restarting UI to show for at least a certain amount of + // time. Even if we fail early, we continue to show the restarting UI + // for a short time to make sure the user has enough time to visually + // see the restarting UI before we return to the error state. + data.forceShowRestarting = true; + setTimeout(() => { + if ( + data !== this._providerStoppedData || + this.shownStage !== "ProviderStopped" + ) { + // We left or re-entered this stage whilst waiting. Do nothing. + return; + } + data.forceShowRestarting = false; + this.updateProviderStoppedContent(); + }, 1000); + } + // Else, we already have a pending timeout. + // E.g., consider the following timeline, where "R" represents entering + // the "Starting" state, "S" represents entering the "Stopped" state, + // "T0" represents the start of the forcedShowRestarting timeout, and "T1" + // represents the completion: + // + // |--------------+-----+-----+-----+----+------------------> + // S0 R0 S1 R1 S2 + // T0 T1 + // |--stopped UI--|--restarting UI-------|--stopped UI------- + // + // + // Similarly with S2 delayed: + // + // |--------------+-----+-----+----------+----+-------------> + // S0 R0 S1 R1 S2 + // T0 T1 + // |--stopped UI--|--restarting UI------------|--stopped UI-- + // + // + // I.e. we restart once (R0) which starts the timeout. Then we stop (S1) and + // restart (R1) again (though unlikely, this could happen if the user + // opens another `about:torconnect` tab after S1 and presses the restart + // button). Rather than create a new timeout, which would delay the + // restart display for even longer, we maintain the current one. + } + + this.updateProviderStoppedContent(); + } + + /** + * Whether we are currently *showing* the tor provider as restarting in the + * UI. + * + * @type {boolean} + */ + restartingProvider = false; + + /** + * Called to update the page content for the `ProviderStopped` stage. + */ + updateProviderStoppedContent() { + const { + isRestarting, + forceShowRestarting, + canShowFailedAlert, + maybeConfigIssue, + } = this._providerStoppedData; + + // Hide any of the debugging information related to configuration issues if + // we do not suspect that this could be the cause. + document.body.classList.toggle( + "hide-provider-config-debugging", + !maybeConfigIssue + ); + + const showRestarting = isRestarting || forceShowRestarting; + this.elements.restartProviderFailed.hidden = + showRestarting || !canShowFailedAlert; + + this.restartingProvider = showRestarting; + // The button is functionally disabled, but can still keep focus. + // TODO: tor-browser#45050. Disabled attribute is waiting on bugzilla bug + // 1927727. + // this.elements.restartProviderButton.disabled = showRestarting; + this.elements.restartProviderButton.iconSrc = showRestarting + ? "chrome://global/skin/icons/loading.svg" + : null; + document.l10n.setAttributes( + this.elements.restartProviderButton, + showRestarting + ? "tor-connect-tor-not-working-restarting-button" + : "tor-connect-tor-not-working-restart-button" + ); + } + updateBootstrappingStatus(data) { this.elements.progressMeter.style.setProperty( "--progress-percent", @@ -816,6 +973,14 @@ class AboutTorConnect { RPMSendAsyncMessage("torconnect:restart"); }); + this.elements.restartProviderButton.addEventListener("click", () => { + if (this.restartingProvider) { + // Ignore clicks whilst the button is shown as "Restarting". + return; + } + RPMSendAsyncMessage("torconnect:restart-provider"); + }); + this.elements.configureButton.textContent = TorStrings.torConnect.torConfigure; this.elements.configureButton.addEventListener("click", () => { @@ -896,6 +1061,9 @@ class AboutTorConnect { RPMAddMessageListener("torconnect:stage-change", ({ data }) => { this.updateStage(data); }); + RPMAddMessageListener("torconnect:provider-status-change", ({ data }) => { + this.updateProviderStatus(data, false); + }); RPMAddMessageListener("torconnect:bootstrap-progress", ({ data }) => { this.updateBootstrappingStatus(data); }); ===================================== toolkit/components/tor-launcher/TorProviderBuilder.sys.mjs ===================================== @@ -204,13 +204,13 @@ export class TorProviderBuilder { // I.e. it should be safe to call // TorProviderBuilder.init(); // TorProviderBuilder.build(); - // TorProviderBuilder.settledState(); + // TorProviderBuilder.settled(); // // etc // without any await. // // In particular, this is needed by `TorConnect.init`, which will call - // `settledState`. It will also call `build` immediately if quickstart is - // set. See tor-browser#41921. + // `settled`. It will also call `build` immediately if quickstart is set. + // See tor-browser#41921. if (this.#providerData) { lazy.logger.info( `Replacing the provider with a "${this.providerType}" provider.` @@ -372,21 +372,24 @@ export class TorProviderBuilder { } /** - * Get the state of the current provider instance. Waits until the provider - * has finished initialisation first. + * Get the state of the current provider instance. * - * If the provider has been replaced, the Stopped state will be returned. - * - * @returns {string} - The `TorProviderState` state for the provider that - * existed when this method was called. + * @returns {string} - The `TorProviderState` state for the current provider. */ - static async settledState() { + static currentState() { + this.#checkActive(); + return this.#providerData.provider.state; + } + + /** + * Wait until the current provider instance has finished initializing, so it + * is no longer in the `Starting` state. + */ + static async settled() { this.#checkActive(); - const { provider, initPromise } = this.#providerData; try { - await initPromise; + await this.#providerData.initPromise; } catch {} - return this.#checkProviderState(provider); } /** ===================================== toolkit/components/tor-launcher/tor-launcher.manifest ===================================== @@ -1,2 +1 @@ category profile-after-change TorStartupService @torproject.org/tor-startup-service;1 -category browser-first-window-ready moz-src:///toolkit/components/tor-launcher/TorProviderBuilder.sys.mjs TorProviderBuilder.firstWindowLoaded ===================================== toolkit/locales/en-US/toolkit/global/tor-browser.ftl ===================================== @@ -15,6 +15,37 @@ appmenu-open-tor-manual = # Here "Tor" refers to the Tor network. tor-connect-page-title = Connect to Tor +# Here "process" is a noun, referring to the execution of a computer program. "Tor process" specifically refers to the execution of the tor program, which is the program that handles the connection to the "Tor network". +tor-connect-tor-not-working-heading = The Tor process has stopped working +# Here "process" is a noun, referring to the execution of a computer program. +tor-connect-tor-not-working-intro = The underlying process that controls your connection to the Tor network has stopped working. +tor-connect-tor-not-working-cause-intro = What could be causing this? +# "-brand-short-name" will be substituted with the localized name for "Tor Browser". +tor-connect-tor-not-working-cause-applications = Another application that uses the Tor network is conflicting with { -brand-short-name }. +# Here "process" is a noun, referring to the execution of a computer program. "Tor process" specifically refers to the execution of the tor program, which is the program that handles the connection to the "Tor network". +tor-connect-tor-not-working-cause-files = The files used by the Tor process have been modified or removed. +# Here "process" is a noun, referring to the execution of a computer program. "Tor process" specifically refers to the execution of the tor program, which is the program that handles the connection to the "Tor network". +tor-connect-tor-not-working-cause-other = The Tor process has stopped working due to a different technical issue. +# Here "process" is a noun, referring to the execution of a computer program. "Tor process" specifically refers to the execution of the tor program, which is the program that handles the connection to the "Tor network". +tor-connect-tor-not-working-cause-generic = The Tor process has stopped working due to a technical issue. +tor-connect-tor-not-working-resolve-intro = What can you do about it? +tor-connect-tor-not-working-resolve-applications = Quit any other applications that use the Tor network, or reconfigure them. +# Here "process" is a noun, referring to the execution of a computer program. "Tor process" specifically refers to the execution of the tor program, which is the program that handles the connection to the "Tor network". +tor-connect-tor-not-working-resolve-files = If you have modified the files used by the Tor process, undo these changes. +# Here "process" is a noun, referring to the execution of a computer program. "Tor process" specifically refers to the execution of the tor program, which is the program that handles the connection to the "Tor network". +tor-connect-tor-not-working-resolve-restart-long = Once you have followed these steps, or made any other change, try restarting the Tor process (this won’t close your browser tabs). +# Here "process" is a noun, referring to the execution of a computer program. "Tor process" specifically refers to the execution of the tor program, which is the program that handles the connection to the "Tor network". +tor-connect-tor-not-working-resolve-restart-short = Try restarting the Tor process (this won’t close your browser tabs). +# The translation of "support channels" should also be wrapped in '<a data-l10n-name="support-link">' and '</a>', which will link to the corresponding support page. +tor-connect-tor-not-working-support = If the problem remains, get in contact with us through one of our <a data-l10n-name="support-link">support channels</a>. +# Here "process" is a noun, referring to the execution of a computer program. "Tor process" specifically refers to the execution of the tor program, which is the program that handles the connection to the "Tor network". +tor-connect-tor-not-working-restart-button = + .label = Restart Tor process +# Here "process" is a noun, referring to the execution of a computer program. "Tor process" specifically refers to the execution of the tor program, which is the program that handles the connection to the "Tor network". +tor-connect-tor-not-working-restarting-button = + .label = Restarting Tor process… +tor-connect-tor-not-working-restarting-failed = Restarting failed + ## Tor Browser home page. tor-browser-home-heading-stable = Explore. Privately. ===================================== toolkit/modules/RemotePageAccessManager.sys.mjs ===================================== @@ -296,6 +296,7 @@ export let RemotePageAccessManager = { "about:torconnect": { RPMAddMessageListener: [ "torconnect:stage-change", + "torconnect:provider-status-change", "torconnect:bootstrap-progress", "torconnect:quickstart-change", "torconnect:region-names-change", @@ -307,10 +308,12 @@ export let RemotePageAccessManager = { "torconnect:set-quickstart", "torconnect:view-tor-logs", "torconnect:restart", + "torconnect:restart-provider", "torconnect:start-again", "torconnect:choose-region", ], RPMSendQuery: ["torconnect:get-init-args", "torconnect:get-regions"], + RPMGetFormatURLPref: ["app.support.baseURL"], }, "about:welcome": { RPMSendAsyncMessage: ["ActivityStream:ContentToMain"], ===================================== toolkit/modules/TorConnect.sys.mjs ===================================== @@ -10,6 +10,8 @@ ChromeUtils.defineESModuleGetters(lazy, { MoatRPC: "moz-src:///toolkit/modules/Moat.sys.mjs", TorBootstrapRequest: "moz-src:///toolkit/components/tor-launcher/TorBootstrapRequest.sys.mjs", + TorProviderBuilder: + "moz-src:///toolkit/components/tor-launcher/TorProviderBuilder.sys.mjs", TorProviderState: "moz-src:///toolkit/components/tor-launcher/TorProviderBuilder.sys.mjs", TorProviderTopics: @@ -81,11 +83,28 @@ ChromeUtils.defineLazyGetter(lazy, "logger", () => /* Topics Notified by the TorConnect module */ export const TorConnectTopics = Object.freeze({ + // Fired when the stage changes. + // The stage name from `TorConnectStage` is passed as the event subject. StageChange: "torconnect:stage-change", + // Fired when the `TorConnect.quickstart` value changes. QuickstartChange: "torconnect:quickstart-change", + // Fired when the `TorConnect.internetStatus` changes. InternetStatusChange: "torconnect:internet-status-change", + // Fired when the `TorConnect.stage.providerStatus` changes. + // NOTE: The state of the provider may switch to `TorProviderState.Stopped` + // prior to `TorConnect` entering the stage `TorConnectStage.ProviderStopped` + // because a stage switch can be delayed. A consumer should always show the + // current `TorConnect` stage as the highest priority, and only react to this + // event when we are already in the `TorConnectStage.ProviderStopped` stage. + // The `ProviderStatus` object is passed as the event subject. + ProviderStatusChange: "torconnect:provider-status-change", + // Fired when the list of region names returned by `TorConnect.getRegionNames` + // may have changed. RegionNamesChange: "torconnect:region-names-change", + // Fired when the `TorConnect.stage.bootstrapStatus` may have changed. + // The `BootstrapStatus` object is passed as the event subject. BootstrapProgress: "torconnect:bootstrap-progress", + // Fired when we enter the `TorConnectStage.Bootstrapped` stage. BootstrapComplete: "torconnect:bootstrap-complete", }); @@ -655,6 +674,7 @@ export const InternetStatus = Object.freeze({ export const TorConnectStage = Object.freeze({ Disabled: "Disabled", Loading: "Loading", + ProviderStopped: "ProviderStopped", Start: "Start", Bootstrapping: "Bootstrapping", Offline: "Offline", @@ -689,6 +709,8 @@ export const TorConnectStage = Object.freeze({ * have reached an error stage at some point before being bootstrapped. * @property {BootstrappingStatus} bootstrappingStatus - The current * bootstrapping status. + * @property {ProviderStatus} providerStatus - The current status of the Tor + * provider. */ /** @@ -714,6 +736,19 @@ export const TorConnectStage = Object.freeze({ * @property {?string} reason - The bootstrapping failure reason. */ +/** + * @typedef {object} ProviderStatus + * + * The status of the current Tor provider. + * + * @property {string} state - The current `TorProviderState` state of the + * provider. + * @property {boolean} maybeConfigIssue - Whether we suspect that a + * configuration issue (conflicting tor process or a mis-config) *may* have + * caused the provider to be stopped. This is a *soft* indicator for UI + * purposes to show additional debugging advice that might resolve the issue. + */ + export const TorConnect = { /** * Default bootstrap options for simulation. @@ -800,6 +835,52 @@ export const TorConnect = { */ _potentiallyBlocked: false, + /** + * The current `TorProviderState` state. `null` whilst we wait for + * `TorProviderBuilder.settled` to return. + * + * @type {?string} + */ + _providerKnownState: null, + + /** + * The current `TorProviderState` state. Whilst we wait for + * `TorProviderBuilder.settled` to return with the true state, we will assume + * that the provider is in the `TorProviderState.Running` state, as would be + * expected under normal circumstances. + */ + get _providerState() { + return this._providerKnownState ?? lazy.TorProviderState.Running; + }, + + /** + * Convenience property for detecting when a provider is running. + * + * @type {boolean} + */ + get _providerRunning() { + return this._providerState === lazy.TorProviderState.Running; + }, + + /** + * Whether we suspect a config issue cause the provider to fail. + * + * @type {boolean} + */ + _maybeConfigIssue: false, + + /** + * The latest provider status information for consumers. + * + * @returns {ProviderStatus} - The provider status. + */ + _providerStatus() { + return { + state: this._providerState, + maybeConfigIssue: this._maybeConfigIssue, + }; + }, + /** * Get a summary of the current user stage. * @@ -822,6 +903,7 @@ export const TorConnect = { tryAgain: this._tryAgain, potentiallyBlocked: this._potentiallyBlocked, bootstrappingStatus: structuredClone(this._bootstrappingStatus), + providerStatus: this._providerStatus(), }; }, @@ -928,6 +1010,23 @@ export const TorConnect = { this._updateInternetStatus(); + // Do not await the `TorProviderBuilder` initialisation before we move to + // the Start stage so that the UI can load quickly. We presume it will not + // fail, but will switch to `ProviderStopped` if necessary. + lazy.TorProviderBuilder.settled().then(() => { + // NOTE: Assuming `TorConnect` is the only consumer of + // `TorProviderBuilder` that will replace the provider, then the current + // provider should be the *first* provider. + const state = lazy.TorProviderBuilder.currentState(); + lazy.logger.debug(`Init state: ${state}`); + this._setProviderState(state, true); + }); + + if (!this._providerRunning) { + // Promise resolved immediately, and failed. Should have already requested + // the ProviderStopped stage. + return; + } // NOTE: At this point, _requestedStage should still be `null`. this._setStage(TorConnectStage.Start); if ( @@ -955,19 +1054,13 @@ export const TorConnect = { } break; case lazy.TorProviderTopics.ProviderStateChanged: - if (data !== lazy.TorProviderState.Stopped) { - break; - } - lazy.logger.info("Starting again since the tor process exited"); - // Treat a failure as a possibly broken configuration. - // So, prevent quickstart at the next start. - Services.prefs.setBoolPref(TorConnectPrefs.prompt_at_startup, true); - this._makeStageRequest(TorConnectStage.Start, true); + this._setProviderState(data, false); break; case lazy.TorSettingsTopics.SettingsChanged: if ( this._stageName !== TorConnectStage.Bootstrapped && this._stageName !== TorConnectStage.Loading && + this._stageName !== TorConnectStage.ProviderStopped && this._stageName !== TorConnectStage.Start && subject.wrappedJSObject.changes.some(propertyName => propertyName.startsWith("bridges.") @@ -1009,9 +1102,20 @@ export const TorConnect = { * @param {string} name - The name of the stage to move to. */ _setStage(name) { + if (this._stageName === TorConnectStage.Disabled) { + throw new Error(`Trying to set the stage to ${name} when disabled`); + } if (this._bootstrapAttempt) { throw new Error(`Trying to set the stage to ${name} during a bootstrap`); } + if (!this._providerRunning && name !== TorConnectStage.ProviderStopped) { + if (!lazy.TorLauncherUtil.isAndroid) { + // TODO: Remove Android exception. + throw new Error( + `Trying to set the stage to ${name} when provider is not running` + ); + } + } lazy.logger.info(`Entering stage ${name}`); this._stageName = name; @@ -1211,6 +1315,13 @@ export const TorConnect = { return false; } + if (!this._providerRunning) { + lazy.logger.warn( + `Tor provider is not running. Ignoring request with ${regionCode}.` + ); + return false; + } + const currentStage = this._stageName; if (regionCode) { @@ -1315,7 +1426,7 @@ export const TorConnect = { this._defaultRegion = bootstrapAttempt.detectedRegion; } - if (result === "complete") { + if (result === "complete" && this._providerRunning) { // Reset tryAgain, potentiallyBlocked and errorDetails in case the tor // process exists later on. this._tryAgain = false; @@ -1351,15 +1462,10 @@ export const TorConnect = { this._tryAgain = true; if (error instanceof lazy.TorProviderInitError) { - // Treat like TorProviderTopics.ProviderStateChanged. We expect a user - // notification when this happens. - // Treat a failure as a possibly broken configuration. - // So, prevent quickstart at the next start. - Services.prefs.setBoolPref(TorConnectPrefs.prompt_at_startup, true); - lazy.logger.info( - "Starting again since the tor provider failed to initialise" - ); - this._setStage(TorConnectStage.Start); + // Unexpected. We expect TorProviderTopics.ProviderStateChanged to have + // already been called. I.e. the requestStage should be set. + lazy.logger.error("Unexpected TorProviderInitError"); + this._setProviderState(lazy.TorProviderBuilder.currentState(), false); return; } @@ -1489,14 +1595,27 @@ export const TorConnect = { lazy.logger.warn(`Cannot move to ${stage} when bootstrapped`); return; } + if (!this._providerRunning && stage !== TorConnectStage.ProviderStopped) { + if (!lazy.TorLauncherUtil.isAndroid) { + // TODO: Remove Android exception. + lazy.logger.warn( + `Cannot move to ${stage} when provider is not running` + ); + return; + } + } if (this._stageName === TorConnectStage.Loading) { - if (stage === TorConnectStage.Start) { - // Will transition to "Start" stage when loading completes. - lazy.logger.info("Still in the Loading stage"); + if (stage === TorConnectStage.ProviderStopped) { + lazy.logger.info("Skipping straight from Loading to ProviderStopped"); } else { - lazy.logger.warn(`Cannot move to ${stage} when Loading`); + if (stage === TorConnectStage.Start) { + // Will transition to "Start" stage when loading completes. + lazy.logger.info("Still in the Loading stage"); + } else { + lazy.logger.warn(`Cannot move to ${stage} when Loading`); + } + return; } - return; } if (!this._bootstrapAttempt) { @@ -1519,6 +1638,116 @@ export const TorConnect = { this._bootstrapAttempt?.cancel(); }, + /** + * Called when the current Tor provider's state changes. + * + * @param {string} state - The `TorProviderState` we are now in. + * @param {boolean} initialState - Whether this is the initial provider's + * state. + */ + _setProviderState(state, initialState) { + if (this._providerKnownState === null && !initialState) { + // Wait for `TorProviderBuilder.settled` to return first. + // We stick to the assumed status for the time being. + return; + } + + const wasRunning = this._providerRunning; + const prevState = this._providerState; + this._providerKnownState = state; + + if (prevState === state) { + // No change in state. + // NOTE: If this is the initial state, then `prevState` will be + // `TorProviderState.Running`, in which case this will *not* notify + // consumers if the initial state is also `Running`. + return; + } + + if (this._providerRunning) { + // As soon as we get a provider that is running (has not immediately + // exited), from now on we will no longer *suspect* that a configuration + // issue (conflicting tor process, or a mis-config) *could* cause a tor + // provider to stop. I.e. if we ever re-enter the "Stopped" or "Starting" + // state, `maybeConfigIssue` will remain `false`. + // + // This is because we assume that the browser's established tor process + // can not be killed by the spawning of a new conflicting non-browser tor + // process, and any changes in the configuration (via files or otherwise) + // mid session won't be read by the existing process. + // + // NOTE: In principle, if the browser tor process is killed for some other + // reason, in the interim there is a time period where the configuration + // could change or a new non-browser tor process is spawned that could + // conflict, which may prevent any *new* browser tor process from + // starting. I.e. the cause of failure switches from non-config issue to + // a config issue. However, such a scenario is deemed unlikely, and the + // consequences of not accounting for it are very mild since + // `maybeConfigIssue` is only soft hint for the debugging UI. + this._maybeConfigIssue = false; + if (!wasRunning) { + // Return to the Start stage to re-try a bootstrap. + this._makeStageRequest(TorConnectStage.Start); + } + } else { + if (initialState) { + // This is the first time we learn the provider state. If the first + // provider is not running after initialisation, then we *suspect* that + // there *could* be a conflict with another tor process. E.g. an + // existing tor process is already using the ports we want to use, so + // the browser's tor provider will fail at initialisation. + this._maybeConfigIssue = true; + } + if (wasRunning) { + // Transitioning from the Running state to a non-Running state. + + // Prevent quickstart firing at the next startup until we have another + // successful bootstrap. + Services.prefs.setBoolPref(TorConnectPrefs.prompt_at_startup, true); + // We request the ProviderStopped stage, which may take some time to + // reach if we need to cancel the current bootstrap first. + // But other methods should take into account that _providerRunning is now + // `false` to early return and guarantee that we enter this + // ProviderStopped stage. + if (lazy.TorLauncherUtil.isAndroid) { + // TODO: Remove this Android path when android supports the + // `ProviderStopped` stage. + this._makeStageRequest(TorConnectStage.Start, true); + } else { + this._makeStageRequest(TorConnectStage.ProviderStopped, true); + } + } + } + + const providerStatus = this._providerStatus(); + lazy.logger.debug("New provider status", providerStatus); + Services.obs.notifyObservers( + providerStatus, + TorConnectTopics.ProviderStatusChange + ); + }, + + /** + * Restart the Tor provider after it has stopped. + */ + restartProvider() { + lazy.logger.debug("Request to restart Tor provider"); + this._ensureEnabled(); + + if (this._stageName !== TorConnectStage.ProviderStopped) { + lazy.logger.warn( + `Cannot restart the provider in stage ${this._stageName}` + ); + return; + } + if (this._providerState === lazy.TorProviderState.Starting) { + lazy.logger.warn("Already restarting the Tor provider"); + return; + } + + lazy.TorProviderBuilder.replace(); + }, + /** * Restart the TorConnect stage to the start. */ View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/3867e5… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/3867e5… You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-153.0esr-16.0-1] fixup! [android] Delete unused media
by Dan Ballard (@dan) 28 Jul '26

28 Jul '26
Dan Ballard pushed to branch tor-browser-153.0esr-16.0-1 at The Tor Project / Applications / Tor Browser Commits: 3867e54e by clairehurst at 2026-07-28T13:33:44-06:00 fixup! [android] Delete unused media Bug 44448: P1 trivialize assets - - - - - 63 changed files: - mobile/android/android-components/components/ui/icons/src/main/res/drawable/mozac_ic_logo_firefox_24.xml - mobile/android/fenix/app/src/debug/res/drawable/ic_firefox.xml - mobile/android/fenix/app/src/debug/res/drawable/ic_launcher_foreground.xml - mobile/android/fenix/app/src/main/res/drawable-nodpi/firefox_as_default_banner_illustration.xml - mobile/android/fenix/app/src/main/res/drawable-xxhdpi/firefox_sport.webp - mobile/android/fenix/app/src/main/res/drawable/bookmarks_folder_illustration.xml - mobile/android/fenix/app/src/main/res/drawable/expressive_firefox.xml - mobile/android/fenix/app/src/main/res/drawable/fox_ai_on_state.xml - mobile/android/fenix/app/src/main/res/drawable/fox_alert_crash_dark.xml - mobile/android/fenix/app/src/main/res/drawable/fox_alert_crash_light.xml - mobile/android/fenix/app/src/main/res/drawable/fox_exclamation_alert.xml - mobile/android/fenix/app/src/main/res/drawable/fox_expressive_face_tail.xml - mobile/android/fenix/app/src/main/res/drawable/fox_hand_over_eyes.xml - mobile/android/fenix/app/src/main/res/drawable/fox_sitting_looking_up.xml - mobile/android/fenix/app/src/main/res/drawable/ic_cool.xml - mobile/android/fenix/app/src/main/res/drawable/ic_cuddling.xml - mobile/android/fenix/app/src/main/res/drawable/ic_flaming.xml - mobile/android/fenix/app/src/main/res/drawable/ic_high_five.xml - mobile/android/fenix/app/src/main/res/drawable/ic_japan_onboarding_favicon.webp - mobile/android/fenix/app/src/main/res/drawable/ic_kit_bookmarks_empty_state.xml - mobile/android/fenix/app/src/main/res/drawable/ic_kit_heart.xml - mobile/android/fenix/app/src/main/res/drawable/ic_kit_shield_off_state.xml - mobile/android/fenix/app/src/main/res/drawable/ic_kit_shield_on_state.xml - mobile/android/fenix/app/src/main/res/drawable/ic_launcher_foreground_cool.xml - mobile/android/fenix/app/src/main/res/drawable/ic_launcher_foreground_cuddling.xml - mobile/android/fenix/app/src/main/res/drawable/ic_launcher_foreground_flaming.xml - mobile/android/fenix/app/src/main/res/drawable/ic_launcher_foreground_minimal.xml - mobile/android/fenix/app/src/main/res/drawable/ic_launcher_foreground_momo.xml - mobile/android/fenix/app/src/main/res/drawable/ic_launcher_foreground_pixelated.xml - mobile/android/fenix/app/src/main/res/drawable/ic_launcher_foreground_pride.xml - mobile/android/fenix/app/src/main/res/drawable/ic_launcher_foreground_retro_2004.xml - mobile/android/fenix/app/src/main/res/drawable/ic_launcher_monochrome.xml - mobile/android/fenix/app/src/main/res/drawable/ic_minimal.xml - mobile/android/fenix/app/src/main/res/drawable/ic_momo.xml - mobile/android/fenix/app/src/main/res/drawable/ic_pixelated.xml - mobile/android/fenix/app/src/main/res/drawable/ic_pride.xml - mobile/android/fenix/app/src/main/res/drawable/ic_retro_2004.xml - mobile/android/fenix/app/src/main/res/drawable/ic_wordmark_sport_logo.webp - mobile/android/fenix/app/src/main/res/drawable/ic_wordmark_text_normal.xml - mobile/android/fenix/app/src/main/res/drawable/ic_wordmark_text_private.xml - mobile/android/fenix/app/src/main/res/drawable/illustration_fox_box_inside_light.xml - mobile/android/fenix/app/src/main/res/drawable/kit_expressive_full.xml - mobile/android/fenix/app/src/main/res/drawable/kit_head_protection_blocker_banner.xml - mobile/android/fenix/app/src/main/res/drawable/kit_sleeping_under_laptop.webp - mobile/android/fenix/app/src/main/res/drawable/mozac_ic_kit_tab_groups.xml - mobile/android/fenix/app/src/main/res/drawable/mozac_ic_kit_tab_groups_list_view.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_marketing.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_notifications.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_set_to_default.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_sync.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_sync_qr.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_toolbar_bottom_active.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_toolbar_bottom_inactive.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_toolbar_top_active.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_toolbar_top_inactive.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_tou.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_tou_2.xml - mobile/android/fenix/app/src/main/res/drawable/nova_onboarding_widget.xml - mobile/android/fenix/app/src/main/res/drawable/protection_panel_not_protected.xml - mobile/android/fenix/app/src/main/res/drawable/protection_panel_not_secure.xml - mobile/android/fenix/app/src/main/res/drawable/review_prompt_negative_button.xml - mobile/android/fenix/app/src/main/res/drawable/review_prompt_positive_button.xml - mobile/android/fenix/app/src/main/res/drawable/sports_widget_celebration.xml The diff was not included because it is too large. View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/3867e54… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/3867e54… You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-153.0esr-16.0-1] fixup! TB 40015: [android] Port padlock states for .onion services
by Dan Ballard (@dan) 28 Jul '26

28 Jul '26
Dan Ballard pushed to branch tor-browser-153.0esr-16.0-1 at The Tor Project / Applications / Tor Browser Commits: 323fa639 by clairehurst at 2026-07-28T12:28:57-07:00 fixup! TB 40015: [android] Port padlock states for .onion services Bug 45115: Fix site security icon for new toolbar - - - - - 1 changed file: - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt Changes: ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddleware.kt ===================================== @@ -76,6 +76,7 @@ import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.ktx.kotlin.applyRegistrableDomainSpan import mozilla.components.support.ktx.kotlin.getOrigin import mozilla.components.support.ktx.kotlin.isContentUrl +import mozilla.components.support.ktx.kotlin.isOnionUrl import mozilla.components.support.ktx.kotlin.isUrl import mozilla.components.support.ktx.util.URLStringUtils import mozilla.components.support.utils.ClipboardHandler @@ -1273,19 +1274,26 @@ class BrowserToolbarMiddleware( onClick = object : BrowserToolbarEvent {}, ) } else if ( - selectedTab.content.securityInfo.isSecure && - selectedTab.trackingProtection.enabled && - !selectedTab.trackingProtection.ignoredOnTrackingProtection + selectedTab.content.securityInfo.isSecure ) { - buildSiteInfoAction( - drawableResId = iconsR.drawable.mozac_ic_shield_checkmark_24, - contentDescription = toolbarR.string.mozac_browser_toolbar_content_description_site_info, - highlighted = highlight, - onClick = StartPageActions.SiteInfoClicked, - ) + if (selectedTab.content.url.isOnionUrl()) { + buildSiteInfoAction( + drawableResId = iconsR.drawable.mozac_ic_onion, + contentDescription = toolbarR.string.mozac_browser_toolbar_content_description_site_info, + highlighted = highlight, + onClick = StartPageActions.SiteInfoClicked, + ) + } else { + buildSiteInfoAction( + drawableResId = iconsR.drawable.mozac_ic_lock_24, + contentDescription = toolbarR.string.mozac_browser_toolbar_content_description_site_info, + highlighted = highlight, + onClick = StartPageActions.SiteInfoClicked, + ) + } } else { buildSiteInfoAction( - drawableResId = iconsR.drawable.mozac_ic_shield_slash_24, + drawableResId = iconsR.drawable.mozac_ic_lock_slash_critical_24, contentDescription = toolbarR.string.mozac_browser_toolbar_content_description_site_info, highlighted = highlight, onClick = StartPageActions.SiteInfoClicked, View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/323fa63… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/323fa63… You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1 0
0 0
[Git][tpo/applications/tor-browser-build][main] Bug 41711: Update our manual machinery for its new home
by boklm (@boklm) 28 Jul '26

28 Jul '26
boklm pushed to branch main at The Tor Project / Applications / tor-browser-build Commits: 8b8abf69 by Nicolas Vigier at 2026-07-28T13:41:58+02:00 Bug 41711: Update our manual machinery for its new home - - - - - 7 changed files: - doc/how-to-update-the-manual.txt - projects/browser/build - projects/manual/README.md - projects/manual/build - projects/manual/config - − projects/manual/packagemanual.py - tools/update_manual.py Changes: ===================================== doc/how-to-update-the-manual.txt ===================================== @@ -1,9 +1,3 @@ -1. Go to https://gitlab.torproject.org/tpo/web/manual/-/jobs/ -2. Open the latest build stage -3. Download the artifacts (they come in a .zip file). -4. Rename it to manual_$PIPELINEID.zip -5. Upload it to people.tpo -6. Update projects/manual/config - 6.1 Change the version to $PIPELINEID - 6.2 Update the hash in the input_files section - 6.3 Update the URL if it was different from the previous uploader +1. Run ./tools/update_manual.py +2. Upload the new file to tb-build-02.torproject.org:~tb-builder/public_html/ +3. Commit the changes made by the script to projects/manual/config ===================================== projects/browser/build ===================================== @@ -184,7 +184,7 @@ tar -C "${TB_STAGE_DIR}" -xf [% c('input_files_by_name/firefox') %]/browser.tar. find . -exec [% c("touch") %] {} \; for tbdir in "${TBDIRS[@]}" do - find chrome/ | sort | zip -X -@ "$tbdir[% IF c('var/macos') %]/Contents/Resources[% END %]/browser/omni.ja" + find chrome/ defaults/preferences/tor-browser-manual.js | sort | zip -X -@ "$tbdir[% IF c('var/macos') %]/Contents/Resources[% END %]/browser/omni.ja" done popd rm -rf $TMP_MANUAL_PATH ===================================== projects/manual/README.md ===================================== @@ -10,7 +10,11 @@ So, since the manual doesn't contain binary executables, we decided not to build it, but to mirror the latest result of the CI to make sure a build stays reproducible (otherwise, CI artifacts would be deleted after a week). -However, the CI artifacts include a lot of files used by other Tor sites but not -from the manual, so we delete them in our build script to save space in the -builds. Also, the paths to resources need to be updated, because we serve the -manual as an about page, so we need to convert them to full `chrome://` URIs. +The download of the latest CI artifacts can be done by the script +`tools/update_manual.py`. + +However, the CI artifacts include a lot of files used by other Tor sites +but not from the manual, so they need to be deleted, and some of the +files need to be adapted for offline use. This is done by the script +`package_marble_build_artifacts.py` (which has tests in +`test_package_marble_build_artifacts.py`). ===================================== projects/manual/build ===================================== @@ -1,19 +1,26 @@ #!/bin/bash [% c("var/set_default_env") -%] -mkdir -p chrome/browser/content/browser/manual -unzip $rootdir/[% c('input_files_by_name/manual') %] -python3 $rootdir/[% c('input_files_by_name/package_script') %] public chrome/browser/content/browser/manual +manual_dir='chrome/browser/content/browser/aboutmanual' +mkdir -p "$manual_dir" manual-src +unzip -d manual-src $rootdir/[% c('input_files_by_name/manual') %] +python3 $rootdir/[% c('input_files_by_name/package_script') %] \ + --in-dir manual-src/public --out-dir "$manual_dir" \ + --out-locales "$rootdir/supported-locales.txt" -pushd chrome/browser/content/browser/manual/static -find -name '*.map' -delete -rm -rf fonts -rm -rf css/digital-climate-strike css/images -# We prune unused images in the Python script, but empty directories remain -find images -type d -empty -delete -popd +# Check for the expected characters, which will also ensure this can +# form a valid javascript string literal. +# Note that $() will strip any trailing newlines, if any. +supported_locales="$(cat "$rootdir/supported-locales.txt")" +if [[ ! "$supported_locales" =~ ^[a-zA-Z,-]*$ ]]; then + echo 'Error: unexpected characters in supported-locales.txt' >&2 + exit 1 +fi + +mkdir -p defaults/preferences +echo 'pref("torbrowser.manual.available-locales", "'"$supported_locales"'");' > defaults/preferences/tor-browser-manual.js [% c('tar', { - tar_src => [ 'chrome' ], + tar_src => [ 'chrome', 'defaults' ], tar_args => '-caf ' _ dest_dir _ '/' _ c('filename'), }) %] ===================================== projects/manual/config ===================================== @@ -1,7 +1,7 @@ # vim: filetype=yaml sw=2 # To update, see doc/how-to-update-the-manual.txt # Remember to update also the package's hash, with the version! -version: 321660 +version: 402523 filename: 'manual-[% c("version") %]-[% c("var/build_id") %].tar.[% c("compress_tar") %]' container: use_container: 1 @@ -21,8 +21,8 @@ var: input_files: - project: container-image - - URL: 'https://build-sources.tbb.torproject.org/manual_[% c("version") %].zip' + - URL: 'https://build-sources.tbb.torproject.org/marble-support_[% c("version") %].zip' name: manual - sha256sum: 9adb7d8ca2c9cb7dbd8d13d46135ea9f42636eafd053192fc5e233f2426cd8a3 - - filename: packagemanual.py + sha256sum: e0f09c869719bf9dc0ae2761f121cae7cd9b5324f817f2cc0a5861c58442f3ff + - filename: package_marble_build_artifacts.py name: package_script ===================================== projects/manual/packagemanual.py deleted ===================================== @@ -1,69 +0,0 @@ -#!/usr/bin/env python3 -from pathlib import Path -import re -import sys -import shutil - - -PAGE_NAME = 'offline-docs' -STATIC_PATH = 'chrome://browser/content/manual/static' - -if len(sys.argv) < 3: - print(f'Usage: {sys.argv[0]} lektor-out-directory target-directory') - sys.exit(1) - -source = Path(sys.argv[1]) -target = Path(sys.argv[2]) -if not target.exists(): - target.mkdir(exist_ok=True) - -static_re = re.compile('"(?:../)*static/([^"]+)"') -link_re = re.compile('href="../([^"]+)"') - - -def clean_urls(match): - m = re.match(r'(?:../)?([^/#]+)[/]?[#]?(.*)', match.group(1)) - slug = m.group(1) - if m.group(2): - anchor = '_' + m.group(2) - else: - anchor = '' - return f'href="#{slug}{anchor}"' - - -remove_images = [] -for p in (source / 'static/images').glob('**/*'): - if p.is_file(): - rel = p.relative_to(source) - remove_images.append(rel) - -htmls = source.rglob(f'{PAGE_NAME}/index.html') -for page in htmls: - with page.open(encoding='utf8') as f: - contents = f.read() - - remove_images = list(filter( - lambda im: contents.find(str(im)) == -1, remove_images)) - - contents = static_re.sub(f'"{STATIC_PATH}/\\1"', contents) - contents = link_re.sub(clean_urls, contents) - - rel = page.relative_to(source) - dest_name = str(list(rel.parents)[-2].name) - if dest_name == PAGE_NAME: - dest_name = 'en' - dest_name += '.html' - with (target / dest_name).open('w', encoding='utf8') as f: - f.write(contents) - - -def ignore_images(path, names): - return [ - n - for n in names - if Path(path, n).relative_to(source) in remove_images - ] - - -shutil.rmtree(target / 'static', ignore_errors=True) -shutil.copytree(source / 'static', target / 'static', ignore=ignore_images) ===================================== tools/update_manual.py ===================================== @@ -10,7 +10,7 @@ from fetch_changelogs import load_token, AUTH_HEADER GITLAB = "https://gitlab.torproject.org" API_URL = f"{GITLAB}/api/v4" -PROJECT_ID = 23 +PROJECT_ID = 3354 REF_NAME = "main" @@ -66,7 +66,7 @@ def update_manual(auth_token, base_path): raise RuntimeError("No usable job found") pipeline_id = int(job["pipeline"]["id"]) - manual_fname = f"manual_{pipeline_id}.zip" + manual_fname = f"marble-support_{pipeline_id}.zip" url = f"https://build-sources.tbb.torproject.org/{manual_fname}" r = requests.head(url) needs_upload = r.status_code != 200 View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/8… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/8… You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-153.0esr-16.0-1] 6 commits: fixup! TB 44694: [android] Remove new Tab bar feature
by brizental (@brizental) 28 Jul '26

28 Jul '26
brizental pushed to branch tor-browser-153.0esr-16.0-1 at The Tor Project / Applications / Tor Browser Commits: eac41a90 by Beatriz Rizental at 2026-07-28T16:18:31+02:00 fixup! TB 44694: [android] Remove new Tab bar feature Bug 45147: Enable android unit test builds. - - - - - 94f970fe by Beatriz Rizental at 2026-07-28T16:18:31+02:00 fixup! TB 44098: [android] Disable sync Bug 45147: Enable android unit test builds. - - - - - 5202d68f by Beatriz Rizental at 2026-07-28T16:18:31+02:00 fixup! TB 42655: [android] Implement "New circuit for this site" on Android Bug 45147: Enable android unit test builds. - - - - - de1a09f1 by Beatriz Rizental at 2026-07-28T16:18:31+02:00 fixup! [android] Disable features and functionality Bug 45147: Enable android unit test builds. - - - - - 092ce022 by Beatriz Rizental at 2026-07-28T16:18:31+02:00 fixup! [android] Delete unused media Bug 45147: Enable android unit test builds. - - - - - a054fea8 by Beatriz Rizental at 2026-07-28T16:18:31+02:00 fixup! [android] Modify UI/UX Bug 45147: Enable android unit test builds. - - - - - 7 changed files: - mobile/android/fenix/app/src/test/java/org/mozilla/fenix/bookmarks/BookmarksMiddlewareTest.kt - mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/menu/compose/MainMenuTest.kt - mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/metrics/MetricsUtilsTest.kt - mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddlewareTest.kt - mobile/android/fenix/app/src/test/java/org/mozilla/fenix/home/setup/store/ChecklistItemTest.kt - mobile/android/fenix/app/src/test/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/DefaultCookieBannerDetailsControllerTest.kt - mobile/android/fenix/app/src/test/java/org/mozilla/fenix/tabstray/TabManagerCfrControllerTest.kt Changes: ===================================== mobile/android/fenix/app/src/test/java/org/mozilla/fenix/bookmarks/BookmarksMiddlewareTest.kt ===================================== @@ -1230,31 +1230,8 @@ class BookmarksMiddlewareTest { assertFalse(exited) } - @Test - fun `GIVEN current screen is an empty list and the top-level is loaded WHEN sign into sync is clicked THEN navigate to sign into sync `() = - runTest { - coEvery { - bookmarksStorage.countBookmarksInTrees( - listOf( - BookmarkRoot.Menu.id, - BookmarkRoot.Toolbar.id, - BookmarkRoot.Unfiled.id, - ), - ) - } returns 0u - coEvery { bookmarksStorage.getTree(BookmarkRoot.Mobile.id) } returns Result.success( - generateBookmarkTree(), - ) - var navigated = false - navigateToSignIntoSync = { navigated = true } - val middleware = buildMiddleware(this) - val store = middleware.makeStore() - testScheduler.advanceUntilIdle() - - store.dispatch(SignIntoSyncClicked) - - assertTrue(navigated) - } + // tor-browser#44098: sign-into-sync from bookmarks was removed, along with the + // SignIntoSyncClicked action this test used to dispatch. @Test fun `GIVEN current screen is a subfolder WHEN close is clicked THEN exit bookmarks `() = ===================================== mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/menu/compose/MainMenuTest.kt ===================================== @@ -94,6 +94,7 @@ class MainMenuTest { onIPProtectionClick = {}, onIPProtectionNavigate = {}, onShareButtonClick = {}, + onNewCircuitButtonClick = {}, extensionsMenuItemDescription = null, moreSettingsSubmenu = {}, extensionSubmenu = {}, ===================================== mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/metrics/MetricsUtilsTest.kt ===================================== @@ -4,7 +4,6 @@ package org.mozilla.fenix.components.metrics -import com.google.android.gms.ads.identifier.AdvertisingIdClient import com.google.android.gms.common.GooglePlayServicesNotAvailableException import com.google.android.gms.common.GooglePlayServicesRepairableException import io.mockk.every @@ -13,6 +12,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.Assert.assertNull +import org.junit.Ignore import org.junit.Test import java.io.IOException @@ -34,21 +34,18 @@ class MetricsUtilsTest { @Test fun `getAdvertisingID() returns null if the API returns null info`() { - val mockInfo: AdvertisingIdClient.Info = mockk() - every { mockInfo.id } returns null - - assertNull(MetricsUtils.getAdvertisingID { mockInfo.id }) + assertNull(MetricsUtils.getAdvertisingID { null }) } + @Ignore("tor-browser#40014: the Google Advertising ID is neutered, so getAdvertisingID() always returns null") @Test fun `getAdvertisingID() returns a valid string if the API returns a valid ID`() { val testId = "test-value-id" - val mockInfo: AdvertisingIdClient.Info = mockk() - every { mockInfo.id } returns testId - assertEquals(testId, MetricsUtils.getAdvertisingID({ mockInfo.id })) + assertEquals(testId, MetricsUtils.getAdvertisingID({ testId })) } + @Ignore("tor-browser#40014: getHashedIdentifier() derives from getAdvertisingID(), which always returns null") @Test fun `getHashedIdentifier() returns a hashed identifier`() = runTest { val testId = "test-value-id" ===================================== mobile/android/fenix/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMiddlewareTest.kt ===================================== @@ -224,7 +224,7 @@ class BrowserToolbarMiddlewareTest { coEvery { bookmarksStorage.getBookmarksWithUrl(any()) } returns Result.success(listOf(mockk())) settings.shouldUseBottomToolbar = false settings.shouldUseExpandedToolbar = false - settings.isTabStripEnabled = false + // settings.isTabStripEnabled = false } @Test @@ -1266,7 +1266,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN on a small screen with tabstrip is disabled and not using the extended layout THEN don't show a share button as page end action`() { - settings.isTabStripEnabled = false + // settings.isTabStripEnabled = false settings.shouldUseExpandedToolbar = false val browserScreenStore = buildBrowserScreenStore() @@ -1278,7 +1278,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN on a wide screen with tabstrip is disabled THEN show a share button as page end action`() { - settings.isTabStripEnabled = false + // settings.isTabStripEnabled = false val browserScreenStore = buildBrowserScreenStore() val middleware = buildMiddleware( browserScreenStore = browserScreenStore, @@ -1292,7 +1292,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN on a large screen with tabstrip is enabled THEN don't show a share button as page end action`() { - settings.isTabStripEnabled = true + // settings.isTabStripEnabled = true val browserScreenStore = buildBrowserScreenStore() val middleware = buildMiddleware(appStore, browserScreenStore) val toolbarStore = buildStore(middleware) @@ -1302,7 +1302,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN the current tab shows a content page WHEN the share shortcut is clicked THEN record telemetry and start sharing the local resource`() = runTest(testDispatcher) { - settings.isTabStripEnabled = true + // settings.isTabStripEnabled = true settings.shouldUseExpandedToolbar = false settings.toolbarSimpleShortcutKey = ShortcutType.SHARE.value val browserScreenStore = buildBrowserScreenStore() @@ -1337,7 +1337,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN the current tab shows a remote PDF WHEN the share shortcut is clicked THEN record telemetry and start sharing the remote resource`() { - settings.isTabStripEnabled = true + // settings.isTabStripEnabled = true settings.shouldUseExpandedToolbar = false settings.toolbarSimpleShortcutKey = ShortcutType.SHARE.value val browserScreenStore = buildBrowserScreenStore() @@ -1382,7 +1382,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN the current tab shows a normal webpage WHEN the share shortcut is clicked THEN record telemetry and open the share dialog`() { - settings.isTabStripEnabled = true + // settings.isTabStripEnabled = true settings.shouldUseExpandedToolbar = false settings.toolbarSimpleShortcutKey = ShortcutType.SHARE.value settings.nativeShareSheetEnabled = false @@ -1430,7 +1430,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `WHEN the share shortcut is clicked THEN the share use case is invoked with the current tab's details`() { - settings.isTabStripEnabled = true + // settings.isTabStripEnabled = true settings.shouldUseExpandedToolbar = false settings.toolbarSimpleShortcutKey = ShortcutType.SHARE.value @@ -1471,7 +1471,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN on a small width with tabstrip is enabled and not using the extended layout THEN don't show a share button as browser end action`() { settings.shouldUseExpandedToolbar = false - settings.isTabStripEnabled = true + // settings.isTabStripEnabled = true val browserScreenStore = buildBrowserScreenStore() val middleware = buildMiddleware( browserScreenStore = browserScreenStore, @@ -1491,7 +1491,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN expanded toolbar with tabstrip and tall window WHEN changing to short window THEN show new tab, tab counter and menu`() = runTest(testDispatcher) { - settings.isTabStripEnabled = true + // settings.isTabStripEnabled = true settings.shouldUseExpandedToolbar = true val browserScreenStore = buildBrowserScreenStore() var isWideScreen = false @@ -1526,7 +1526,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN on a wide window with tabstrip and extended layout enabled THEN don't show a share button as browser end action`() { - settings.isTabStripEnabled = true + // settings.isTabStripEnabled = true settings.shouldUseExpandedToolbar = true val browserScreenStore = buildBrowserScreenStore() @@ -1539,7 +1539,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `WHEN cycling through tall window and wide window THEN update what end page actions should be shown`() { val appStore = AppStore() - settings.isTabStripEnabled = false + // settings.isTabStripEnabled = false settings.shouldUseExpandedToolbar = false val readerModeStatus: ReaderModeStatus = mockk(relaxed = true) { every { isAvailable } returns true @@ -3156,7 +3156,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN share shortcut is selected THEN update end page actions without share action`() = runTest(testDispatcher) { - settings.isTabStripEnabled = false + // settings.isTabStripEnabled = false settings.toolbarSimpleShortcutKey = ShortcutType.SHARE.value val browserScreenStore = buildBrowserScreenStore() val middleware = buildMiddleware( @@ -3353,7 +3353,7 @@ class BrowserToolbarMiddlewareTest { @Test fun `GIVEN simple toolbar use share shortcut AND wide window with tabstrip enabled WHEN initializing toolbar THEN only show one Share in end browser actions`() { - settings.isTabStripEnabled = true + // settings.isTabStripEnabled = true settings.toolbarSimpleShortcutKey = ShortcutType.SHARE.value val middleware = buildMiddleware( ===================================== mobile/android/fenix/app/src/test/java/org/mozilla/fenix/home/setup/store/ChecklistItemTest.kt ===================================== @@ -7,6 +7,7 @@ package org.mozilla.fenix.home.setup.store import androidx.annotation.StringRes import io.mockk.every import io.mockk.mockk +import mozilla.components.lib.crash.R as crashR import org.junit.Assert.assertEquals import org.junit.Test import org.mozilla.fenix.R @@ -149,7 +150,7 @@ class ChecklistItemTest { ChecklistItem.Task( type = ChecklistItem.Task.Type.SIGN_IN, title = R.string.setup_checklist_task_account_sync, - icon = R.drawable.ic_fx_accounts_avatar, + icon = crashR.drawable.mozac_lib_crash_notification, isCompleted = isCompleted, ), ) @@ -185,7 +186,7 @@ class ChecklistItemTest { ChecklistItem.Task( type = ChecklistItem.Task.Type.SIGN_IN, title = R.string.setup_checklist_task_account_sync, - icon = R.drawable.ic_fx_accounts_avatar, + icon = crashR.drawable.mozac_lib_crash_notification, isCompleted = isCompleted, ), ), @@ -258,7 +259,7 @@ class ChecklistItemTest { ChecklistItem.Task( type = ChecklistItem.Task.Type.SIGN_IN, title = R.string.setup_checklist_task_account_sync, - icon = R.drawable.ic_fx_accounts_avatar, + icon = crashR.drawable.mozac_lib_crash_notification, isCompleted = isCompleted, ), ), ===================================== mobile/android/fenix/app/src/test/java/org/mozilla/fenix/settings/quicksettings/protections/cookiebanners/DefaultCookieBannerDetailsControllerTest.kt ===================================== @@ -220,46 +220,7 @@ internal class DefaultCookieBannerDetailsControllerTest { } } - @Test - fun `GIVEN cookie banner mode is site not supported WHEN handleRequestSiteSupportPressed THEN request report site domain`() = - runTest(testDispatcher) { - val store = BrowserStore( - BrowserState( - customTabs = listOf( - createCustomTab( - url = "https://www.mozilla.org", - id = "mozilla", - ), - ), - ), - ) - every { testContext.components.core.store } returns store - coEvery { controller.getTabDomain(any()) } returns "mozilla.org" - every { protectionsStore.dispatch(any()) } returns mockk() - - val job = Pings.cookieBannerReportSite.testBeforeNextSubmit { - assertNotNull(CookieBanners.reportSiteDomain.testGetValue()) - assertEquals("mozilla.org", CookieBanners.reportSiteDomain.testGetValue()) - } - controller.handleRequestSiteSupportPressed() - testScheduler.advanceUntilIdle() - - job.join() - - assertNotNull(CookieBanners.reportDomainSiteButton.testGetValue()) - testScheduler.advanceUntilIdle() - coVerifyOrder { - protectionsStore.dispatch( - ProtectionsAction.RequestReportSiteDomain( - "mozilla.org", - ), - ) - protectionsStore.dispatch( - ProtectionsAction.UpdateCookieBannerMode( - cookieBannerUIMode = CookieBannerUIMode.REQUEST_UNSUPPORTED_SITE_SUBMITTED, - ), - ) - cookieBannersStorage.saveSiteDomain("mozilla.org") - } - } + // tor-browser#42089: the ability to submit site support requests was removed, along with + // handleRequestSiteSupportPressed(), ProtectionsAction.RequestReportSiteDomain and + // CookieBannerUIMode.REQUEST_UNSUPPORTED_SITE_SUBMITTED this test used to exercise. } ===================================== mobile/android/fenix/app/src/test/java/org/mozilla/fenix/tabstray/TabManagerCfrControllerTest.kt ===================================== @@ -100,7 +100,7 @@ class TabManagerCfrControllerTest { @Test fun `GIVEN an adjacent tab WHEN maybeMarkTabSwipeCfrReady is called THEN shouldShowTabSwipeCfr is set`() { settings.hasShownTabSwipeCFR = false - settings.isTabStripEnabled = false + // settings.isTabStripEnabled = false settings.isSwipeToolbarToSwitchTabsEnabled = true settings.shouldShowTabSwipeCFR = false val adjacentTab = createTab(id = "tab2", url = "") View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/51b776… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/51b776… You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1 0
0 0
[Git][tpo/applications/mullvad-browser][mullvad-browser-153.0esr-16.0-1] BB 45085: [android] Confine GooglePlayIntegrityClient to Components.kt
by brizental (@brizental) 28 Jul '26

28 Jul '26
brizental pushed to branch mullvad-browser-153.0esr-16.0-1 at The Tor Project / Applications / Mullvad Browser Commits: 7e4d093f by Beatriz Rizental at 2026-07-28T11:20:40-03:00 BB 45085: [android] Confine GooglePlayIntegrityClient to Components.kt Uplifting: https://phabricator.services.mozilla.com/D313912 - - - - - 4 changed files: - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/ClientUUID.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/llm/Llm.kt Changes: ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt ===================================== @@ -583,7 +583,7 @@ open class FenixApplication : Application(), Provider, ThemeProvider { } runOnVisualCompleteness(queue) { GlobalScope.launch(IO) { - components.integrityClient.warmUp() + components.warmUpIntegrityClient() } } } ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/ClientUUID.kt ===================================== @@ -7,7 +7,6 @@ package org.mozilla.fenix.components import android.content.Context import android.content.SharedPreferences import androidx.core.content.edit -import mozilla.components.lib.integrity.googleplay.RequestHashProvider import mozilla.components.lib.llm.mlpa.UserIdProvider import mozilla.components.lib.llm.mlpa.service.UserId import mozilla.components.support.ktx.kotlin.toHexString @@ -39,9 +38,15 @@ fun interface Hasher { /** * Generates and persists a stable per-install UUID, used to identify this client - * consistently across [UserIdProvider] and [RequestHashProvider] consumers. + * consistently across [UserIdProvider] consumers and other callers that need a + * stable per-request hash derived from that UUID. */ -interface ClientUUID : UserIdProvider, RequestHashProvider { +interface ClientUUID : UserIdProvider { + /** + * Generates a hash derived from the client's stable UUID. + */ + fun generateHash(): String + companion object { /** * Convenience initializer that creates a [SharedPreferences] to be used by [ClientUUID]. ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt ===================================== @@ -19,6 +19,7 @@ import kotlinx.coroutines.MainScope import kotlinx.coroutines.SupervisorJob import mozilla.components.concept.ai.controls.AIFeatureBlock import mozilla.components.concept.ai.controls.AIFeatureRegistry +import mozilla.components.concept.integrity.IntegrityClient import mozilla.components.feature.addons.AddonManager import mozilla.components.feature.addons.amo.AMOAddonsProvider import mozilla.components.feature.addons.migration.DefaultSupportedAddonsChecker @@ -32,6 +33,8 @@ import mozilla.components.lib.ai.controls.default import mozilla.components.lib.crash.store.CrashAction import mozilla.components.lib.crash.store.CrashMiddleware import mozilla.components.lib.integrity.googleplay.GooglePlayIntegrityClient +import mozilla.components.lib.integrity.googleplay.IntegrityConsumer +import mozilla.components.lib.integrity.googleplay.RequestHashProvider import mozilla.components.lib.llm.mlpa.MlpaTokenStorage import mozilla.components.lib.publicsuffixlist.PublicSuffixList import mozilla.components.service.fxrelay.eligibility.RelayEligibilityStore @@ -434,14 +437,25 @@ class Components(private val context: Context) { ) } - val integrityClient by lazyMonitored { + private val googlePlayIntegrityClient by lazyMonitored { GooglePlayIntegrityClient.create( context = context, projectNumberToken = BuildConfig.GPS_INTEGRITY_TOKEN, - requestHashProvider = clientUUID, + requestHashProvider = RequestHashProvider { clientUUID.generateHash() }, ) } + val integrityClient: IntegrityClient by lazyMonitored { + googlePlayIntegrityClient.forConsumer(IntegrityConsumer.Summarize) + } + + /** + * Eagerly initializes the underlying Play Integrity token provider. This is exposed + * separately from [integrityClient] because warm-up is specific to the Google + * Play-backed implementation and isn't part of the [IntegrityClient] concept. + */ + suspend fun warmUpIntegrityClient(): Boolean = googlePlayIntegrityClient.warmUp() + val termsOfUsePromptRepository by lazyMonitored { DefaultTermsOfUsePromptRepository(settings) } ===================================== mobile/android/fenix/app/src/main/java/org/mozilla/fenix/components/llm/Llm.kt ===================================== @@ -5,8 +5,7 @@ package org.mozilla.fenix.components.llm import mozilla.components.concept.fetch.Client -import mozilla.components.lib.integrity.googleplay.GooglePlayIntegrityClient -import mozilla.components.lib.integrity.googleplay.IntegrityConsumer +import mozilla.components.concept.integrity.IntegrityClient import mozilla.components.lib.llm.mlpa.MlpaLlmProvider import mozilla.components.lib.llm.mlpa.MlpaTokenProvider import mozilla.components.lib.llm.mlpa.MlpaTokenStorage @@ -25,7 +24,7 @@ class Llm( private val client: Client, private val storage: MlpaTokenStorage, private val fxaTokenProvider: FxaAccessTokenProvider, - private val integrityClient: GooglePlayIntegrityClient, + private val integrityClient: IntegrityClient, private val userIdProvider: UserIdProvider, ) { @@ -36,7 +35,7 @@ class Llm( MlpaTokenProvider.choose( MlpaTokenProvider.fxaTokenProvider(fxaTokenProvider), MlpaTokenProvider.mlpaIntegrityHandshake( - integrityClient = integrityClient.forConsumer(IntegrityConsumer.Summarize), + integrityClient = integrityClient, authenticationService = fenixMlpaService, userIdProvider = userIdProvider, storage = storage, View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/7e4… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/7e4… You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1 0
0 0
[Git][tpo/applications/mullvad-browser][mullvad-browser-153.0esr-16.0-1] BB 44908: Do not read AutoConfig from /etc/firefox when --disable-system-preferences
by brizental (@brizental) 28 Jul '26

28 Jul '26
brizental pushed to branch mullvad-browser-153.0esr-16.0-1 at The Tor Project / Applications / Mullvad Browser Commits: 16c34621 by Beatriz Rizental at 2026-07-28T11:19:42-03:00 BB 44908: Do not read AutoConfig from /etc/firefox when --disable-system-preferences Uplifting: https://phabricator.services.mozilla.com/D314532 - - - - - 1 changed file: - extensions/pref/autoconfig/src/nsReadConfig.cpp Changes: ===================================== extensions/pref/autoconfig/src/nsReadConfig.cpp ===================================== @@ -243,7 +243,7 @@ nsresult nsReadConfig::openAndEvaluateJSFile(const char* aFileName, nsCOMPtr<nsIInputStream> inStr; if (isBinDir) { nsCOMPtr<nsIFile> jsFile; -#if defined(MOZ_WIDGET_GTK) +#if defined(MOZ_WIDGET_GTK) && defined(MOZ_SYSTEM_PREFERENCES) bool exists; rv = @@ -257,15 +257,15 @@ nsresult nsReadConfig::openAndEvaluateJSFile(const char* aFileName, if (NS_FAILED(rv)) return rv; if (!exists) { -#endif // defined(MOZ_WIDGET_GTK) +#endif // defined(MOZ_WIDGET_GTK) && defined(MOZ_SYSTEM_PREFERENCES) rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(jsFile)); if (NS_FAILED(rv)) return rv; rv = jsFile->AppendNative(nsDependentCString(aFileName)); if (NS_FAILED(rv)) return rv; -#if defined(MOZ_WIDGET_GTK) +#if defined(MOZ_WIDGET_GTK) && defined(MOZ_SYSTEM_PREFERENCES) } -#endif // defined(MOZ_WIDGET_GTK) +#endif // defined(MOZ_WIDGET_GTK) && defined(MOZ_SYSTEM_PREFERENCES) rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), jsFile); if (NS_FAILED(rv)) return rv; View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/16c… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/16c… You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
1 0
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • 5
  • ...
  • 16
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.