tor-commits
Threads by month
- ----- 2026 -----
- September
- 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
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 215750 discussions
[Git][tpo/applications/mullvad-browser][mullvad-browser-153.1.0esr-16.0-1] 5 commits: Bug 1842361 - Download confirmation notification can be overlaid over other...
by ma1 (@ma1) 17 Aug '26
by ma1 (@ma1) 17 Aug '26
17 Aug '26
ma1 pushed to branch mullvad-browser-153.1.0esr-16.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
afa215f6 by giorga at 2026-08-17T17:44:13+02:00
Bug 1842361 - Download confirmation notification can be overlaid over other origins. r=android-reviewers,jdelorenzo
Differential Revision: https://phabricator.services.mozilla.com/D309062
- - - - -
3f028fb0 by Marcin Koziński at 2026-08-17T17:44:14+02:00
Bug 1978587 - Forward onEnterAnimationComplete to interested fragments r=android-reviewers,twhite
Differential Revision: https://phabricator.services.mozilla.com/D306954
- - - - -
dda99725 by Marcin Koziński at 2026-08-17T17:44:14+02:00
Bug 2049034 - Add an initial delay to download button in Fenix download dialog a=pascalc
Original Revision: https://phabricator.services.mozilla.com/D309334
Differential Revision: https://phabricator.services.mozilla.com/D310049
- - - - -
287fd32c by Jamie Nicol at 2026-08-17T17:44:15+02:00
Bug 2049810 - Allocate HardwareBuffer for screen pixels request in parent process. r=gfx-reviewers,lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D308519
- - - - -
3468dc6e by owlishDeveloper at 2026-08-17T17:44:16+02:00
Bug 2055683 - IPC improvement a=pascalc
Original Revision: https://phabricator.services.mozilla.com/D314463
Differential Revision: https://phabricator.services.mozilla.com/D314798
- - - - -
24 changed files:
- gfx/layers/ipc/PUiCompositorController.ipdl
- gfx/layers/ipc/UiCompositorControllerChild.cpp
- gfx/layers/ipc/UiCompositorControllerChild.h
- gfx/layers/ipc/UiCompositorControllerParent.cpp
- gfx/layers/ipc/UiCompositorControllerParent.h
- gfx/layers/wr/WebRenderBridgeParent.cpp
- gfx/layers/wr/WebRenderBridgeParent.h
- gfx/webrender_bindings/RenderCompositor.h
- gfx/webrender_bindings/RenderCompositorOGLSWGL.cpp
- gfx/webrender_bindings/RenderCompositorOGLSWGL.h
- gfx/webrender_bindings/RendererOGL.cpp
- gfx/webrender_bindings/RendererOGL.h
- gfx/webrender_bindings/WebRenderAPI.cpp
- gfx/webrender_bindings/WebRenderAPI.h
- mobile/android/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/DownloadsFeature.kt
- mobile/android/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/DownloadsFeatureTest.kt
- mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragment.kt
- + mobile/android/android-components/components/support/utils/src/main/java/mozilla/components/support/utils/OnEnterAnimationCompleteListener.kt
- mobile/android/components/geckoview/GeckoViewContentChannelParent.cpp
- mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonPopupBaseFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserActivity.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/RenameAndChangeLocationDialogFragment.kt
Changes:
=====================================
gfx/layers/ipc/PUiCompositorController.ipdl
=====================================
@@ -3,9 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
using mozilla::gfx::IntRect from "mozilla/gfx/Rect.h";
-using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
using mozilla::layers::CompositorScrollUpdate from "mozilla/layers/CompositorScrollUpdate.h";
-using mozilla::void_t from "mozilla/ipc/IPCCore.h";
include "mozilla/GfxMessageUtils.h";
include "mozilla/layers/LayersMessageUtils.h";
@@ -34,15 +32,14 @@ parent:
async MaxToolbarHeight(int32_t aHeight);
async FixedBottomOffset(int32_t aOffset);
async DefaultClearColor(uint32_t aColor);
- async RequestScreenPixels(uint64_t aRequestId, IntRect aSourceRect, IntSize aDestSize);
+ async RequestScreenPixels(uint64_t aRequestId, IntRect aSourceRect,
+ FileDescriptor aHardwareBuffer);
async EnableLayerUpdateNotifications(bool aEnable);
child:
async ToolbarAnimatorMessageFromCompositor(int32_t aMessage);
async NotifyCompositorScrollUpdate(CompositorScrollUpdate aUpdate);
- // Returns when the child side has finished using the HardwareBuffer,
- // indicating that the parent side can now release it.
- async ScreenPixels(uint64_t aRequestId, FileDescriptor? aHardwareBuffer, FileDescriptor? aAcquireFence)
- returns (void_t ok);
+ async ScreenPixels(uint64_t aRequestId, bool aSuccess,
+ FileDescriptor? aAcquireFence);
};
} // layers
=====================================
gfx/layers/ipc/UiCompositorControllerChild.cpp
=====================================
@@ -148,19 +148,36 @@ UiCompositorControllerChild::RequestScreenPixels(gfx::IntRect aSourceRect,
// We only support one request at a time. If an old request is still
// outstanding when a new request is made, just reject the old request.
- if (mScreenPixelsPromise) {
- mScreenPixelsPromise.extract().second->Reject(NS_ERROR_ABORT, __func__);
+ if (mScreenPixelsRequest) {
+ mScreenPixelsRequest.extract().mPromise->Reject(NS_ERROR_ABORT, __func__);
+ }
+
+ RefPtr<layers::AndroidHardwareBuffer> hardwareBuffer =
+ layers::AndroidHardwareBuffer::Create(aDestSize,
+ gfx::SurfaceFormat::R8G8B8A8);
+ if (!hardwareBuffer) {
+ return ScreenPixelsPromise::CreateAndReject(NS_ERROR_OUT_OF_MEMORY,
+ __func__);
+ }
+
+ UniqueFileHandle bufferFd = hardwareBuffer->SerializeToFileDescriptor();
+ if (!bufferFd) {
+ return ScreenPixelsPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
}
static uint64_t nextRequestId = 0;
const uint64_t requestId = nextRequestId++;
auto promise = MakeRefPtr<ScreenPixelsPromise::Private>(__func__);
- // Using synchronous dispatch ensures we are done using the hardware buffer
- // prior to RecvScreenPixels calling aResolver which in turn will cause the
- // hardware buffer on the parent side to be released.
- promise->UseSynchronousTaskDispatch(__func__);
- mScreenPixelsPromise.emplace(requestId, promise);
- (void)SendRequestScreenPixels(requestId, aSourceRect, aDestSize);
+ mScreenPixelsRequest.emplace(ScreenPixelsRequest{
+ .mRequestId = requestId,
+ .mHardwareBuffer = hardwareBuffer,
+ .mPromise = promise,
+ });
+ if (!SendRequestScreenPixels(requestId, aSourceRect,
+ ipc::FileDescriptor(std::move(bufferFd)))) {
+ mScreenPixelsRequest.extract().mPromise->Reject(NS_ERROR_NOT_AVAILABLE,
+ __func__);
+ }
return promise;
}
#endif
@@ -213,8 +230,8 @@ void UiCompositorControllerChild::ActorDestroy(ActorDestroyReason aWhy) {
mParent = nullptr;
#ifdef MOZ_WIDGET_ANDROID
- if (mScreenPixelsPromise) {
- mScreenPixelsPromise->second->Reject(NS_ERROR_ABORT, __func__);
+ if (mScreenPixelsRequest) {
+ mScreenPixelsRequest->mPromise->Reject(NS_ERROR_ABORT, __func__);
}
#endif
if (mProcessToken) {
@@ -258,39 +275,28 @@ UiCompositorControllerChild::RecvNotifyCompositorScrollUpdate(
}
mozilla::ipc::IPCResult UiCompositorControllerChild::RecvScreenPixels(
- uint64_t aRequestId, Maybe<ipc::FileDescriptor>&& aHardwareBuffer,
- Maybe<ipc::FileDescriptor>&& aAcquireFence,
- ScreenPixelsResolver&& aResolver) {
+ uint64_t aRequestId, bool aSuccess,
+ Maybe<ipc::FileDescriptor>&& aAcquireFence) {
#if defined(MOZ_WIDGET_ANDROID)
- if (!mScreenPixelsPromise || mScreenPixelsPromise->first != aRequestId) {
+ if (!mScreenPixelsRequest || mScreenPixelsRequest->mRequestId != aRequestId) {
// Response is for an outdated request whose promise will have already been
// rejected. Just ignore it.
return IPC_OK();
}
- RefPtr<layers::AndroidHardwareBuffer> hardwareBuffer;
- if (aHardwareBuffer) {
- hardwareBuffer =
- layers::AndroidHardwareBuffer::DeserializeFromFileDescriptor(
- aHardwareBuffer->TakePlatformHandle());
+ auto request = mScreenPixelsRequest.extract();
+ if (!aSuccess) {
+ request.mPromise->Reject(NS_ERROR_FAILURE, __func__);
+ return IPC_OK();
}
- if (hardwareBuffer && aAcquireFence) {
- hardwareBuffer->SetAcquireFence(aAcquireFence->TakePlatformHandle());
+
+ if (aAcquireFence) {
+ request.mHardwareBuffer->SetAcquireFence(
+ aAcquireFence->TakePlatformHandle());
}
- // Note this is resolved synchronously, ensuring we have finished using the
- // hardware buffer as soon as this call returns (and importantly before the
- // aResolver call below).
- mScreenPixelsPromise.extract().second->Resolve(std::move(hardwareBuffer),
- __func__);
+ request.mPromise->Resolve(std::move(request.mHardwareBuffer), __func__);
#endif // defined(MOZ_WIDGET_ANDROID)
- // Notify the parent side that it can drop its reference to the hardware
- // buffer. In theory this could be done as soon as we have called
- // DeserializeFromFileDescriptor(). However, on certain Exynos devices we have
- // seen that releasing the original hardware buffer frees the underlying
- // resource even if a reference obtained via (de)serialization remains alive.
- // See bug 2017901.
- aResolver(void_t{});
return IPC_OK();
}
=====================================
gfx/layers/ipc/UiCompositorControllerChild.h
=====================================
@@ -84,9 +84,8 @@ class UiCompositorControllerChild final
mozilla::ipc::IPCResult RecvNotifyCompositorScrollUpdate(
const CompositorScrollUpdate& aUpdate);
mozilla::ipc::IPCResult RecvScreenPixels(
- uint64_t aRequestId, Maybe<ipc::FileDescriptor>&& aHardwareBuffer,
- Maybe<ipc::FileDescriptor>&& aAcquireFence,
- ScreenPixelsResolver&& aResolver);
+ uint64_t aRequestId, bool aSuccess,
+ Maybe<ipc::FileDescriptor>&& aAcquireFence);
private:
explicit UiCompositorControllerChild(const uint64_t& aProcessToken,
@@ -118,8 +117,12 @@ class UiCompositorControllerChild final
// RecvScreenPixels() altogether. Unfortunately, however, we cannot chain to a
// promise returned from an IPDL function on the Android UI thread, as the
// thread does not support direct task dispatch.
- Maybe<std::pair<uint64_t, RefPtr<ScreenPixelsPromise::Private>>>
- mScreenPixelsPromise;
+ struct ScreenPixelsRequest {
+ uint64_t mRequestId;
+ RefPtr<layers::AndroidHardwareBuffer> mHardwareBuffer;
+ RefPtr<ScreenPixelsPromise::Private> mPromise;
+ };
+ Maybe<ScreenPixelsRequest> mScreenPixelsRequest;
#endif
// Should only be set when compositor is in process.
=====================================
gfx/layers/ipc/UiCompositorControllerParent.cpp
=====================================
@@ -139,39 +139,39 @@ mozilla::ipc::IPCResult UiCompositorControllerParent::RecvDefaultClearColor(
}
mozilla::ipc::IPCResult UiCompositorControllerParent::RecvRequestScreenPixels(
- uint64_t aRequestId, gfx::IntRect aSourceRect, gfx::IntSize aDestSize) {
+ uint64_t aRequestId, gfx::IntRect aSourceRect,
+ ipc::FileDescriptor&& aHardwareBuffer) {
#if defined(MOZ_WIDGET_ANDROID)
+ RefPtr<AndroidHardwareBuffer> hardwareBuffer =
+ AndroidHardwareBuffer::DeserializeFromFileDescriptor(
+ aHardwareBuffer.TakePlatformHandle());
+ if (!hardwareBuffer) {
+ (void)SendScreenPixels(aRequestId, false, Nothing());
+ return IPC_OK();
+ }
+
LayerTreeState* state =
CompositorBridgeParent::GetLayerTreeState(mRootLayerTreeId);
if (state && state->mWrBridge) {
- state->mWrBridge->RequestScreenPixels(aSourceRect, aDestSize)
+ state->mWrBridge->RequestScreenPixels(aSourceRect, hardwareBuffer)
->Then(
GetCurrentSerialEventTarget(), __func__,
- [target = RefPtr{this},
- aRequestId](RefPtr<AndroidHardwareBuffer> aHardwareBuffer) {
- UniqueFileHandle bufferFd =
- aHardwareBuffer->SerializeToFileDescriptor();
+ [target = RefPtr{this}, aRequestId,
+ hardwareBuffer = std::move(hardwareBuffer)](Ok) {
UniqueFileHandle fenceFd =
- aHardwareBuffer->GetAndResetAcquireFence();
- target
- ->SendScreenPixels(
- aRequestId,
- aHardwareBuffer
- ? Some(ipc::FileDescriptor(std::move(bufferFd)))
- : Nothing(),
- fenceFd ? Some(ipc::FileDescriptor(std::move(fenceFd)))
- : Nothing())
- // Ensure the hardware buffer remains alive until child side
- // has finished using it.
- ->Then(GetCurrentSerialEventTarget(), __func__,
- [aHardwareBuffer](
- ScreenPixelsPromise::ResolveOrRejectValue&&) {});
+ hardwareBuffer->GetAndResetAcquireFence();
+ (void)target->SendScreenPixels(
+ aRequestId, true,
+ fenceFd ? Some(ipc::FileDescriptor(std::move(fenceFd)))
+ : Nothing());
},
[target = RefPtr{this}, aRequestId](nsresult aError) {
- (void)target->SendScreenPixels(aRequestId, Nothing(), Nothing());
+ (void)target->SendScreenPixels(aRequestId, false, Nothing());
});
state->mWrBridge->ScheduleForcedGenerateFrame(wr::RenderReasons::OTHER);
+ } else {
+ (void)SendScreenPixels(aRequestId, false, Nothing());
}
#endif // defined(MOZ_WIDGET_ANDROID)
=====================================
gfx/layers/ipc/UiCompositorControllerParent.h
=====================================
@@ -41,9 +41,9 @@ class UiCompositorControllerParent final
mozilla::ipc::IPCResult RecvMaxToolbarHeight(const int32_t& aHeight);
mozilla::ipc::IPCResult RecvFixedBottomOffset(const int32_t& aOffset);
mozilla::ipc::IPCResult RecvDefaultClearColor(const uint32_t& aColor);
- mozilla::ipc::IPCResult RecvRequestScreenPixels(uint64_t aRequestId,
- gfx::IntRect aSourceRect,
- gfx::IntSize aDestSize);
+ mozilla::ipc::IPCResult RecvRequestScreenPixels(
+ uint64_t aRequestId, gfx::IntRect aSourceRect,
+ ipc::FileDescriptor&& aHardwareBuffer);
mozilla::ipc::IPCResult RecvEnableLayerUpdateNotifications(
const bool& aEnable);
void ActorDestroy(ActorDestroyReason aWhy) override;
=====================================
gfx/layers/wr/WebRenderBridgeParent.cpp
=====================================
@@ -1945,8 +1945,8 @@ void WebRenderBridgeParent::UpdateBoolParameters() {
#if defined(MOZ_WIDGET_ANDROID)
RefPtr<WebRenderBridgeParent::ScreenPixelsPromise>
-WebRenderBridgeParent::RequestScreenPixels(gfx::IntRect aSourceRect,
- gfx::IntSize aDestSize) {
+WebRenderBridgeParent::RequestScreenPixels(
+ gfx::IntRect aSourceRect, RefPtr<AndroidHardwareBuffer> aHardwareBuffer) {
if (mDestroyed) {
return ScreenPixelsPromise::CreateAndReject(NS_ERROR_ABORT, __func__);
}
@@ -1962,7 +1962,7 @@ WebRenderBridgeParent::RequestScreenPixels(gfx::IntRect aSourceRect,
}
mScreenPixelsRequest.emplace(ScreenPixelsRequest{
.mSourceRect = aSourceRect,
- .mDestSize = aDestSize,
+ .mHardwareBuffer = std::move(aHardwareBuffer),
.mPromise = new ScreenPixelsPromise::Private(__func__),
});
return mScreenPixelsRequest->mPromise;
@@ -1982,7 +1982,9 @@ void WebRenderBridgeParent::MaybeCaptureScreenPixels() {
MOZ_ASSERT(cbp && !cbp->IsPaused());
# endif
- mLateInit->mApi->RequestScreenPixels(request.mSourceRect, request.mDestSize)
+ mLateInit->mApi
+ ->RequestScreenPixels(request.mSourceRect,
+ std::move(request.mHardwareBuffer))
->ChainTo(request.mPromise.forget(), __func__);
}
#endif
=====================================
gfx/layers/wr/WebRenderBridgeParent.h
=====================================
@@ -325,13 +325,13 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
void BeginRecording(const TimeStamp& aRecordingStart);
#if defined(MOZ_WIDGET_ANDROID)
- using ScreenPixelsPromise =
- MozPromise<RefPtr<layers::AndroidHardwareBuffer>, nsresult, true>;
+ using ScreenPixelsPromise = MozPromise<Ok, nsresult, true>;
/**
* Request a screengrab for android
*/
- RefPtr<ScreenPixelsPromise> RequestScreenPixels(gfx::IntRect aSourceRect,
- gfx::IntSize aDestSize);
+ RefPtr<ScreenPixelsPromise> RequestScreenPixels(
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer);
#endif
/**
@@ -539,7 +539,7 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
#if defined(MOZ_WIDGET_ANDROID)
struct ScreenPixelsRequest {
gfx::IntRect mSourceRect;
- gfx::IntSize mDestSize;
+ RefPtr<layers::AndroidHardwareBuffer> mHardwareBuffer;
RefPtr<ScreenPixelsPromise::Private> mPromise;
};
Maybe<ScreenPixelsRequest> mScreenPixelsRequest;
=====================================
gfx/webrender_bindings/RenderCompositor.h
=====================================
@@ -235,7 +235,7 @@ class RenderCompositor {
#ifdef MOZ_WIDGET_ANDROID
virtual bool MaybeCaptureScreenPixels(
const gfx::IntRect& aSourceRect,
- RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer) {
+ layers::AndroidHardwareBuffer* aHardwareBuffer) {
return false;
}
#endif
=====================================
gfx/webrender_bindings/RenderCompositorOGLSWGL.cpp
=====================================
@@ -315,7 +315,7 @@ bool RenderCompositorOGLSWGL::MaybeReadback(
#ifdef MOZ_WIDGET_ANDROID
bool RenderCompositorOGLSWGL::MaybeCaptureScreenPixels(
const gfx::IntRect& aSourceRect,
- RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer) {
+ layers::AndroidHardwareBuffer* aHardwareBuffer) {
auto* const gl = GetGLContext();
gl::ScopedBindFramebuffer scopedBind(gl);
=====================================
gfx/webrender_bindings/RenderCompositorOGLSWGL.h
=====================================
@@ -59,7 +59,7 @@ class RenderCompositorOGLSWGL : public RenderCompositorLayersSWGL {
#ifdef MOZ_WIDGET_ANDROID
bool MaybeCaptureScreenPixels(
const gfx::IntRect& aSourceRect,
- RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer) override;
+ layers::AndroidHardwareBuffer* aHardwareBuffer) override;
#endif
private:
=====================================
gfx/webrender_bindings/RendererOGL.cpp
=====================================
@@ -469,7 +469,13 @@ Maybe<layers::FrameRecording> RendererOGL::EndRecording() {
#ifdef MOZ_WIDGET_ANDROID
RefPtr<RendererOGL::ScreenPixelsPromise> RendererOGL::RequestScreenPixels(
- gfx::IntRect aSourceRect, gfx::IntSize aDestSize) {
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer) {
+ if (!aHardwareBuffer) {
+ return ScreenPixelsPromise::CreateAndReject(NS_ERROR_ILLEGAL_VALUE,
+ __func__);
+ }
+
// If a new request is made we no longer care about the result of the previous
// one, so just reject it if it exists.
if (mPendingScreenPixelsRequest) {
@@ -478,7 +484,7 @@ RefPtr<RendererOGL::ScreenPixelsPromise> RendererOGL::RequestScreenPixels(
}
mPendingScreenPixelsRequest.emplace(ScreenPixelsRequest{
.mSourceRect = aSourceRect,
- .mDestSize = aDestSize,
+ .mHardwareBuffer = std::move(aHardwareBuffer),
.mPromise = new ScreenPixelsPromise::Private(__func__),
});
return mPendingScreenPixelsRequest->mPromise;
@@ -491,19 +497,16 @@ void RendererOGL::MaybeCaptureScreenPixels() {
auto request = mPendingScreenPixelsRequest.extract();
- const RefPtr<layers::AndroidHardwareBuffer> hardwareBuffer =
- layers::AndroidHardwareBuffer::Create(request.mDestSize,
- gfx::SurfaceFormat::R8G8B8A8);
-
if (mCompositor->MaybeCaptureScreenPixels(request.mSourceRect,
- hardwareBuffer)) {
- request.mPromise->Resolve(hardwareBuffer, __func__);
+ request.mHardwareBuffer)) {
+ request.mPromise->Resolve(Ok{}, __func__);
return;
}
auto* const gle = gl::GLContextEGL::Cast(gl());
const auto& egl = gle->mEgl;
- gl::ScopedEGLImageForAndroidHardwareBuffer eglImage(gle, hardwareBuffer);
+ gl::ScopedEGLImageForAndroidHardwareBuffer eglImage(gle,
+ request.mHardwareBuffer);
gl::ScopedBindFramebuffer scopedBind(gl());
gl::ScopedRenderbuffer rb(gl());
gl()->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, rb);
@@ -517,7 +520,7 @@ void RendererOGL::MaybeCaptureScreenPixels() {
request.mSourceRect.x,
mCompositor->GetBufferSize().height - request.mSourceRect.y,
request.mSourceRect.width, -request.mSourceRect.height);
- const auto destRect = gfx::IntRect({}, hardwareBuffer->mSize);
+ const auto destRect = gfx::IntRect({}, request.mHardwareBuffer->mSize);
gl()->BindReadFB(0);
gl()->BindDrawFB(fb.FB());
gl()->fBlitFramebuffer(srcRect.x, srcRect.y, srcRect.XMost(), srcRect.YMost(),
@@ -529,12 +532,12 @@ void RendererOGL::MaybeCaptureScreenPixels() {
egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr)) {
auto fence = UniqueFileHandle(egl->fDupNativeFenceFDANDROID(sync));
if (fence) {
- hardwareBuffer->SetAcquireFence(std::move(fence));
+ request.mHardwareBuffer->SetAcquireFence(std::move(fence));
}
egl->fDestroySync(sync);
}
- request.mPromise->Resolve(hardwareBuffer, __func__);
+ request.mPromise->Resolve(Ok{}, __func__);
}
#endif
=====================================
gfx/webrender_bindings/RendererOGL.h
=====================================
@@ -93,12 +93,12 @@ class RendererOGL {
Maybe<layers::FrameRecording> EndRecording();
#ifdef MOZ_WIDGET_ANDROID
- using ScreenPixelsPromise =
- MozPromise<RefPtr<layers::AndroidHardwareBuffer>, nsresult, true>;
+ using ScreenPixelsPromise = MozPromise<Ok, nsresult, true>;
// Captures the pixels for the next rendered frame. Returns a promise that
// resolves once the pixels are captured.
- RefPtr<ScreenPixelsPromise> RequestScreenPixels(gfx::IntRect aSourceRect,
- gfx::IntSize aDestSize);
+ RefPtr<ScreenPixelsPromise> RequestScreenPixels(
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer);
#endif
/// This can be called on the render thread only.
@@ -174,7 +174,7 @@ class RendererOGL {
#ifdef MOZ_WIDGET_ANDROID
struct ScreenPixelsRequest {
gfx::IntRect mSourceRect;
- gfx::IntSize mDestSize;
+ RefPtr<layers::AndroidHardwareBuffer> mHardwareBuffer;
RefPtr<ScreenPixelsPromise::Private> mPromise;
};
Maybe<ScreenPixelsRequest> mPendingScreenPixelsRequest;
=====================================
gfx/webrender_bindings/WebRenderAPI.cpp
=====================================
@@ -962,12 +962,17 @@ RefPtr<WebRenderAPI::EndRecordingPromise> WebRenderAPI::EndRecording() {
#ifdef MOZ_WIDGET_ANDROID
RefPtr<WebRenderAPI::ScreenPixelsPromise> WebRenderAPI::RequestScreenPixels(
- gfx::IntRect aSourceRect, gfx::IntSize aDestSize) {
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer) {
class ScreenshotEvent final : public RendererEvent {
public:
- explicit ScreenshotEvent(gfx::IntRect aSourceRect, gfx::IntSize aDestSize,
- RefPtr<ScreenPixelsPromise::Private> aPromise)
- : mSourceRect(aSourceRect), mDestSize(aDestSize), mPromise(aPromise) {
+ explicit ScreenshotEvent(
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer,
+ RefPtr<ScreenPixelsPromise::Private> aPromise)
+ : mSourceRect(aSourceRect),
+ mHardwareBuffer(std::move(aHardwareBuffer)),
+ mPromise(aPromise) {
MOZ_COUNT_CTOR(ScreenshotEvent);
}
@@ -977,8 +982,9 @@ RefPtr<WebRenderAPI::ScreenPixelsPromise> WebRenderAPI::RequestScreenPixels(
RendererOGL* const renderer = aRenderThread.GetRenderer(aWindowId);
if (!renderer) {
mPromise->Reject(NS_ERROR_FAILURE, __func__);
+ return;
}
- renderer->RequestScreenPixels(mSourceRect, mDestSize)
+ renderer->RequestScreenPixels(mSourceRect, std::move(mHardwareBuffer))
->ChainTo(mPromise.forget(), __func__);
}
@@ -986,12 +992,13 @@ RefPtr<WebRenderAPI::ScreenPixelsPromise> WebRenderAPI::RequestScreenPixels(
private:
const gfx::IntRect mSourceRect;
- const gfx::IntSize mDestSize;
+ RefPtr<layers::AndroidHardwareBuffer> mHardwareBuffer;
RefPtr<ScreenPixelsPromise::Private> mPromise;
};
auto promise = MakeRefPtr<ScreenPixelsPromise::Private>(__func__);
- auto event = MakeUnique<ScreenshotEvent>(aSourceRect, aDestSize, promise);
+ auto event = MakeUnique<ScreenshotEvent>(aSourceRect,
+ std::move(aHardwareBuffer), promise);
RenderThread::Get()->PostEvent(mId, std::move(event));
return promise;
=====================================
gfx/webrender_bindings/WebRenderAPI.h
=====================================
@@ -322,13 +322,13 @@ class WebRenderAPI final {
RefPtr<EndRecordingPromise> EndRecording();
#ifdef MOZ_WIDGET_ANDROID
- using ScreenPixelsPromise =
- MozPromise<RefPtr<layers::AndroidHardwareBuffer>, nsresult, true>;
+ using ScreenPixelsPromise = MozPromise<Ok, nsresult, true>;
// Queues a task to the render thread to capture screen pixels for the next
// rendered frame. Returns a promise that resolves once the pixels are
// captured.
- RefPtr<ScreenPixelsPromise> RequestScreenPixels(gfx::IntRect aSourceRect,
- gfx::IntSize aDestSize);
+ RefPtr<ScreenPixelsPromise> RequestScreenPixels(
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer);
#endif
layers::RemoteTextureInfoList* GetPendingRemoteTextureInfoList();
=====================================
mobile/android/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/DownloadsFeature.kt
=====================================
@@ -123,6 +123,8 @@ value class OpenFileCallback(val value: () -> Unit)
* manager is provided, a dialog will be shown before every download.
* @property promptsStyling styling properties for the dialog.
* @property onDownloadStartedListener a callback invoked when a download is started.
+ * @property dismissCustomFirstPartyDownloadDialog A callback invoked when the custom first party
+ * download dialog should be dismissed.
* @property shouldForwardToThirdParties Indicates if downloads should be forward to third party apps,
* if there are multiple apps a chooser dialog will shown.
* @property customFirstPartyDownloadDialog An optional delegate for showing a dialog for a download
@@ -146,6 +148,7 @@ class DownloadsFeature(
private val fragmentManager: FragmentManager? = null,
private val promptsStyling: PromptsStyling? = null,
private val onDownloadStartedListener: ((String) -> Unit) = {},
+ private val dismissCustomFirstPartyDownloadDialog: () -> Unit = {},
private val shouldForwardToThirdParties: () -> Boolean = { false },
private val customFirstPartyDownloadDialog: (
(
@@ -556,6 +559,7 @@ class DownloadsFeature(
internal fun dismissAllDownloadDialogs() {
findPreviousDownloadDialogFragment()?.dismiss()
findPreviousAppDownloaderDialogFragment()?.dismiss()
+ dismissCustomFirstPartyDownloadDialog.invoke()
}
private val ActivityInfo.identifier: String get() = packageName + name
=====================================
mobile/android/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/DownloadsFeatureTest.kt
=====================================
@@ -1460,6 +1460,64 @@ class DownloadsFeatureTest {
verify(cancelDownloadRequestUseCase).invoke(anyString(), anyString())
}
+ @Test
+ fun `GIVEN a custom download dialog is used WHEN dismissAllDownloadDialogs is called THEN the dialog is dismissed`() = runTest(testDispatcher) {
+ val dismissCustomDialog = mock<() -> Unit>()
+ val feature = DownloadsFeature(
+ testContext,
+ store,
+ useCases = DownloadsUseCases(store, mock()),
+ downloadFileUtils = FakeDownloadFileUtils(),
+ downloadManager = mock(),
+ mainDispatcher = testDispatcher,
+ dismissCustomFirstPartyDownloadDialog = dismissCustomDialog,
+ )
+
+ feature.dismissAllDownloadDialogs()
+
+ verify(dismissCustomDialog).invoke()
+ }
+
+ @Test
+ fun `GIVEN a custom download dialog is used WHEN navigating to another website THEN the dialog is dismissed`() = runTest(testDispatcher) {
+ val dismissCustomDialog = mock<() -> Unit>()
+ val downloadsUseCases = spy(DownloadsUseCases(store, mock()))
+ val cancelDownloadRequestUseCase = mock<CancelDownloadRequestUseCase>()
+ val download = DownloadState(url = "https://www.mozilla.org", sessionId = "test-tab")
+ store.dispatch(ContentAction.UpdateDownloadAction("test-tab", download = download))
+
+ doReturn(cancelDownloadRequestUseCase).`when`(downloadsUseCases).cancelDownloadRequest
+
+ val feature = spy(
+ DownloadsFeature(
+ testContext,
+ store,
+ useCases = downloadsUseCases,
+ downloadFileUtils = FakeDownloadFileUtils(),
+ downloadManager = mock(),
+ mainDispatcher = testDispatcher,
+ dismissCustomFirstPartyDownloadDialog = dismissCustomDialog,
+ ),
+ )
+
+ doReturn(true).`when`(feature).processDownload(any(), any())
+
+ feature.start()
+ testDispatcher.scheduler.advanceUntilIdle()
+
+ store.dispatch(ContentAction.UpdateDownloadAction("test-tab", download = download))
+ testDispatcher.scheduler.advanceUntilIdle()
+
+ grantPermissions()
+
+ val tab = createTab("https://www.firefox.com")
+ store.dispatch(TabListAction.AddTabAction(tab, select = true))
+ testDispatcher.scheduler.advanceUntilIdle()
+
+ verify(feature).dismissAllDownloadDialogs()
+ verify(dismissCustomDialog).invoke()
+ }
+
@Test
fun `ResolveInfo to DownloaderApps`() = runTest(testDispatcher) {
val spyContext = spy(testContext)
=====================================
mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragment.kt
=====================================
@@ -32,6 +32,7 @@ import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.ktx.android.content.appName
import mozilla.components.support.ktx.kotlin.ifNullOrEmpty
import mozilla.components.support.ktx.util.PromptAbuserDetector
+import mozilla.components.support.utils.OnEnterAnimationCompleteListener
internal const val KEY_SESSION_ID = "KEY_SESSION_ID"
internal const val KEY_TITLE = "KEY_TITLE"
@@ -51,7 +52,9 @@ private const val KEY_IS_NOTIFICATION_REQUEST = "KEY_IS_NOTIFICATION_REQUEST"
private const val DEFAULT_VALUE = Int.MAX_VALUE
private const val KEY_PERMISSION_ID = "KEY_PERMISSION_ID"
-internal open class SitePermissionsDialogFragment : NoObscuredTouchesDialogFragment() {
+internal open class SitePermissionsDialogFragment :
+ NoObscuredTouchesDialogFragment(),
+ OnEnterAnimationCompleteListener {
private val logger = Logger("SitePermissionsDialogFragment")
@@ -134,6 +137,11 @@ internal open class SitePermissionsDialogFragment : NoObscuredTouchesDialogFragm
feature?.onDismiss(permissionRequestId, sessionId)
}
+ override fun onEnterAnimationComplete() {
+ // Extend the positive button click delay.
+ promptAbuserDetector.updateJSDialogAbusedState()
+ }
+
private fun Dialog.setContainerView(rootView: View) {
if (dialogShouldWidthMatchParent) {
setContentView(rootView)
=====================================
mobile/android/android-components/components/support/utils/src/main/java/mozilla/components/support/utils/OnEnterAnimationCompleteListener.kt
=====================================
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.support.utils
+
+/**
+ * Allows forwarding [android.app.Activity.onEnterAnimationComplete] to other classes
+ * (e.g. fragments) that want to participate in handling it.
+ */
+interface OnEnterAnimationCompleteListener {
+ /**
+ * Called when the Activity's entering animation has completed.
+ */
+ fun onEnterAnimationComplete()
+}
=====================================
mobile/android/components/geckoview/GeckoViewContentChannelParent.cpp
=====================================
@@ -159,6 +159,11 @@ bool GeckoViewContentChannelParent::Init(
nsCOMPtr<nsIURI> uri = ipc::DeserializeURI(aArgs.uri());
+ if (!uri || !uri->SchemeIs("content")) {
+ rv = NS_ERROR_UNKNOWN_PROTOCOL;
+ return false;
+ }
+
nsAutoCString remoteType;
rv = GetRemoteType(remoteType);
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
=====================================
mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt
=====================================
@@ -29,6 +29,7 @@ import androidx.test.espresso.intent.matcher.IntentMatchers
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
+import mozilla.components.support.ktx.util.PromptAbuserDetector
import org.hamcrest.CoreMatchers.allOf
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.snackbar.SNACKBAR_TEST_TAG
@@ -257,7 +258,9 @@ class DownloadRobot(private val composeTestRule: ComposeTestRule) {
class Transition(private val composeTestRule: ComposeTestRule) {
fun clickDownload(composeTestRule: ComposeTestRule, interact: DownloadRobot.() -> Unit): Transition {
Log.i(TAG, "clickDownload: Trying to click the \"Download\" download prompt button")
+ PromptAbuserDetector.validationsEnabled = false
composeTestRule.downloadButton().performClick()
+ PromptAbuserDetector.validationsEnabled = true
Log.i(TAG, "clickDownload: Clicked the \"Download\" download prompt button")
DownloadRobot(composeTestRule).interact()
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonPopupBaseFragment.kt
=====================================
@@ -161,6 +161,10 @@ abstract class AddonPopupBaseFragment :
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_DOWNLOAD_PERMISSIONS)
},
+ dismissCustomFirstPartyDownloadDialog = {
+ dismissRenameDialog()
+ downloadDialog?.dismiss()
+ },
customFirstPartyDownloadDialog = { currentDownloadState, _, positiveAction, negativeAction, _ ->
run {
if (canShowDownloadDialog()) {
@@ -394,6 +398,13 @@ abstract class AddonPopupBaseFragment :
return downloadDialog == null && !isRenameFragmentShowing
}
+ private fun dismissRenameDialog() {
+ val renameDialog = childFragmentManager.findFragmentByTag(
+ RenameAndChangeLocationDialogFragment.RENAME_AND_CHANGE_LOCATION_DIALOG_TAG,
+ ) as? RenameAndChangeLocationDialogFragment
+ renameDialog?.dismissAllowingStateLoss()
+ }
+
/**
* Forwards activity results to the [ActivityResultHandler] features.
*/
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
=====================================
@@ -742,6 +742,10 @@ abstract class BaseBrowserFragment :
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_DOWNLOAD_PERMISSIONS)
},
+ dismissCustomFirstPartyDownloadDialog = {
+ dismissRenameDialog()
+ dismissDownloadDialogs()
+ },
customFirstPartyDownloadDialog = {
currentDownloadState,
fileNameIfAlreadyDownloaded,
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserActivity.kt
=====================================
@@ -11,6 +11,7 @@ import androidx.annotation.VisibleForTesting
import androidx.core.net.toUri
import mozilla.components.browser.state.selector.findCustomTab
import mozilla.components.browser.state.state.SessionState
+import mozilla.components.support.utils.OnEnterAnimationCompleteListener
import mozilla.components.support.utils.SafeIntent
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.ext.components
@@ -92,5 +93,14 @@ open class ExternalAppBrowserActivity : HomeActivity() {
override fun onEnterAnimationComplete() {
super.onEnterAnimationComplete()
isFinishedAnimating = true
+
+ val fragments = supportFragmentManager.fragments.toMutableList()
+ while (fragments.isNotEmpty()) {
+ val fragment = fragments.removeAt(0)
+ if (fragment is OnEnterAnimationCompleteListener) {
+ fragment.onEnterAnimationComplete()
+ }
+ fragments.addAll(fragment.childFragmentManager.fragments)
+ }
}
}
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/RenameAndChangeLocationDialogFragment.kt
=====================================
@@ -20,6 +20,8 @@ import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import mozilla.components.concept.base.crash.Breadcrumb
import mozilla.components.support.base.log.logger.Logger
+import mozilla.components.support.ktx.util.PromptAbuserDetector
+import mozilla.components.support.utils.OnEnterAnimationCompleteListener
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.requireComponents
@@ -38,10 +40,12 @@ import org.mozilla.fenix.theme.FirefoxTheme
*
* The callback [onConfirmSave] is invoked with the final file name and directory path.
*/
-class RenameAndChangeLocationDialogFragment : DialogFragment() {
+class RenameAndChangeLocationDialogFragment : DialogFragment(), OnEnterAnimationCompleteListener {
private val logger = Logger("RenameAndChangeLocationDialogFragment")
private val safeArguments get() = requireNotNull(arguments)
+ private val promptAbuserDetector = PromptAbuserDetector(TIME_SHOWN_OFFSET_MILLIS)
+
internal val fileName: String
get() = safeArguments.getString(KEY_FILE_NAME, "")
@@ -75,6 +79,15 @@ class RenameAndChangeLocationDialogFragment : DialogFragment() {
}
}
+ override fun onResume() {
+ super.onResume()
+ promptAbuserDetector.start()
+ }
+
+ override fun onEnterAnimationComplete() {
+ promptAbuserDetector.start()
+ }
+
override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog)
onCancel()
@@ -99,6 +112,8 @@ class RenameAndChangeLocationDialogFragment : DialogFragment() {
val composeView = createComposeView()
+ promptAbuserDetector.start()
+
return MaterialAlertDialogBuilder(requireContext())
.setView(composeView)
.create()
@@ -144,11 +159,15 @@ class RenameAndChangeLocationDialogFragment : DialogFragment() {
directoryLauncher.launch(null)
},
onConfirm = {
- onConfirmSave(
- dialogState.fileName,
- dialogState.directoryPath,
- )
- dismiss()
+ if (promptAbuserDetector.areDialogsBeingAbused()) {
+ promptAbuserDetector.updateJSDialogAbusedState()
+ } else {
+ onConfirmSave(
+ dialogState.fileName,
+ dialogState.directoryPath,
+ )
+ dismiss()
+ }
},
onCancel = {
onCancel()
@@ -182,6 +201,7 @@ class RenameAndChangeLocationDialogFragment : DialogFragment() {
private const val KEY_DIRECTORY_PATH = "directory_path"
private const val KEY_CONTENT_SIZE = "content_size"
const val RENAME_AND_CHANGE_LOCATION_DIALOG_TAG = "RENAME_AND_CHANGE_LOCATION_DIALOG_TAG"
+ private const val TIME_SHOWN_OFFSET_MILLIS = 500
/**
* Creates a new instance of [RenameAndChangeLocationDialogFragment].
@@ -203,3 +223,14 @@ class RenameAndChangeLocationDialogFragment : DialogFragment() {
}
}
}
+
+/**
+ * Starts (or restarts) the time-based check without increasing the "click count".
+ *
+ * Makes it safe to call from multiple/successive lifecycle methods, without running into the risk
+ * of triggering the more restrictive count-based protection on the 1st click (or even before it).
+ */
+private fun PromptAbuserDetector.start() {
+ resetJSAlertAbuseState()
+ updateJSDialogAbusedState()
+}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/61…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/61…
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
[Git][tpo/applications/tor-browser] Pushed new tag tor-browser-153.1.0esr-16.0-1-build2
by ma1 (@ma1) 17 Aug '26
by ma1 (@ma1) 17 Aug '26
17 Aug '26
ma1 pushed new tag tor-browser-153.1.0esr-16.0-1-build2 at The Tor Project / Applications / Tor Browser
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/tree/tor-brows…
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
[Git][tpo/applications/tor-browser][tor-browser-153.1.0esr-16.0-1] 5 commits: Bug 1842361 - Download confirmation notification can be overlaid over other...
by ma1 (@ma1) 17 Aug '26
by ma1 (@ma1) 17 Aug '26
17 Aug '26
ma1 pushed to branch tor-browser-153.1.0esr-16.0-1 at The Tor Project / Applications / Tor Browser
Commits:
bb66338d by giorga at 2026-08-16T00:41:44+02:00
Bug 1842361 - Download confirmation notification can be overlaid over other origins. r=android-reviewers,jdelorenzo
Differential Revision: https://phabricator.services.mozilla.com/D309062
- - - - -
7655bbd2 by Marcin Koziński at 2026-08-16T00:41:44+02:00
Bug 1978587 - Forward onEnterAnimationComplete to interested fragments r=android-reviewers,twhite
Differential Revision: https://phabricator.services.mozilla.com/D306954
- - - - -
d13ffd02 by Marcin Koziński at 2026-08-16T00:56:58+02:00
Bug 2049034 - Add an initial delay to download button in Fenix download dialog a=pascalc
Original Revision: https://phabricator.services.mozilla.com/D309334
Differential Revision: https://phabricator.services.mozilla.com/D310049
- - - - -
4e27f4b0 by Jamie Nicol at 2026-08-17T08:17:03+02:00
Bug 2049810 - Allocate HardwareBuffer for screen pixels request in parent process. r=gfx-reviewers,lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D308519
- - - - -
a6ed37e7 by owlishDeveloper at 2026-08-17T10:29:07+02:00
Bug 2055683 - IPC improvement a=pascalc
Original Revision: https://phabricator.services.mozilla.com/D314463
Differential Revision: https://phabricator.services.mozilla.com/D314798
- - - - -
24 changed files:
- gfx/layers/ipc/PUiCompositorController.ipdl
- gfx/layers/ipc/UiCompositorControllerChild.cpp
- gfx/layers/ipc/UiCompositorControllerChild.h
- gfx/layers/ipc/UiCompositorControllerParent.cpp
- gfx/layers/ipc/UiCompositorControllerParent.h
- gfx/layers/wr/WebRenderBridgeParent.cpp
- gfx/layers/wr/WebRenderBridgeParent.h
- gfx/webrender_bindings/RenderCompositor.h
- gfx/webrender_bindings/RenderCompositorOGLSWGL.cpp
- gfx/webrender_bindings/RenderCompositorOGLSWGL.h
- gfx/webrender_bindings/RendererOGL.cpp
- gfx/webrender_bindings/RendererOGL.h
- gfx/webrender_bindings/WebRenderAPI.cpp
- gfx/webrender_bindings/WebRenderAPI.h
- mobile/android/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/DownloadsFeature.kt
- mobile/android/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/DownloadsFeatureTest.kt
- mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragment.kt
- + mobile/android/android-components/components/support/utils/src/main/java/mozilla/components/support/utils/OnEnterAnimationCompleteListener.kt
- mobile/android/components/geckoview/GeckoViewContentChannelParent.cpp
- mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonPopupBaseFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserActivity.kt
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/RenameAndChangeLocationDialogFragment.kt
Changes:
=====================================
gfx/layers/ipc/PUiCompositorController.ipdl
=====================================
@@ -3,9 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
using mozilla::gfx::IntRect from "mozilla/gfx/Rect.h";
-using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
using mozilla::layers::CompositorScrollUpdate from "mozilla/layers/CompositorScrollUpdate.h";
-using mozilla::void_t from "mozilla/ipc/IPCCore.h";
include "mozilla/GfxMessageUtils.h";
include "mozilla/layers/LayersMessageUtils.h";
@@ -34,15 +32,14 @@ parent:
async MaxToolbarHeight(int32_t aHeight);
async FixedBottomOffset(int32_t aOffset);
async DefaultClearColor(uint32_t aColor);
- async RequestScreenPixels(uint64_t aRequestId, IntRect aSourceRect, IntSize aDestSize);
+ async RequestScreenPixels(uint64_t aRequestId, IntRect aSourceRect,
+ FileDescriptor aHardwareBuffer);
async EnableLayerUpdateNotifications(bool aEnable);
child:
async ToolbarAnimatorMessageFromCompositor(int32_t aMessage);
async NotifyCompositorScrollUpdate(CompositorScrollUpdate aUpdate);
- // Returns when the child side has finished using the HardwareBuffer,
- // indicating that the parent side can now release it.
- async ScreenPixels(uint64_t aRequestId, FileDescriptor? aHardwareBuffer, FileDescriptor? aAcquireFence)
- returns (void_t ok);
+ async ScreenPixels(uint64_t aRequestId, bool aSuccess,
+ FileDescriptor? aAcquireFence);
};
} // layers
=====================================
gfx/layers/ipc/UiCompositorControllerChild.cpp
=====================================
@@ -148,19 +148,36 @@ UiCompositorControllerChild::RequestScreenPixels(gfx::IntRect aSourceRect,
// We only support one request at a time. If an old request is still
// outstanding when a new request is made, just reject the old request.
- if (mScreenPixelsPromise) {
- mScreenPixelsPromise.extract().second->Reject(NS_ERROR_ABORT, __func__);
+ if (mScreenPixelsRequest) {
+ mScreenPixelsRequest.extract().mPromise->Reject(NS_ERROR_ABORT, __func__);
+ }
+
+ RefPtr<layers::AndroidHardwareBuffer> hardwareBuffer =
+ layers::AndroidHardwareBuffer::Create(aDestSize,
+ gfx::SurfaceFormat::R8G8B8A8);
+ if (!hardwareBuffer) {
+ return ScreenPixelsPromise::CreateAndReject(NS_ERROR_OUT_OF_MEMORY,
+ __func__);
+ }
+
+ UniqueFileHandle bufferFd = hardwareBuffer->SerializeToFileDescriptor();
+ if (!bufferFd) {
+ return ScreenPixelsPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
}
static uint64_t nextRequestId = 0;
const uint64_t requestId = nextRequestId++;
auto promise = MakeRefPtr<ScreenPixelsPromise::Private>(__func__);
- // Using synchronous dispatch ensures we are done using the hardware buffer
- // prior to RecvScreenPixels calling aResolver which in turn will cause the
- // hardware buffer on the parent side to be released.
- promise->UseSynchronousTaskDispatch(__func__);
- mScreenPixelsPromise.emplace(requestId, promise);
- (void)SendRequestScreenPixels(requestId, aSourceRect, aDestSize);
+ mScreenPixelsRequest.emplace(ScreenPixelsRequest{
+ .mRequestId = requestId,
+ .mHardwareBuffer = hardwareBuffer,
+ .mPromise = promise,
+ });
+ if (!SendRequestScreenPixels(requestId, aSourceRect,
+ ipc::FileDescriptor(std::move(bufferFd)))) {
+ mScreenPixelsRequest.extract().mPromise->Reject(NS_ERROR_NOT_AVAILABLE,
+ __func__);
+ }
return promise;
}
#endif
@@ -213,8 +230,8 @@ void UiCompositorControllerChild::ActorDestroy(ActorDestroyReason aWhy) {
mParent = nullptr;
#ifdef MOZ_WIDGET_ANDROID
- if (mScreenPixelsPromise) {
- mScreenPixelsPromise->second->Reject(NS_ERROR_ABORT, __func__);
+ if (mScreenPixelsRequest) {
+ mScreenPixelsRequest->mPromise->Reject(NS_ERROR_ABORT, __func__);
}
#endif
if (mProcessToken) {
@@ -258,39 +275,28 @@ UiCompositorControllerChild::RecvNotifyCompositorScrollUpdate(
}
mozilla::ipc::IPCResult UiCompositorControllerChild::RecvScreenPixels(
- uint64_t aRequestId, Maybe<ipc::FileDescriptor>&& aHardwareBuffer,
- Maybe<ipc::FileDescriptor>&& aAcquireFence,
- ScreenPixelsResolver&& aResolver) {
+ uint64_t aRequestId, bool aSuccess,
+ Maybe<ipc::FileDescriptor>&& aAcquireFence) {
#if defined(MOZ_WIDGET_ANDROID)
- if (!mScreenPixelsPromise || mScreenPixelsPromise->first != aRequestId) {
+ if (!mScreenPixelsRequest || mScreenPixelsRequest->mRequestId != aRequestId) {
// Response is for an outdated request whose promise will have already been
// rejected. Just ignore it.
return IPC_OK();
}
- RefPtr<layers::AndroidHardwareBuffer> hardwareBuffer;
- if (aHardwareBuffer) {
- hardwareBuffer =
- layers::AndroidHardwareBuffer::DeserializeFromFileDescriptor(
- aHardwareBuffer->TakePlatformHandle());
+ auto request = mScreenPixelsRequest.extract();
+ if (!aSuccess) {
+ request.mPromise->Reject(NS_ERROR_FAILURE, __func__);
+ return IPC_OK();
}
- if (hardwareBuffer && aAcquireFence) {
- hardwareBuffer->SetAcquireFence(aAcquireFence->TakePlatformHandle());
+
+ if (aAcquireFence) {
+ request.mHardwareBuffer->SetAcquireFence(
+ aAcquireFence->TakePlatformHandle());
}
- // Note this is resolved synchronously, ensuring we have finished using the
- // hardware buffer as soon as this call returns (and importantly before the
- // aResolver call below).
- mScreenPixelsPromise.extract().second->Resolve(std::move(hardwareBuffer),
- __func__);
+ request.mPromise->Resolve(std::move(request.mHardwareBuffer), __func__);
#endif // defined(MOZ_WIDGET_ANDROID)
- // Notify the parent side that it can drop its reference to the hardware
- // buffer. In theory this could be done as soon as we have called
- // DeserializeFromFileDescriptor(). However, on certain Exynos devices we have
- // seen that releasing the original hardware buffer frees the underlying
- // resource even if a reference obtained via (de)serialization remains alive.
- // See bug 2017901.
- aResolver(void_t{});
return IPC_OK();
}
=====================================
gfx/layers/ipc/UiCompositorControllerChild.h
=====================================
@@ -84,9 +84,8 @@ class UiCompositorControllerChild final
mozilla::ipc::IPCResult RecvNotifyCompositorScrollUpdate(
const CompositorScrollUpdate& aUpdate);
mozilla::ipc::IPCResult RecvScreenPixels(
- uint64_t aRequestId, Maybe<ipc::FileDescriptor>&& aHardwareBuffer,
- Maybe<ipc::FileDescriptor>&& aAcquireFence,
- ScreenPixelsResolver&& aResolver);
+ uint64_t aRequestId, bool aSuccess,
+ Maybe<ipc::FileDescriptor>&& aAcquireFence);
private:
explicit UiCompositorControllerChild(const uint64_t& aProcessToken,
@@ -118,8 +117,12 @@ class UiCompositorControllerChild final
// RecvScreenPixels() altogether. Unfortunately, however, we cannot chain to a
// promise returned from an IPDL function on the Android UI thread, as the
// thread does not support direct task dispatch.
- Maybe<std::pair<uint64_t, RefPtr<ScreenPixelsPromise::Private>>>
- mScreenPixelsPromise;
+ struct ScreenPixelsRequest {
+ uint64_t mRequestId;
+ RefPtr<layers::AndroidHardwareBuffer> mHardwareBuffer;
+ RefPtr<ScreenPixelsPromise::Private> mPromise;
+ };
+ Maybe<ScreenPixelsRequest> mScreenPixelsRequest;
#endif
// Should only be set when compositor is in process.
=====================================
gfx/layers/ipc/UiCompositorControllerParent.cpp
=====================================
@@ -139,39 +139,39 @@ mozilla::ipc::IPCResult UiCompositorControllerParent::RecvDefaultClearColor(
}
mozilla::ipc::IPCResult UiCompositorControllerParent::RecvRequestScreenPixels(
- uint64_t aRequestId, gfx::IntRect aSourceRect, gfx::IntSize aDestSize) {
+ uint64_t aRequestId, gfx::IntRect aSourceRect,
+ ipc::FileDescriptor&& aHardwareBuffer) {
#if defined(MOZ_WIDGET_ANDROID)
+ RefPtr<AndroidHardwareBuffer> hardwareBuffer =
+ AndroidHardwareBuffer::DeserializeFromFileDescriptor(
+ aHardwareBuffer.TakePlatformHandle());
+ if (!hardwareBuffer) {
+ (void)SendScreenPixels(aRequestId, false, Nothing());
+ return IPC_OK();
+ }
+
LayerTreeState* state =
CompositorBridgeParent::GetLayerTreeState(mRootLayerTreeId);
if (state && state->mWrBridge) {
- state->mWrBridge->RequestScreenPixels(aSourceRect, aDestSize)
+ state->mWrBridge->RequestScreenPixels(aSourceRect, hardwareBuffer)
->Then(
GetCurrentSerialEventTarget(), __func__,
- [target = RefPtr{this},
- aRequestId](RefPtr<AndroidHardwareBuffer> aHardwareBuffer) {
- UniqueFileHandle bufferFd =
- aHardwareBuffer->SerializeToFileDescriptor();
+ [target = RefPtr{this}, aRequestId,
+ hardwareBuffer = std::move(hardwareBuffer)](Ok) {
UniqueFileHandle fenceFd =
- aHardwareBuffer->GetAndResetAcquireFence();
- target
- ->SendScreenPixels(
- aRequestId,
- aHardwareBuffer
- ? Some(ipc::FileDescriptor(std::move(bufferFd)))
- : Nothing(),
- fenceFd ? Some(ipc::FileDescriptor(std::move(fenceFd)))
- : Nothing())
- // Ensure the hardware buffer remains alive until child side
- // has finished using it.
- ->Then(GetCurrentSerialEventTarget(), __func__,
- [aHardwareBuffer](
- ScreenPixelsPromise::ResolveOrRejectValue&&) {});
+ hardwareBuffer->GetAndResetAcquireFence();
+ (void)target->SendScreenPixels(
+ aRequestId, true,
+ fenceFd ? Some(ipc::FileDescriptor(std::move(fenceFd)))
+ : Nothing());
},
[target = RefPtr{this}, aRequestId](nsresult aError) {
- (void)target->SendScreenPixels(aRequestId, Nothing(), Nothing());
+ (void)target->SendScreenPixels(aRequestId, false, Nothing());
});
state->mWrBridge->ScheduleForcedGenerateFrame(wr::RenderReasons::OTHER);
+ } else {
+ (void)SendScreenPixels(aRequestId, false, Nothing());
}
#endif // defined(MOZ_WIDGET_ANDROID)
=====================================
gfx/layers/ipc/UiCompositorControllerParent.h
=====================================
@@ -41,9 +41,9 @@ class UiCompositorControllerParent final
mozilla::ipc::IPCResult RecvMaxToolbarHeight(const int32_t& aHeight);
mozilla::ipc::IPCResult RecvFixedBottomOffset(const int32_t& aOffset);
mozilla::ipc::IPCResult RecvDefaultClearColor(const uint32_t& aColor);
- mozilla::ipc::IPCResult RecvRequestScreenPixels(uint64_t aRequestId,
- gfx::IntRect aSourceRect,
- gfx::IntSize aDestSize);
+ mozilla::ipc::IPCResult RecvRequestScreenPixels(
+ uint64_t aRequestId, gfx::IntRect aSourceRect,
+ ipc::FileDescriptor&& aHardwareBuffer);
mozilla::ipc::IPCResult RecvEnableLayerUpdateNotifications(
const bool& aEnable);
void ActorDestroy(ActorDestroyReason aWhy) override;
=====================================
gfx/layers/wr/WebRenderBridgeParent.cpp
=====================================
@@ -1945,8 +1945,8 @@ void WebRenderBridgeParent::UpdateBoolParameters() {
#if defined(MOZ_WIDGET_ANDROID)
RefPtr<WebRenderBridgeParent::ScreenPixelsPromise>
-WebRenderBridgeParent::RequestScreenPixels(gfx::IntRect aSourceRect,
- gfx::IntSize aDestSize) {
+WebRenderBridgeParent::RequestScreenPixels(
+ gfx::IntRect aSourceRect, RefPtr<AndroidHardwareBuffer> aHardwareBuffer) {
if (mDestroyed) {
return ScreenPixelsPromise::CreateAndReject(NS_ERROR_ABORT, __func__);
}
@@ -1962,7 +1962,7 @@ WebRenderBridgeParent::RequestScreenPixels(gfx::IntRect aSourceRect,
}
mScreenPixelsRequest.emplace(ScreenPixelsRequest{
.mSourceRect = aSourceRect,
- .mDestSize = aDestSize,
+ .mHardwareBuffer = std::move(aHardwareBuffer),
.mPromise = new ScreenPixelsPromise::Private(__func__),
});
return mScreenPixelsRequest->mPromise;
@@ -1982,7 +1982,9 @@ void WebRenderBridgeParent::MaybeCaptureScreenPixels() {
MOZ_ASSERT(cbp && !cbp->IsPaused());
# endif
- mLateInit->mApi->RequestScreenPixels(request.mSourceRect, request.mDestSize)
+ mLateInit->mApi
+ ->RequestScreenPixels(request.mSourceRect,
+ std::move(request.mHardwareBuffer))
->ChainTo(request.mPromise.forget(), __func__);
}
#endif
=====================================
gfx/layers/wr/WebRenderBridgeParent.h
=====================================
@@ -325,13 +325,13 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
void BeginRecording(const TimeStamp& aRecordingStart);
#if defined(MOZ_WIDGET_ANDROID)
- using ScreenPixelsPromise =
- MozPromise<RefPtr<layers::AndroidHardwareBuffer>, nsresult, true>;
+ using ScreenPixelsPromise = MozPromise<Ok, nsresult, true>;
/**
* Request a screengrab for android
*/
- RefPtr<ScreenPixelsPromise> RequestScreenPixels(gfx::IntRect aSourceRect,
- gfx::IntSize aDestSize);
+ RefPtr<ScreenPixelsPromise> RequestScreenPixels(
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer);
#endif
/**
@@ -539,7 +539,7 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
#if defined(MOZ_WIDGET_ANDROID)
struct ScreenPixelsRequest {
gfx::IntRect mSourceRect;
- gfx::IntSize mDestSize;
+ RefPtr<layers::AndroidHardwareBuffer> mHardwareBuffer;
RefPtr<ScreenPixelsPromise::Private> mPromise;
};
Maybe<ScreenPixelsRequest> mScreenPixelsRequest;
=====================================
gfx/webrender_bindings/RenderCompositor.h
=====================================
@@ -235,7 +235,7 @@ class RenderCompositor {
#ifdef MOZ_WIDGET_ANDROID
virtual bool MaybeCaptureScreenPixels(
const gfx::IntRect& aSourceRect,
- RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer) {
+ layers::AndroidHardwareBuffer* aHardwareBuffer) {
return false;
}
#endif
=====================================
gfx/webrender_bindings/RenderCompositorOGLSWGL.cpp
=====================================
@@ -315,7 +315,7 @@ bool RenderCompositorOGLSWGL::MaybeReadback(
#ifdef MOZ_WIDGET_ANDROID
bool RenderCompositorOGLSWGL::MaybeCaptureScreenPixels(
const gfx::IntRect& aSourceRect,
- RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer) {
+ layers::AndroidHardwareBuffer* aHardwareBuffer) {
auto* const gl = GetGLContext();
gl::ScopedBindFramebuffer scopedBind(gl);
=====================================
gfx/webrender_bindings/RenderCompositorOGLSWGL.h
=====================================
@@ -59,7 +59,7 @@ class RenderCompositorOGLSWGL : public RenderCompositorLayersSWGL {
#ifdef MOZ_WIDGET_ANDROID
bool MaybeCaptureScreenPixels(
const gfx::IntRect& aSourceRect,
- RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer) override;
+ layers::AndroidHardwareBuffer* aHardwareBuffer) override;
#endif
private:
=====================================
gfx/webrender_bindings/RendererOGL.cpp
=====================================
@@ -469,7 +469,13 @@ Maybe<layers::FrameRecording> RendererOGL::EndRecording() {
#ifdef MOZ_WIDGET_ANDROID
RefPtr<RendererOGL::ScreenPixelsPromise> RendererOGL::RequestScreenPixels(
- gfx::IntRect aSourceRect, gfx::IntSize aDestSize) {
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer) {
+ if (!aHardwareBuffer) {
+ return ScreenPixelsPromise::CreateAndReject(NS_ERROR_ILLEGAL_VALUE,
+ __func__);
+ }
+
// If a new request is made we no longer care about the result of the previous
// one, so just reject it if it exists.
if (mPendingScreenPixelsRequest) {
@@ -478,7 +484,7 @@ RefPtr<RendererOGL::ScreenPixelsPromise> RendererOGL::RequestScreenPixels(
}
mPendingScreenPixelsRequest.emplace(ScreenPixelsRequest{
.mSourceRect = aSourceRect,
- .mDestSize = aDestSize,
+ .mHardwareBuffer = std::move(aHardwareBuffer),
.mPromise = new ScreenPixelsPromise::Private(__func__),
});
return mPendingScreenPixelsRequest->mPromise;
@@ -491,19 +497,16 @@ void RendererOGL::MaybeCaptureScreenPixels() {
auto request = mPendingScreenPixelsRequest.extract();
- const RefPtr<layers::AndroidHardwareBuffer> hardwareBuffer =
- layers::AndroidHardwareBuffer::Create(request.mDestSize,
- gfx::SurfaceFormat::R8G8B8A8);
-
if (mCompositor->MaybeCaptureScreenPixels(request.mSourceRect,
- hardwareBuffer)) {
- request.mPromise->Resolve(hardwareBuffer, __func__);
+ request.mHardwareBuffer)) {
+ request.mPromise->Resolve(Ok{}, __func__);
return;
}
auto* const gle = gl::GLContextEGL::Cast(gl());
const auto& egl = gle->mEgl;
- gl::ScopedEGLImageForAndroidHardwareBuffer eglImage(gle, hardwareBuffer);
+ gl::ScopedEGLImageForAndroidHardwareBuffer eglImage(gle,
+ request.mHardwareBuffer);
gl::ScopedBindFramebuffer scopedBind(gl());
gl::ScopedRenderbuffer rb(gl());
gl()->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, rb);
@@ -517,7 +520,7 @@ void RendererOGL::MaybeCaptureScreenPixels() {
request.mSourceRect.x,
mCompositor->GetBufferSize().height - request.mSourceRect.y,
request.mSourceRect.width, -request.mSourceRect.height);
- const auto destRect = gfx::IntRect({}, hardwareBuffer->mSize);
+ const auto destRect = gfx::IntRect({}, request.mHardwareBuffer->mSize);
gl()->BindReadFB(0);
gl()->BindDrawFB(fb.FB());
gl()->fBlitFramebuffer(srcRect.x, srcRect.y, srcRect.XMost(), srcRect.YMost(),
@@ -529,12 +532,12 @@ void RendererOGL::MaybeCaptureScreenPixels() {
egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr)) {
auto fence = UniqueFileHandle(egl->fDupNativeFenceFDANDROID(sync));
if (fence) {
- hardwareBuffer->SetAcquireFence(std::move(fence));
+ request.mHardwareBuffer->SetAcquireFence(std::move(fence));
}
egl->fDestroySync(sync);
}
- request.mPromise->Resolve(hardwareBuffer, __func__);
+ request.mPromise->Resolve(Ok{}, __func__);
}
#endif
=====================================
gfx/webrender_bindings/RendererOGL.h
=====================================
@@ -93,12 +93,12 @@ class RendererOGL {
Maybe<layers::FrameRecording> EndRecording();
#ifdef MOZ_WIDGET_ANDROID
- using ScreenPixelsPromise =
- MozPromise<RefPtr<layers::AndroidHardwareBuffer>, nsresult, true>;
+ using ScreenPixelsPromise = MozPromise<Ok, nsresult, true>;
// Captures the pixels for the next rendered frame. Returns a promise that
// resolves once the pixels are captured.
- RefPtr<ScreenPixelsPromise> RequestScreenPixels(gfx::IntRect aSourceRect,
- gfx::IntSize aDestSize);
+ RefPtr<ScreenPixelsPromise> RequestScreenPixels(
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer);
#endif
/// This can be called on the render thread only.
@@ -174,7 +174,7 @@ class RendererOGL {
#ifdef MOZ_WIDGET_ANDROID
struct ScreenPixelsRequest {
gfx::IntRect mSourceRect;
- gfx::IntSize mDestSize;
+ RefPtr<layers::AndroidHardwareBuffer> mHardwareBuffer;
RefPtr<ScreenPixelsPromise::Private> mPromise;
};
Maybe<ScreenPixelsRequest> mPendingScreenPixelsRequest;
=====================================
gfx/webrender_bindings/WebRenderAPI.cpp
=====================================
@@ -962,12 +962,17 @@ RefPtr<WebRenderAPI::EndRecordingPromise> WebRenderAPI::EndRecording() {
#ifdef MOZ_WIDGET_ANDROID
RefPtr<WebRenderAPI::ScreenPixelsPromise> WebRenderAPI::RequestScreenPixels(
- gfx::IntRect aSourceRect, gfx::IntSize aDestSize) {
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer) {
class ScreenshotEvent final : public RendererEvent {
public:
- explicit ScreenshotEvent(gfx::IntRect aSourceRect, gfx::IntSize aDestSize,
- RefPtr<ScreenPixelsPromise::Private> aPromise)
- : mSourceRect(aSourceRect), mDestSize(aDestSize), mPromise(aPromise) {
+ explicit ScreenshotEvent(
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer,
+ RefPtr<ScreenPixelsPromise::Private> aPromise)
+ : mSourceRect(aSourceRect),
+ mHardwareBuffer(std::move(aHardwareBuffer)),
+ mPromise(aPromise) {
MOZ_COUNT_CTOR(ScreenshotEvent);
}
@@ -977,8 +982,9 @@ RefPtr<WebRenderAPI::ScreenPixelsPromise> WebRenderAPI::RequestScreenPixels(
RendererOGL* const renderer = aRenderThread.GetRenderer(aWindowId);
if (!renderer) {
mPromise->Reject(NS_ERROR_FAILURE, __func__);
+ return;
}
- renderer->RequestScreenPixels(mSourceRect, mDestSize)
+ renderer->RequestScreenPixels(mSourceRect, std::move(mHardwareBuffer))
->ChainTo(mPromise.forget(), __func__);
}
@@ -986,12 +992,13 @@ RefPtr<WebRenderAPI::ScreenPixelsPromise> WebRenderAPI::RequestScreenPixels(
private:
const gfx::IntRect mSourceRect;
- const gfx::IntSize mDestSize;
+ RefPtr<layers::AndroidHardwareBuffer> mHardwareBuffer;
RefPtr<ScreenPixelsPromise::Private> mPromise;
};
auto promise = MakeRefPtr<ScreenPixelsPromise::Private>(__func__);
- auto event = MakeUnique<ScreenshotEvent>(aSourceRect, aDestSize, promise);
+ auto event = MakeUnique<ScreenshotEvent>(aSourceRect,
+ std::move(aHardwareBuffer), promise);
RenderThread::Get()->PostEvent(mId, std::move(event));
return promise;
=====================================
gfx/webrender_bindings/WebRenderAPI.h
=====================================
@@ -322,13 +322,13 @@ class WebRenderAPI final {
RefPtr<EndRecordingPromise> EndRecording();
#ifdef MOZ_WIDGET_ANDROID
- using ScreenPixelsPromise =
- MozPromise<RefPtr<layers::AndroidHardwareBuffer>, nsresult, true>;
+ using ScreenPixelsPromise = MozPromise<Ok, nsresult, true>;
// Queues a task to the render thread to capture screen pixels for the next
// rendered frame. Returns a promise that resolves once the pixels are
// captured.
- RefPtr<ScreenPixelsPromise> RequestScreenPixels(gfx::IntRect aSourceRect,
- gfx::IntSize aDestSize);
+ RefPtr<ScreenPixelsPromise> RequestScreenPixels(
+ gfx::IntRect aSourceRect,
+ RefPtr<layers::AndroidHardwareBuffer> aHardwareBuffer);
#endif
layers::RemoteTextureInfoList* GetPendingRemoteTextureInfoList();
=====================================
mobile/android/android-components/components/feature/downloads/src/main/java/mozilla/components/feature/downloads/DownloadsFeature.kt
=====================================
@@ -122,6 +122,8 @@ value class OpenFileCallback(val value: () -> Unit)
* manager is provided, a dialog will be shown before every download.
* @property promptsStyling styling properties for the dialog.
* @property onDownloadStartedListener a callback invoked when a download is started.
+ * @property dismissCustomFirstPartyDownloadDialog A callback invoked when the custom first party
+ * download dialog should be dismissed.
* @property shouldForwardToThirdParties Indicates if downloads should be forward to third party apps,
* if there are multiple apps a chooser dialog will shown.
* @property customFirstPartyDownloadDialog An optional delegate for showing a dialog for a download
@@ -145,6 +147,7 @@ class DownloadsFeature(
private val fragmentManager: FragmentManager? = null,
private val promptsStyling: PromptsStyling? = null,
private val onDownloadStartedListener: ((String) -> Unit) = {},
+ private val dismissCustomFirstPartyDownloadDialog: () -> Unit = {},
private val shouldForwardToThirdParties: () -> Boolean = { false },
private val customFirstPartyDownloadDialog: (
(
@@ -555,6 +558,7 @@ class DownloadsFeature(
internal fun dismissAllDownloadDialogs() {
findPreviousDownloadDialogFragment()?.dismiss()
findPreviousAppDownloaderDialogFragment()?.dismiss()
+ dismissCustomFirstPartyDownloadDialog.invoke()
}
private val ActivityInfo.identifier: String get() = packageName + name
=====================================
mobile/android/android-components/components/feature/downloads/src/test/java/mozilla/components/feature/downloads/DownloadsFeatureTest.kt
=====================================
@@ -1513,6 +1513,64 @@ class DownloadsFeatureTest {
verify(cancelDownloadRequestUseCase).invoke(anyString(), anyString())
}
+ @Test
+ fun `GIVEN a custom download dialog is used WHEN dismissAllDownloadDialogs is called THEN the dialog is dismissed`() = runTest(testDispatcher) {
+ val dismissCustomDialog = mock<() -> Unit>()
+ val feature = DownloadsFeature(
+ testContext,
+ store,
+ useCases = DownloadsUseCases(store, mock()),
+ downloadFileUtils = FakeDownloadFileUtils(),
+ downloadManager = mock(),
+ mainDispatcher = testDispatcher,
+ dismissCustomFirstPartyDownloadDialog = dismissCustomDialog,
+ )
+
+ feature.dismissAllDownloadDialogs()
+
+ verify(dismissCustomDialog).invoke()
+ }
+
+ @Test
+ fun `GIVEN a custom download dialog is used WHEN navigating to another website THEN the dialog is dismissed`() = runTest(testDispatcher) {
+ val dismissCustomDialog = mock<() -> Unit>()
+ val downloadsUseCases = spy(DownloadsUseCases(store, mock()))
+ val cancelDownloadRequestUseCase = mock<CancelDownloadRequestUseCase>()
+ val download = DownloadState(url = "https://www.mozilla.org", sessionId = "test-tab")
+ store.dispatch(ContentAction.UpdateDownloadAction("test-tab", download = download))
+
+ doReturn(cancelDownloadRequestUseCase).`when`(downloadsUseCases).cancelDownloadRequest
+
+ val feature = spy(
+ DownloadsFeature(
+ testContext,
+ store,
+ useCases = downloadsUseCases,
+ downloadFileUtils = FakeDownloadFileUtils(),
+ downloadManager = mock(),
+ mainDispatcher = testDispatcher,
+ dismissCustomFirstPartyDownloadDialog = dismissCustomDialog,
+ ),
+ )
+
+ doReturn(true).`when`(feature).processDownload(any(), any())
+
+ feature.start()
+ testDispatcher.scheduler.advanceUntilIdle()
+
+ store.dispatch(ContentAction.UpdateDownloadAction("test-tab", download = download))
+ testDispatcher.scheduler.advanceUntilIdle()
+
+ grantPermissions()
+
+ val tab = createTab("https://www.firefox.com")
+ store.dispatch(TabListAction.AddTabAction(tab, select = true))
+ testDispatcher.scheduler.advanceUntilIdle()
+
+ verify(feature).dismissAllDownloadDialogs()
+ verify(dismissCustomDialog).invoke()
+ }
+
@Test
fun `ResolveInfo to DownloaderApps`() = runTest(testDispatcher) {
val spyContext = spy(testContext)
=====================================
mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragment.kt
=====================================
@@ -32,6 +32,7 @@ import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.ktx.android.content.appName
import mozilla.components.support.ktx.kotlin.ifNullOrEmpty
import mozilla.components.support.ktx.util.PromptAbuserDetector
+import mozilla.components.support.utils.OnEnterAnimationCompleteListener
internal const val KEY_SESSION_ID = "KEY_SESSION_ID"
internal const val KEY_TITLE = "KEY_TITLE"
@@ -51,7 +52,9 @@ private const val KEY_IS_NOTIFICATION_REQUEST = "KEY_IS_NOTIFICATION_REQUEST"
private const val DEFAULT_VALUE = Int.MAX_VALUE
private const val KEY_PERMISSION_ID = "KEY_PERMISSION_ID"
-internal open class SitePermissionsDialogFragment : NoObscuredTouchesDialogFragment() {
+internal open class SitePermissionsDialogFragment :
+ NoObscuredTouchesDialogFragment(),
+ OnEnterAnimationCompleteListener {
private val logger = Logger("SitePermissionsDialogFragment")
@@ -134,6 +137,11 @@ internal open class SitePermissionsDialogFragment : NoObscuredTouchesDialogFragm
feature?.onDismiss(permissionRequestId, sessionId)
}
+ override fun onEnterAnimationComplete() {
+ // Extend the positive button click delay.
+ promptAbuserDetector.updateJSDialogAbusedState()
+ }
+
private fun Dialog.setContainerView(rootView: View) {
if (dialogShouldWidthMatchParent) {
setContentView(rootView)
=====================================
mobile/android/android-components/components/support/utils/src/main/java/mozilla/components/support/utils/OnEnterAnimationCompleteListener.kt
=====================================
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.support.utils
+
+/**
+ * Allows forwarding [android.app.Activity.onEnterAnimationComplete] to other classes
+ * (e.g. fragments) that want to participate in handling it.
+ */
+interface OnEnterAnimationCompleteListener {
+ /**
+ * Called when the Activity's entering animation has completed.
+ */
+ fun onEnterAnimationComplete()
+}
=====================================
mobile/android/components/geckoview/GeckoViewContentChannelParent.cpp
=====================================
@@ -159,6 +159,11 @@ bool GeckoViewContentChannelParent::Init(
nsCOMPtr<nsIURI> uri = ipc::DeserializeURI(aArgs.uri());
+ if (!uri || !uri->SchemeIs("content")) {
+ rv = NS_ERROR_UNKNOWN_PROTOCOL;
+ return false;
+ }
+
nsAutoCString remoteType;
rv = GetRemoteType(remoteType);
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
=====================================
mobile/android/fenix/app/src/androidTest/java/org/mozilla/fenix/ui/robots/DownloadRobot.kt
=====================================
@@ -29,6 +29,7 @@ import androidx.test.espresso.intent.matcher.IntentMatchers
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
+import mozilla.components.support.ktx.util.PromptAbuserDetector
import org.hamcrest.CoreMatchers.allOf
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.snackbar.SNACKBAR_TEST_TAG
@@ -257,7 +258,9 @@ class DownloadRobot(private val composeTestRule: ComposeTestRule) {
class Transition(private val composeTestRule: ComposeTestRule) {
fun clickDownload(composeTestRule: ComposeTestRule, interact: DownloadRobot.() -> Unit): Transition {
Log.i(TAG, "clickDownload: Trying to click the \"Download\" download prompt button")
+ PromptAbuserDetector.validationsEnabled = false
composeTestRule.downloadButton().performClick()
+ PromptAbuserDetector.validationsEnabled = true
Log.i(TAG, "clickDownload: Clicked the \"Download\" download prompt button")
DownloadRobot(composeTestRule).interact()
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/addons/AddonPopupBaseFragment.kt
=====================================
@@ -161,6 +161,10 @@ abstract class AddonPopupBaseFragment :
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_DOWNLOAD_PERMISSIONS)
},
+ dismissCustomFirstPartyDownloadDialog = {
+ dismissRenameDialog()
+ downloadDialog?.dismiss()
+ },
customFirstPartyDownloadDialog = { currentDownloadState, _, positiveAction, negativeAction, _ ->
run {
if (canShowDownloadDialog()) {
@@ -394,6 +398,13 @@ abstract class AddonPopupBaseFragment :
return downloadDialog == null && !isRenameFragmentShowing
}
+ private fun dismissRenameDialog() {
+ val renameDialog = childFragmentManager.findFragmentByTag(
+ RenameAndChangeLocationDialogFragment.RENAME_AND_CHANGE_LOCATION_DIALOG_TAG,
+ ) as? RenameAndChangeLocationDialogFragment
+ renameDialog?.dismissAllowingStateLoss()
+ }
+
/**
* Forwards activity results to the [ActivityResultHandler] features.
*/
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
=====================================
@@ -742,6 +742,10 @@ abstract class BaseBrowserFragment :
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_DOWNLOAD_PERMISSIONS)
},
+ dismissCustomFirstPartyDownloadDialog = {
+ dismissRenameDialog()
+ dismissDownloadDialogs()
+ },
customFirstPartyDownloadDialog = {
currentDownloadState,
fileNameIfAlreadyDownloaded,
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserActivity.kt
=====================================
@@ -11,6 +11,7 @@ import androidx.annotation.VisibleForTesting
import androidx.core.net.toUri
import mozilla.components.browser.state.selector.findCustomTab
import mozilla.components.browser.state.state.SessionState
+import mozilla.components.support.utils.OnEnterAnimationCompleteListener
import mozilla.components.support.utils.SafeIntent
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.ext.components
@@ -92,5 +93,14 @@ open class ExternalAppBrowserActivity : HomeActivity() {
override fun onEnterAnimationComplete() {
super.onEnterAnimationComplete()
isFinishedAnimating = true
+
+ val fragments = supportFragmentManager.fragments.toMutableList()
+ while (fragments.isNotEmpty()) {
+ val fragment = fragments.removeAt(0)
+ if (fragment is OnEnterAnimationCompleteListener) {
+ fragment.onEnterAnimationComplete()
+ }
+ fragments.addAll(fragment.childFragmentManager.fragments)
+ }
}
}
=====================================
mobile/android/fenix/app/src/main/java/org/mozilla/fenix/downloads/RenameAndChangeLocationDialogFragment.kt
=====================================
@@ -20,6 +20,8 @@ import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import mozilla.components.concept.base.crash.Breadcrumb
import mozilla.components.support.base.log.logger.Logger
+import mozilla.components.support.ktx.util.PromptAbuserDetector
+import mozilla.components.support.utils.OnEnterAnimationCompleteListener
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.requireComponents
@@ -38,10 +40,12 @@ import org.mozilla.fenix.theme.FirefoxTheme
*
* The callback [onConfirmSave] is invoked with the final file name and directory path.
*/
-class RenameAndChangeLocationDialogFragment : DialogFragment() {
+class RenameAndChangeLocationDialogFragment : DialogFragment(), OnEnterAnimationCompleteListener {
private val logger = Logger("RenameAndChangeLocationDialogFragment")
private val safeArguments get() = requireNotNull(arguments)
+ private val promptAbuserDetector = PromptAbuserDetector(TIME_SHOWN_OFFSET_MILLIS)
+
internal val fileName: String
get() = safeArguments.getString(KEY_FILE_NAME, "")
@@ -75,6 +79,15 @@ class RenameAndChangeLocationDialogFragment : DialogFragment() {
}
}
+ override fun onResume() {
+ super.onResume()
+ promptAbuserDetector.start()
+ }
+
+ override fun onEnterAnimationComplete() {
+ promptAbuserDetector.start()
+ }
+
override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog)
onCancel()
@@ -99,6 +112,8 @@ class RenameAndChangeLocationDialogFragment : DialogFragment() {
val composeView = createComposeView()
+ promptAbuserDetector.start()
+
return MaterialAlertDialogBuilder(requireContext())
.setView(composeView)
.create()
@@ -144,11 +159,15 @@ class RenameAndChangeLocationDialogFragment : DialogFragment() {
directoryLauncher.launch(null)
},
onConfirm = {
- onConfirmSave(
- dialogState.fileName,
- dialogState.directoryPath,
- )
- dismiss()
+ if (promptAbuserDetector.areDialogsBeingAbused()) {
+ promptAbuserDetector.updateJSDialogAbusedState()
+ } else {
+ onConfirmSave(
+ dialogState.fileName,
+ dialogState.directoryPath,
+ )
+ dismiss()
+ }
},
onCancel = {
onCancel()
@@ -182,6 +201,7 @@ class RenameAndChangeLocationDialogFragment : DialogFragment() {
private const val KEY_DIRECTORY_PATH = "directory_path"
private const val KEY_CONTENT_SIZE = "content_size"
const val RENAME_AND_CHANGE_LOCATION_DIALOG_TAG = "RENAME_AND_CHANGE_LOCATION_DIALOG_TAG"
+ private const val TIME_SHOWN_OFFSET_MILLIS = 500
/**
* Creates a new instance of [RenameAndChangeLocationDialogFragment].
@@ -203,3 +223,14 @@ class RenameAndChangeLocationDialogFragment : DialogFragment() {
}
}
}
+
+/**
+ * Starts (or restarts) the time-based check without increasing the "click count".
+ *
+ * Makes it safe to call from multiple/successive lifecycle methods, without running into the risk
+ * of triggering the more restrictive count-based protection on the 1st click (or even before it).
+ */
+private fun PromptAbuserDetector.start() {
+ resetJSAlertAbuseState()
+ updateJSDialogAbusedState()
+}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/9857f6…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/9857f6…
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
[Git][tpo/applications/mullvad-browser][mullvad-browser-153.1.0esr-16.0-1] fixup! BB 44711: Hide unwanted setting controls in Base Browser.
by Pier Angelo Vendrame (@pierov) 17 Aug '26
by Pier Angelo Vendrame (@pierov) 17 Aug '26
17 Aug '26
Pier Angelo Vendrame pushed to branch mullvad-browser-153.1.0esr-16.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
61089e28 by Henry Wilkes at 2026-08-17T09:36:39+02:00
fixup! BB 44711: Hide unwanted setting controls in Base Browser.
BB 44831: Hide the search suggestions private browsing banner.
- - - - -
1 changed file:
- browser/components/preferences/config/search.mjs
Changes:
=====================================
browser/components/preferences/config/search.mjs
=====================================
@@ -12,6 +12,7 @@ const { XPCOMUtils } = ChromeUtils.importESModule(
const lazy = XPCOMUtils.declareLazy({
AddonSearchEngine:
"moz-src:///toolkit/components/search/AddonSearchEngine.sys.mjs",
+ AppConstants: "resource://gre/modules/AppConstants.sys.mjs",
ConfigSearchEngine:
"moz-src:///toolkit/components/search/ConfigSearchEngine.sys.mjs",
CustomizableUI:
@@ -428,6 +429,11 @@ Preferences.addSetting({
id: "urlBarSuggestionPermanentPBMessage",
deps: ["urlBarSuggestionCheckbox", "permanentPBEnabledPref"],
visible: deps => {
+ // Hide since the wording is misleading about the default history settings.
+ // tor-browser#44831.
+ if (lazy.AppConstants.BASE_BROWSER_VERSION) {
+ return false;
+ }
return (
deps.urlBarSuggestionCheckbox.visible && deps.permanentPBEnabledPref.value
);
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/610…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/commit/610…
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
[Git][tpo/applications/tor-browser-build][main] Bump Firefox version to 153.1.0esr for nightly builds.
by Pier Angelo Vendrame (@pierov) 17 Aug '26
by Pier Angelo Vendrame (@pierov) 17 Aug '26
17 Aug '26
Pier Angelo Vendrame pushed to branch main at The Tor Project / Applications / tor-browser-build
Commits:
250cce38 by Pier Angelo Vendrame at 2026-08-17T09:34:50+02:00
Bump Firefox version to 153.1.0esr for nightly builds.
- - - - -
2 changed files:
- projects/firefox/config
- projects/geckoview/config
Changes:
=====================================
projects/firefox/config
=====================================
@@ -18,12 +18,12 @@ container:
use_container: 1
var:
- firefox_platform_version: '153.0'
+ firefox_platform_version: '153.1.0'
firefox_version: '[% c("var/firefox_platform_version") %]esr'
browser_series: '16.0'
browser_rebase: 1
browser_branch: '[% c("var/browser_series") %]-[% c("var/browser_rebase") %]'
- browser_build: 2
+ browser_build: 1
upstream_firefox_commit: FIREFOX_NIGHTLY_153_END
copyright_year: '[% exec("git show -s --format=%ci " _ c("git_hash") _ "^{commit}", { exec_noco => 1 }).remove("-.*") %]'
nightly_updates_publish_dir: '[% c("var/nightly_updates_publish_dir_prefix") %]nightly-[% c("var/osname") %]'
=====================================
projects/geckoview/config
=====================================
@@ -21,12 +21,12 @@ container:
build_apk: '[% !c("var/online_build") %]'
var:
- firefox_platform_version: '153.0'
+ firefox_platform_version: '153.1.0'
geckoview_version: '[% c("var/firefox_platform_version") %]esr'
browser_series: '16.0'
browser_rebase: 1
browser_branch: '[% c("var/browser_series") %]-[% c("var/browser_rebase") %]'
- browser_build: 2
+ browser_build: 1
gitlab_project: https://gitlab.torproject.org/tpo/applications/tor-browser
git_commit: '[% exec("git rev-parse " _ c("git_hash") _ "^{commit}", { exec_noco => 1 }) %]'
deps:
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/2…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/2…
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
[Git][tpo/applications/mullvad-browser] Pushed new tag mullvad-browser-153.1.0esr-16.0-1-build1
by Pier Angelo Vendrame (@pierov) 17 Aug '26
by Pier Angelo Vendrame (@pierov) 17 Aug '26
17 Aug '26
Pier Angelo Vendrame pushed new tag mullvad-browser-153.1.0esr-16.0-1-build1 at The Tor Project / Applications / Mullvad Browser
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/tree/mullv…
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
[Git][tpo/applications/mullvad-browser] Pushed new tag mullvad-browser-140.14.0esr-15.0-1-build1
by Pier Angelo Vendrame (@pierov) 17 Aug '26
by Pier Angelo Vendrame (@pierov) 17 Aug '26
17 Aug '26
Pier Angelo Vendrame pushed new tag mullvad-browser-140.14.0esr-15.0-1-build1 at The Tor Project / Applications / Mullvad Browser
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/tree/mullv…
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
[Git][tpo/applications/mullvad-browser][mullvad-browser-153.1.0esr-16.0-1] 31 commits: Add CI for Mullvad Browser
by Pier Angelo Vendrame (@pierov) 17 Aug '26
by Pier Angelo Vendrame (@pierov) 17 Aug '26
17 Aug '26
Pier Angelo Vendrame pushed to branch mullvad-browser-153.1.0esr-16.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
400dd15f by Henry Wilkes at 2026-08-13T16:57:25+02:00
Add CI for Mullvad Browser
- - - - -
feb7516d by Pier Angelo Vendrame at 2026-08-13T16:57:25+02:00
MB 38: Mullvad Browser configuration
- - - - -
6a86b740 by Pier Angelo Vendrame at 2026-08-13T16:57:25+02:00
MB 1: Mullvad Browser branding
See also:
mullvad-browser#5: Product name and directory customization
mullvad-browser#12: Create new branding directories and integrate Mullvad icons+branding
mullvad-browser#14: Remove Default Built-in bookmarks
mullvad-browser#35: Add custom PDF icons for Windows builds
mullvad-browser#48: Replace Mozilla copyright and legal trademarks in mullvadbrowser.exe metadata
mullvad-browser#51: Update trademark string
mullvad-browser#104: Update shipped dll metadata copyright/licensing info
mullvad-browser#107: Add alpha and nightly icons
- - - - -
78b3fcd1 by Pier Angelo Vendrame at 2026-08-13T17:17:11+02:00
fixup! MB 1: Mullvad Browser branding
MB 563: Hide Firefox's icon in about:pdf promo.
- - - - -
5e84686e by Henry Wilkes at 2026-08-13T17:17:11+02:00
Mullvad Browser strings
This commit adds strings needed by the following Mullvad Browser
patches.
- - - - -
1e439dc0 by Pier Angelo Vendrame at 2026-08-13T17:17:11+02:00
MB 20: Allow packaged-addons in PBM.
We install a few addons from the distribution directory, but they are
not automatically enabled for PBM mode.
This commit modifies the code that installs them to also add the PBM
permission to the known ones.
- - - - -
b705f3db by Pier Angelo Vendrame at 2026-08-13T17:17:12+02:00
MB 63: Customize some about pages for Mullvad Browser
Also:
mullvad-browser#57: Purge unneeded about: pages
- - - - -
713638a3 by Pier Angelo Vendrame at 2026-08-13T17:17:12+02:00
MB 37: Customization for the about dialog
- - - - -
6497726a by Henry Wilkes at 2026-08-13T17:17:12+02:00
MB 39: Add home page about:mullvad-browser
- - - - -
d172ee5a by Pier Angelo Vendrame at 2026-08-13T17:17:13+02:00
fixup! MB 39: Add home page about:mullvad-browser
MB 564: Fix about:mullvadbrowser colors.
- - - - -
6792933b by hackademix at 2026-08-13T17:17:13+02:00
MB 97: Remove UI cues to install new extensions.
- - - - -
e1a166d6 by Pier Angelo Vendrame at 2026-08-13T17:17:13+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.
- - - - -
36288a26 by hackademix at 2026-08-13T17:17:14+02:00
MB 47: uBlock Origin customization
- - - - -
d6f9a738 by Pier Angelo Vendrame at 2026-08-13T17:17:14+02:00
MB 21: Disable the password manager
This commit disables the about:login page and removes the "Login and
Password" section of about:preferences.
We do not do anything to the real password manager of Firefox, that is
in toolkit: it contains C++ parts that make it difficult to actually
prevent it from being built..
Finally, we modify the the function that opens about:login to report an
error in the console so that we can quickly get a backtrace to the code
that tries to use it.
- - - - -
59cfe688 by Pier Angelo Vendrame at 2026-08-13T17:17:14+02:00
fixup! MB 21: Disable the password manager
MB 538: Use settings config for our customization.
- - - - -
8e602851 by Pier Angelo Vendrame at 2026-08-13T17:17:15+02:00
MB 112: Updater customization for Mullvad Browser
MB 71: Set the updater base URL to Mullvad domain
- - - - -
250e79c0 by Nicolas Vigier at 2026-08-13T17:17:15+02:00
MB 79: Add Mullvad Browser MAR signing keys
MB 256: Add mullvad-browser nightly mar signing key
- - - - -
dc37cd48 by Pier Angelo Vendrame at 2026-08-13T17:17:15+02:00
MB 34: Hide unsafe and unwanted preferences UI
about:preferences allow to override some of our defaults, that could
be fingeprintable or have some other unwanted consequences.
- - - - -
887adbde by Henry Wilkes at 2026-08-13T17:17:16+02:00
amend! MB 34: Hide unsafe and unwanted preferences UI
MB 34: Hide unwanted setting controls in Mullvad Browser.
- - - - -
f2c51c96 by hackademix at 2026-08-13T17:17:16+02:00
MB 163: Prevent uBlock Origin from being uninstalled/disabled
- - - - -
84eaaeb3 by Pier Angelo Vendrame at 2026-08-13T17:17:16+02:00
MB 160: Disable the cookie exceptions button
Besides disabling the "Delete on close checkbox", disable also the
"Manage Exceptions" button when always using PBM.
- - - - -
a4036117 by Richard Pospesel at 2026-08-13T17:17:17+02:00
MB 188: Customize Gitlab Issue and Merge templates
- - - - -
0fe15e0f by rui hildt at 2026-08-13T17:17:17+02:00
MB 213: Customize the search engines list.
- - - - -
a5492f10 by hackademix at 2026-08-13T17:17:17+02:00
MB 214: Enable cross-tab identity leak protection in "quiet" mode
- - - - -
cf577ca0 by Pier Angelo Vendrame at 2026-08-13T17:17:18+02:00
MB 320: Temporarily disable WebRTC and WDBA on Windows.
WebRTC should be re-enabled when tor-browser#42758 is resolved, and and
the default browser agent when in general we make this feature work
again.
- - - - -
1a65f0a5 by Henry Wilkes at 2026-08-13T17:17:18+02:00
MB 329: Customize toolbar for mullvad-browser.
- - - - -
96fb24b5 by Henry Wilkes at 2026-08-13T17:17:18+02:00
MB 419: Mullvad Browser migration procedures.
This commit implements the the Mullvad Browser's version of _migrateUI.
- - - - -
5fe86d90 by Henry Wilkes at 2026-08-13T17:17:19+02:00
MB 488: Adjust search engine removal notification for Mullvad Leta.
- - - - -
6685cd2a by Pier Angelo Vendrame at 2026-08-13T17:17:19+02:00
MB 80: Enable Mullvad Browser as a default browser
- - - - -
15886959 by Beatriz Rizental at 2026-08-13T17:17:19+02:00
MB 43564: Modify ./mach bootstrap for Mullvad Browser
- - - - -
a080ab7f by june wilde at 2026-08-13T17:17:20+02:00
MB 446: Selective Saving Mode Backend
- - - - -
273 changed files:
- .gitlab/ci/jobs/update-translations.yml
- .gitlab/issue_templates/000 Bug Report.md
- .gitlab/issue_templates/010 Proposal.md
- .gitlab/issue_templates/020 Web Compatibility.md
- .gitlab/issue_templates/030 Test.md
- .gitlab/issue_templates/040 Feature.md
- .gitlab/issue_templates/041 Time-Gated Feature.md
- .gitlab/issue_templates/051 Revert.md
- + .gitlab/issue_templates/060 Rebase - Alpha.md
- + .gitlab/issue_templates/061 Rebase - Stable.md
- .gitlab/issue_templates/090 Emergency Security Issue.md
- .gitlab/merge_request_templates/Default.md
- + .gitlab/merge_request_templates/Rebase.md
- browser/app/Makefile.in
- browser/app/macbuild/Contents/Info.plist.in
- browser/app/module.ver
- browser/app/firefox.exe.manifest → browser/app/mullvadbrowser.exe.manifest
- + browser/app/profile/000-mullvad-browser.js
- browser/app/profile/001-base-profile.js
- browser/base/content/aboutDialog.xhtml
- browser/base/content/appmenu-viewcache.inc.xhtml
- browser/base/content/browser-menubar.inc.xhtml
- browser/base/content/browser-places.js
- browser/base/content/browser.js
- browser/base/content/default-bookmarks.html
- browser/base/content/nsContextMenu.sys.mjs
- browser/base/content/overrides/app-license.html
- browser/base/content/pageinfo/pageInfo.xhtml
- browser/base/content/utilityOverlay.js
- browser/branding/branding-common.mozbuild
- + browser/branding/mb-alpha/VisualElements_150.png
- + browser/branding/mb-alpha/VisualElements_70.png
- + browser/branding/mb-alpha/configure.sh
- + browser/branding/mb-alpha/content/about-logo.png
- + browser/branding/mb-alpha/content/about-logo.svg
- + browser/branding/mb-alpha/content/about-logo(a)2x.png
- + browser/branding/mb-alpha/content/about-wordmark.svg
- + browser/branding/mb-alpha/content/about.png
- + browser/branding/mb-alpha/content/aboutDialog.css
- + browser/branding/mb-alpha/content/document_pdf.svg
- + browser/branding/mb-alpha/content/firefox-wordmark.svg
- + browser/branding/mb-alpha/content/icon128.png
- + browser/branding/mb-alpha/content/icon16.png
- + browser/branding/mb-alpha/content/icon256.png
- + browser/branding/mb-alpha/content/icon32.png
- + browser/branding/mb-alpha/content/icon48.png
- + browser/branding/mb-alpha/content/icon64.png
- + browser/branding/mb-alpha/content/jar.mn
- + browser/branding/mb-alpha/content/moz.build
- + browser/branding/mb-alpha/content/mullvad-branding.css
- + browser/branding/mb-alpha/default128.png
- + browser/branding/mb-alpha/default16.png
- + browser/branding/mb-alpha/default22.png
- + browser/branding/mb-alpha/default24.png
- + browser/branding/mb-alpha/default256.png
- + browser/branding/mb-alpha/default32.png
- + browser/branding/mb-alpha/default48.png
- + browser/branding/mb-alpha/default64.png
- + browser/branding/mb-alpha/document.icns
- + browser/branding/mb-alpha/document.ico
- + browser/branding/mb-alpha/document_pdf.ico
- + browser/branding/mb-alpha/firefox.icns
- + browser/branding/mb-alpha/firefox.ico
- + browser/branding/mb-alpha/firefox.svg
- + browser/branding/mb-alpha/locales/en-US/brand.ftl
- + browser/branding/mb-alpha/locales/en-US/brand.properties
- + browser/branding/mb-alpha/locales/jar.mn
- + browser/branding/mb-alpha/locales/moz.build
- + browser/branding/mb-alpha/locales/mullvad-about-wordmark-en.ftl
- + browser/branding/mb-alpha/moz.build
- + browser/branding/mb-alpha/mullvadbrowser.VisualElementsManifest.xml
- + browser/branding/mb-alpha/newtab.ico
- + browser/branding/mb-alpha/newwindow.ico
- + browser/branding/mb-alpha/pbmode.ico
- + browser/branding/mb-alpha/pref/firefox-branding.js
- + browser/branding/mb-nightly/VisualElements_150.png
- + browser/branding/mb-nightly/VisualElements_70.png
- + browser/branding/mb-nightly/configure.sh
- + browser/branding/mb-nightly/content/about-logo.png
- + browser/branding/mb-nightly/content/about-logo.svg
- + browser/branding/mb-nightly/content/about-logo(a)2x.png
- + browser/branding/mb-nightly/content/about-wordmark.svg
- + browser/branding/mb-nightly/content/about.png
- + browser/branding/mb-nightly/content/aboutDialog.css
- + browser/branding/mb-nightly/content/document_pdf.svg
- + browser/branding/mb-nightly/content/firefox-wordmark.svg
- + browser/branding/mb-nightly/content/icon128.png
- + browser/branding/mb-nightly/content/icon16.png
- + browser/branding/mb-nightly/content/icon256.png
- + browser/branding/mb-nightly/content/icon32.png
- + browser/branding/mb-nightly/content/icon48.png
- + browser/branding/mb-nightly/content/icon64.png
- + browser/branding/mb-nightly/content/jar.mn
- + browser/branding/mb-nightly/content/moz.build
- + browser/branding/mb-nightly/content/mullvad-branding.css
- + browser/branding/mb-nightly/default128.png
- + browser/branding/mb-nightly/default16.png
- + browser/branding/mb-nightly/default22.png
- + browser/branding/mb-nightly/default24.png
- + browser/branding/mb-nightly/default256.png
- + browser/branding/mb-nightly/default32.png
- + browser/branding/mb-nightly/default48.png
- + browser/branding/mb-nightly/default64.png
- + browser/branding/mb-nightly/document.icns
- + browser/branding/mb-nightly/document.ico
- + browser/branding/mb-nightly/document_pdf.ico
- + browser/branding/mb-nightly/firefox.icns
- + browser/branding/mb-nightly/firefox.ico
- + browser/branding/mb-nightly/firefox.svg
- + browser/branding/mb-nightly/locales/en-US/brand.ftl
- + browser/branding/mb-nightly/locales/en-US/brand.properties
- + browser/branding/mb-nightly/locales/jar.mn
- + browser/branding/mb-nightly/locales/moz.build
- + browser/branding/mb-nightly/locales/mullvad-about-wordmark-en.ftl
- + browser/branding/mb-nightly/moz.build
- + browser/branding/mb-nightly/mullvadbrowser.VisualElementsManifest.xml
- + browser/branding/mb-nightly/newtab.ico
- + browser/branding/mb-nightly/newwindow.ico
- + browser/branding/mb-nightly/pbmode.ico
- + browser/branding/mb-nightly/pref/firefox-branding.js
- + browser/branding/mb-release/VisualElements_150.png
- + browser/branding/mb-release/VisualElements_70.png
- + browser/branding/mb-release/configure.sh
- + browser/branding/mb-release/content/about-logo.png
- + browser/branding/mb-release/content/about-logo.svg
- + browser/branding/mb-release/content/about-logo(a)2x.png
- + browser/branding/mb-release/content/about-wordmark.svg
- + browser/branding/mb-release/content/about.png
- + browser/branding/mb-release/content/aboutDialog.css
- + browser/branding/mb-release/content/document_pdf.svg
- + browser/branding/mb-release/content/firefox-wordmark.svg
- + browser/branding/mb-release/content/icon128.png
- + browser/branding/mb-release/content/icon16.png
- + browser/branding/mb-release/content/icon256.png
- + browser/branding/mb-release/content/icon32.png
- + browser/branding/mb-release/content/icon48.png
- + browser/branding/mb-release/content/icon64.png
- + browser/branding/mb-release/content/jar.mn
- + browser/branding/mb-release/content/moz.build
- + browser/branding/mb-release/content/mullvad-branding.css
- + browser/branding/mb-release/default128.png
- + browser/branding/mb-release/default16.png
- + browser/branding/mb-release/default22.png
- + browser/branding/mb-release/default24.png
- + browser/branding/mb-release/default256.png
- + browser/branding/mb-release/default32.png
- + browser/branding/mb-release/default48.png
- + browser/branding/mb-release/default64.png
- + browser/branding/mb-release/document.icns
- + browser/branding/mb-release/document.ico
- + browser/branding/mb-release/document_pdf.ico
- + browser/branding/mb-release/firefox.icns
- + browser/branding/mb-release/firefox.ico
- + browser/branding/mb-release/firefox.svg
- + browser/branding/mb-release/locales/en-US/brand.ftl
- + browser/branding/mb-release/locales/en-US/brand.properties
- + browser/branding/mb-release/locales/jar.mn
- + browser/branding/mb-release/locales/moz.build
- + browser/branding/mb-release/locales/mullvad-about-wordmark-en.ftl
- + browser/branding/mb-release/moz.build
- + browser/branding/mb-release/mullvadbrowser.VisualElementsManifest.xml
- + browser/branding/mb-release/newtab.ico
- + browser/branding/mb-release/newwindow.ico
- + browser/branding/mb-release/pbmode.ico
- + browser/branding/mb-release/pref/firefox-branding.js
- browser/components/BrowserContentHandler.sys.mjs
- browser/components/BrowserGlue.sys.mjs
- browser/components/DesktopActorRegistry.sys.mjs
- browser/components/ProfileDataUpgrader.sys.mjs
- browser/components/about/AboutRedirector.cpp
- browser/components/about/components.conf
- browser/components/customizableui/CustomizableUI.sys.mjs
- browser/components/moz.build
- + browser/components/mullvad-browser/AboutMullvadBrowserChild.sys.mjs
- + browser/components/mullvad-browser/AboutMullvadBrowserParent.sys.mjs
- + browser/components/mullvad-browser/content/2728-sparkles.svg
- + browser/components/mullvad-browser/content/aboutMullvadBrowser.css
- + browser/components/mullvad-browser/content/aboutMullvadBrowser.html
- + browser/components/mullvad-browser/content/aboutMullvadBrowser.js
- + browser/components/mullvad-browser/jar.mn
- + browser/components/mullvad-browser/moz.build
- browser/components/preferences/config/passwords-autofill.mjs
- browser/components/preferences/config/privacy.mjs
- browser/components/preferences/config/search.mjs
- browser/components/preferences/home.inc.xhtml
- browser/components/preferences/preferences.js
- browser/components/preferences/preferences.xhtml
- browser/components/preferences/privacy.inc.xhtml
- browser/components/preferences/search.inc.xhtml
- browser/components/search/SearchUIUtils.sys.mjs
- browser/components/shell/ShellService.sys.mjs
- browser/components/shell/WindowsDefaultBrowser.cpp
- browser/components/shell/nsWindowsShellService.cpp
- browser/components/tabbrowser/NewTabPagePreloading.sys.mjs
- browser/config/mozconfigs/base-browser
- + browser/config/mozconfigs/mullvad-browser
- browser/installer/package-manifest.in
- browser/installer/windows/nsis/updater_append.ini
- browser/locales/l10n.toml
- browser/modules/HomePage.sys.mjs
- browser/moz.build
- browser/moz.configure
- build/moz.configure/basebrowser-resources.configure
- build/moz.configure/bootstrap.configure
- config/create_rc.py
- devtools/client/aboutdebugging/src/actions/runtimes.js
- devtools/client/aboutdebugging/src/components/sidebar/Sidebar.js
- devtools/client/jar.mn
- devtools/client/themes/images/aboutdebugging-firefox-aurora.svg
- devtools/client/themes/images/aboutdebugging-firefox-beta.svg
- devtools/client/themes/images/aboutdebugging-firefox-logo.svg
- devtools/client/themes/images/aboutdebugging-firefox-nightly.svg
- devtools/client/themes/images/aboutdebugging-firefox-release.svg
- + devtools/client/themes/images/aboutdebugging-mullvadbrowser-logo.svg
- docshell/base/nsAboutRedirector.cpp
- docshell/build/components.conf
- moz.configure
- mozconfig-linux-aarch64
- mozconfig-linux-aarch64-dev
- mozconfig-linux-x86_64
- mozconfig-linux-x86_64-asan
- mozconfig-linux-x86_64-dev
- mozconfig-macos
- mozconfig-macos-dev
- mozconfig-windows-x86_64
- + other-licenses/nsis/Contrib/ApplicationID/Makefile
- other-licenses/nsis/Contrib/ApplicationID/Set.cpp
- + other-licenses/nsis/Contrib/CityHash/Makefile
- python/mozboot/mozboot/bootstrap.py
- python/mozbuild/mozbuild/backend/base.py
- python/mozbuild/mozbuild/tbbutils.py
- toolkit/components/aboutpdf/content/aboutPDF.html
- toolkit/components/extensions/child/ext-storage.js
- toolkit/components/extensions/parent/ext-storage.js
- toolkit/components/moz.build
- toolkit/components/passwordmgr/LoginHelper.sys.mjs
- toolkit/components/remote/nsDBusRemoteClient.cpp
- toolkit/components/remote/nsDBusRemoteServer.cpp
- toolkit/components/search/SearchService.sys.mjs
- toolkit/components/search/content/base-browser-search-engine-icons.json
- toolkit/components/search/content/base-browser-search-engines.json
- + toolkit/components/search/content/brave.svg
- + toolkit/components/search/content/mojeek.ico
- toolkit/components/search/tests/xpcshell/test_base_browser.js
- toolkit/components/securitylevel/SecurityLevel.sys.mjs
- + toolkit/components/selectivesavingmode/SelectiveSavingMode.manifest
- + toolkit/components/selectivesavingmode/SelectiveSavingMode.sys.mjs
- + toolkit/components/selectivesavingmode/components.conf
- + toolkit/components/selectivesavingmode/content/broom-clean.svg
- + toolkit/components/selectivesavingmode/content/broom-saved.svg
- + toolkit/components/selectivesavingmode/jar.mn
- + toolkit/components/selectivesavingmode/moz.build
- + toolkit/components/selectivesavingmode/tests/xpcshell/test_selective_saving_mode.js
- + toolkit/components/selectivesavingmode/tests/xpcshell/xpcshell.toml
- + toolkit/content/aboutTelemetryMullvad.xhtml
- toolkit/content/jar.mn
- + toolkit/locales/en-US/toolkit/global/mullvad-browser.ftl
- toolkit/mozapps/defaultagent/EventLog.h
- toolkit/mozapps/defaultagent/SetDefaultBrowser.cpp
- toolkit/mozapps/extensions/AddonManager.sys.mjs
- toolkit/mozapps/extensions/content/aboutaddons.css
- toolkit/mozapps/extensions/internal/XPIDatabase.sys.mjs
- toolkit/mozapps/extensions/internal/XPIProvider.sys.mjs
- toolkit/mozapps/update/updater/nightly_aurora_level3_primary.der
- toolkit/mozapps/update/updater/nightly_aurora_level3_secondary.der
- toolkit/mozapps/update/updater/release_primary.der
- toolkit/mozapps/update/updater/release_secondary.der
- + toolkit/themes/shared/icons/mullvadbrowser.png
- toolkit/themes/shared/minimal-toolkit.jar.inc.mn
- toolkit/xre/nsAppRunner.cpp
- tools/lint/fluent-lint/exclusions.yml
- widget/windows/WinTaskbar.cpp
- widget/windows/moz.build
The diff was not included because it is too large.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/06…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/06…
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
[Git][tpo/applications/mullvad-browser][mullvad-browser-140.14.0esr-15.0-1] 24 commits: Add CI for Mullvad Browser
by Pier Angelo Vendrame (@pierov) 17 Aug '26
by Pier Angelo Vendrame (@pierov) 17 Aug '26
17 Aug '26
Pier Angelo Vendrame pushed to branch mullvad-browser-140.14.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
17bead2c by Henry Wilkes at 2026-08-13T16:46:14+02:00
Add CI for Mullvad Browser
- - - - -
8dbffa79 by Pier Angelo Vendrame at 2026-08-13T16:46:14+02:00
MB 38: Mullvad Browser configuration
- - - - -
3431c07b by Pier Angelo Vendrame at 2026-08-13T16:46:15+02:00
MB 1: Mullvad Browser branding
See also:
mullvad-browser#5: Product name and directory customization
mullvad-browser#12: Create new branding directories and integrate Mullvad icons+branding
mullvad-browser#14: Remove Default Built-in bookmarks
mullvad-browser#35: Add custom PDF icons for Windows builds
mullvad-browser#48: Replace Mozilla copyright and legal trademarks in mullvadbrowser.exe metadata
mullvad-browser#51: Update trademark string
mullvad-browser#104: Update shipped dll metadata copyright/licensing info
mullvad-browser#107: Add alpha and nightly icons
- - - - -
ec3f63ee by Henry Wilkes at 2026-08-13T16:46:15+02:00
Mullvad Browser strings
This commit adds strings needed by the following Mullvad Browser
patches.
- - - - -
17f71b7a by Pier Angelo Vendrame at 2026-08-13T16:46:15+02:00
MB 20: Allow packaged-addons in PBM.
We install a few addons from the distribution directory, but they are
not automatically enabled for PBM mode.
This commit modifies the code that installs them to also add the PBM
permission to the known ones.
- - - - -
1708dae2 by Pier Angelo Vendrame at 2026-08-13T16:46:15+02:00
MB 63: Customize some about pages for Mullvad Browser
Also:
mullvad-browser#57: Purge unneeded about: pages
- - - - -
84db7f20 by Pier Angelo Vendrame at 2026-08-13T16:46:16+02:00
MB 37: Customization for the about dialog
- - - - -
9f20cf7f by Henry Wilkes at 2026-08-13T16:46:16+02:00
MB 39: Add home page about:mullvad-browser
- - - - -
6cb7117b by hackademix at 2026-08-13T16:46:16+02:00
MB 97: Remove UI cues to install new extensions.
- - - - -
9799ed3d by hackademix at 2026-08-13T16:46:16+02:00
MB 47: uBlock Origin customization
- - - - -
fd4cdb58 by Pier Angelo Vendrame at 2026-08-13T16:46:17+02:00
MB 21: Disable the password manager
This commit disables the about:login page and removes the "Login and
Password" section of about:preferences.
We do not do anything to the real password manager of Firefox, that is
in toolkit: it contains C++ parts that make it difficult to actually
prevent it from being built..
Finally, we modify the the function that opens about:login to report an
error in the console so that we can quickly get a backtrace to the code
that tries to use it.
- - - - -
32b0425a by Pier Angelo Vendrame at 2026-08-13T16:46:17+02:00
MB 112: Updater customization for Mullvad Browser
MB 71: Set the updater base URL to Mullvad domain
- - - - -
464b56c8 by Nicolas Vigier at 2026-08-13T16:46:17+02:00
MB 79: Add Mullvad Browser MAR signing keys
MB 256: Add mullvad-browser nightly mar signing key
- - - - -
0db049c4 by Pier Angelo Vendrame at 2026-08-13T16:46:17+02:00
MB 34: Hide unsafe and unwanted preferences UI
about:preferences allow to override some of our defaults, that could
be fingeprintable or have some other unwanted consequences.
- - - - -
b2546533 by Pier Angelo Vendrame at 2026-08-13T16:46:18+02:00
MB 160: Disable the cookie exceptions button
Besides disabling the "Delete on close checkbox", disable also the
"Manage Exceptions" button when always using PBM.
- - - - -
4c68d944 by hackademix at 2026-08-13T16:46:18+02:00
MB 163: prevent uBlock Origin from being uninstalled/disabled
- - - - -
009442b1 by Pier Angelo Vendrame at 2026-08-13T16:46:18+02:00
MB 188: Customize Gitlab Issue and Merge templates
- - - - -
1b0dba09 by Pier Angelo Vendrame at 2026-08-13T16:46:18+02:00
MB 213: Customize the search engines list.
MB 483: Ship DDG without AI as a bundled search engine.
MB 487: Use custom order for search engines.
- - - - -
2780d8fe by hackademix at 2026-08-13T16:46:19+02:00
MB 214: Enable cross-tab identity leak protection in "quiet" mode
- - - - -
c3eb0cab by Pier Angelo Vendrame at 2026-08-13T16:46:19+02:00
MB 80: Enable Mullvad Browser as a default browser
- - - - -
686c4bec by Pier Angelo Vendrame at 2026-08-13T16:46:19+02:00
MB 320: Temporarily disable WebRTC and WDBA on Windows.
WebRTC should be re-enabled when tor-browser#42758 is resolved, and and
the default browser agent when in general we make this feature work
again.
- - - - -
d81605a9 by Henry Wilkes at 2026-08-13T16:46:19+02:00
MB 329: Customize toolbar for mullvad-browser.
- - - - -
b6e4f471 by Henry Wilkes at 2026-08-13T16:46:20+02:00
MB 419: Mullvad Browser migration procedures.
This commit implements the the Mullvad Browser's version of _migrateUI.
- - - - -
d1a3c1a8 by Henry Wilkes at 2026-08-13T16:46:20+02:00
MB 488: Adjust search engine removal notification for Mullvad Leta.
- - - - -
253 changed files:
- .gitlab/ci/jobs/update-translations.yml
- .gitlab/issue_templates/000 Bug Report.md
- .gitlab/issue_templates/010 Proposal.md
- .gitlab/issue_templates/020 Web Compatibility.md
- .gitlab/issue_templates/030 Test.md
- .gitlab/issue_templates/040 Feature.md
- .gitlab/issue_templates/060 Rebase - Alpha.md
- .gitlab/issue_templates/061 Rebase - Stable.md
- .gitlab/issue_templates/063 Rebase - Rapid.md
- .gitlab/issue_templates/090 Emergency Security Issue.md
- .gitlab/merge_request_templates/Default.md
- + .gitlab/merge_request_templates/Rebase.md
- browser/app/Makefile.in
- browser/app/macbuild/Contents/Info.plist.in
- browser/app/module.ver
- browser/app/firefox.exe.manifest → browser/app/mullvadbrowser.exe.manifest
- + browser/app/profile/000-mullvad-browser.js
- browser/app/profile/001-base-profile.js
- browser/base/content/aboutDialog.xhtml
- browser/base/content/appmenu-viewcache.inc.xhtml
- browser/base/content/browser-menubar.inc
- browser/base/content/browser-places.js
- browser/base/content/browser.js
- browser/base/content/default-bookmarks.html
- browser/base/content/nsContextMenu.sys.mjs
- browser/base/content/overrides/app-license.html
- browser/base/content/pageinfo/pageInfo.xhtml
- browser/base/content/utilityOverlay.js
- browser/branding/branding-common.mozbuild
- + browser/branding/mb-alpha/VisualElements_150.png
- + browser/branding/mb-alpha/VisualElements_70.png
- + browser/branding/mb-alpha/configure.sh
- + browser/branding/mb-alpha/content/about-logo.png
- + browser/branding/mb-alpha/content/about-logo.svg
- + browser/branding/mb-alpha/content/about-logo(a)2x.png
- + browser/branding/mb-alpha/content/about-wordmark.svg
- + browser/branding/mb-alpha/content/about.png
- + browser/branding/mb-alpha/content/aboutDialog.css
- + browser/branding/mb-alpha/content/document_pdf.svg
- + browser/branding/mb-alpha/content/firefox-wordmark.svg
- + browser/branding/mb-alpha/content/icon128.png
- + browser/branding/mb-alpha/content/icon16.png
- + browser/branding/mb-alpha/content/icon256.png
- + browser/branding/mb-alpha/content/icon32.png
- + browser/branding/mb-alpha/content/icon48.png
- + browser/branding/mb-alpha/content/icon64.png
- + browser/branding/mb-alpha/content/jar.mn
- + browser/branding/mb-alpha/content/moz.build
- + browser/branding/mb-alpha/content/mullvad-branding.css
- + browser/branding/mb-alpha/default128.png
- + browser/branding/mb-alpha/default16.png
- + browser/branding/mb-alpha/default22.png
- + browser/branding/mb-alpha/default24.png
- + browser/branding/mb-alpha/default256.png
- + browser/branding/mb-alpha/default32.png
- + browser/branding/mb-alpha/default48.png
- + browser/branding/mb-alpha/default64.png
- + browser/branding/mb-alpha/document.icns
- + browser/branding/mb-alpha/document.ico
- + browser/branding/mb-alpha/document_pdf.ico
- + browser/branding/mb-alpha/firefox.icns
- + browser/branding/mb-alpha/firefox.ico
- + browser/branding/mb-alpha/firefox.svg
- + browser/branding/mb-alpha/locales/en-US/brand.ftl
- + browser/branding/mb-alpha/locales/en-US/brand.properties
- + browser/branding/mb-alpha/locales/jar.mn
- + browser/branding/mb-alpha/locales/moz.build
- + browser/branding/mb-alpha/locales/mullvad-about-wordmark-en.ftl
- + browser/branding/mb-alpha/moz.build
- + browser/branding/mb-alpha/mullvadbrowser.VisualElementsManifest.xml
- + browser/branding/mb-alpha/newtab.ico
- + browser/branding/mb-alpha/newwindow.ico
- + browser/branding/mb-alpha/pbmode.ico
- + browser/branding/mb-alpha/pref/firefox-branding.js
- + browser/branding/mb-nightly/VisualElements_150.png
- + browser/branding/mb-nightly/VisualElements_70.png
- + browser/branding/mb-nightly/configure.sh
- + browser/branding/mb-nightly/content/about-logo.png
- + browser/branding/mb-nightly/content/about-logo.svg
- + browser/branding/mb-nightly/content/about-logo(a)2x.png
- + browser/branding/mb-nightly/content/about-wordmark.svg
- + browser/branding/mb-nightly/content/about.png
- + browser/branding/mb-nightly/content/aboutDialog.css
- + browser/branding/mb-nightly/content/document_pdf.svg
- + browser/branding/mb-nightly/content/firefox-wordmark.svg
- + browser/branding/mb-nightly/content/icon128.png
- + browser/branding/mb-nightly/content/icon16.png
- + browser/branding/mb-nightly/content/icon256.png
- + browser/branding/mb-nightly/content/icon32.png
- + browser/branding/mb-nightly/content/icon48.png
- + browser/branding/mb-nightly/content/icon64.png
- + browser/branding/mb-nightly/content/jar.mn
- + browser/branding/mb-nightly/content/moz.build
- + browser/branding/mb-nightly/content/mullvad-branding.css
- + browser/branding/mb-nightly/default128.png
- + browser/branding/mb-nightly/default16.png
- + browser/branding/mb-nightly/default22.png
- + browser/branding/mb-nightly/default24.png
- + browser/branding/mb-nightly/default256.png
- + browser/branding/mb-nightly/default32.png
- + browser/branding/mb-nightly/default48.png
- + browser/branding/mb-nightly/default64.png
- + browser/branding/mb-nightly/document.icns
- + browser/branding/mb-nightly/document.ico
- + browser/branding/mb-nightly/document_pdf.ico
- + browser/branding/mb-nightly/firefox.icns
- + browser/branding/mb-nightly/firefox.ico
- + browser/branding/mb-nightly/firefox.svg
- + browser/branding/mb-nightly/locales/en-US/brand.ftl
- + browser/branding/mb-nightly/locales/en-US/brand.properties
- + browser/branding/mb-nightly/locales/jar.mn
- + browser/branding/mb-nightly/locales/moz.build
- + browser/branding/mb-nightly/locales/mullvad-about-wordmark-en.ftl
- + browser/branding/mb-nightly/moz.build
- + browser/branding/mb-nightly/mullvadbrowser.VisualElementsManifest.xml
- + browser/branding/mb-nightly/newtab.ico
- + browser/branding/mb-nightly/newwindow.ico
- + browser/branding/mb-nightly/pbmode.ico
- + browser/branding/mb-nightly/pref/firefox-branding.js
- + browser/branding/mb-release/VisualElements_150.png
- + browser/branding/mb-release/VisualElements_70.png
- + browser/branding/mb-release/configure.sh
- + browser/branding/mb-release/content/about-logo.png
- + browser/branding/mb-release/content/about-logo.svg
- + browser/branding/mb-release/content/about-logo(a)2x.png
- + browser/branding/mb-release/content/about-wordmark.svg
- + browser/branding/mb-release/content/about.png
- + browser/branding/mb-release/content/aboutDialog.css
- + browser/branding/mb-release/content/document_pdf.svg
- + browser/branding/mb-release/content/firefox-wordmark.svg
- + browser/branding/mb-release/content/icon128.png
- + browser/branding/mb-release/content/icon16.png
- + browser/branding/mb-release/content/icon256.png
- + browser/branding/mb-release/content/icon32.png
- + browser/branding/mb-release/content/icon48.png
- + browser/branding/mb-release/content/icon64.png
- + browser/branding/mb-release/content/jar.mn
- + browser/branding/mb-release/content/moz.build
- + browser/branding/mb-release/content/mullvad-branding.css
- + browser/branding/mb-release/default128.png
- + browser/branding/mb-release/default16.png
- + browser/branding/mb-release/default22.png
- + browser/branding/mb-release/default24.png
- + browser/branding/mb-release/default256.png
- + browser/branding/mb-release/default32.png
- + browser/branding/mb-release/default48.png
- + browser/branding/mb-release/default64.png
- + browser/branding/mb-release/document.icns
- + browser/branding/mb-release/document.ico
- + browser/branding/mb-release/document_pdf.ico
- + browser/branding/mb-release/firefox.icns
- + browser/branding/mb-release/firefox.ico
- + browser/branding/mb-release/firefox.svg
- + browser/branding/mb-release/locales/en-US/brand.ftl
- + browser/branding/mb-release/locales/en-US/brand.properties
- + browser/branding/mb-release/locales/jar.mn
- + browser/branding/mb-release/locales/moz.build
- + browser/branding/mb-release/locales/mullvad-about-wordmark-en.ftl
- + browser/branding/mb-release/moz.build
- + browser/branding/mb-release/mullvadbrowser.VisualElementsManifest.xml
- + browser/branding/mb-release/newtab.ico
- + browser/branding/mb-release/newwindow.ico
- + browser/branding/mb-release/pbmode.ico
- + browser/branding/mb-release/pref/firefox-branding.js
- browser/components/BrowserContentHandler.sys.mjs
- browser/components/BrowserGlue.sys.mjs
- browser/components/DesktopActorRegistry.sys.mjs
- browser/components/ProfileDataUpgrader.sys.mjs
- browser/components/about/AboutRedirector.cpp
- browser/components/about/components.conf
- browser/components/customizableui/CustomizableUI.sys.mjs
- browser/components/moz.build
- + browser/components/mullvad-browser/AboutMullvadBrowserChild.sys.mjs
- + browser/components/mullvad-browser/AboutMullvadBrowserParent.sys.mjs
- + browser/components/mullvad-browser/content/2728-sparkles.svg
- + browser/components/mullvad-browser/content/aboutMullvadBrowser.css
- + browser/components/mullvad-browser/content/aboutMullvadBrowser.html
- + browser/components/mullvad-browser/content/aboutMullvadBrowser.js
- + browser/components/mullvad-browser/jar.mn
- + browser/components/mullvad-browser/moz.build
- browser/components/preferences/home.inc.xhtml
- browser/components/preferences/main.js
- browser/components/preferences/preferences.xhtml
- browser/components/preferences/privacy.inc.xhtml
- browser/components/preferences/privacy.js
- browser/components/preferences/search.inc.xhtml
- browser/components/search/SearchUIUtils.sys.mjs
- browser/components/shell/ShellService.sys.mjs
- browser/components/shell/WindowsDefaultBrowser.cpp
- browser/components/shell/nsWindowsShellService.cpp
- browser/components/tabbrowser/NewTabPagePreloading.sys.mjs
- browser/config/mozconfigs/base-browser
- + browser/config/mozconfigs/mullvad-browser
- browser/installer/package-manifest.in
- browser/installer/windows/nsis/updater_append.ini
- browser/locales/l10n.toml
- browser/modules/HomePage.sys.mjs
- browser/moz.build
- browser/moz.configure
- config/create_rc.py
- devtools/client/aboutdebugging/src/actions/runtimes.js
- devtools/client/aboutdebugging/src/components/sidebar/Sidebar.js
- devtools/client/jar.mn
- devtools/client/themes/images/aboutdebugging-firefox-aurora.svg
- devtools/client/themes/images/aboutdebugging-firefox-beta.svg
- devtools/client/themes/images/aboutdebugging-firefox-logo.svg
- devtools/client/themes/images/aboutdebugging-firefox-nightly.svg
- devtools/client/themes/images/aboutdebugging-firefox-release.svg
- + devtools/client/themes/images/aboutdebugging-mullvadbrowser-logo.svg
- docshell/base/nsAboutRedirector.cpp
- docshell/build/components.conf
- moz.configure
- mozconfig-linux-aarch64
- mozconfig-linux-aarch64-dev
- mozconfig-linux-x86_64
- mozconfig-linux-x86_64-asan
- mozconfig-linux-x86_64-dev
- mozconfig-macos
- mozconfig-macos-dev
- mozconfig-windows-x86_64
- + other-licenses/nsis/Contrib/ApplicationID/Makefile
- other-licenses/nsis/Contrib/ApplicationID/Set.cpp
- + other-licenses/nsis/Contrib/CityHash/Makefile
- toolkit/components/extensions/child/ext-storage.js
- toolkit/components/extensions/parent/ext-storage.js
- toolkit/components/passwordmgr/LoginHelper.sys.mjs
- toolkit/components/search/SearchService.sys.mjs
- toolkit/components/search/content/base-browser-search-engine-icons.json
- toolkit/components/search/content/base-browser-search-engines.json
- + toolkit/components/search/content/brave.svg
- + toolkit/components/search/content/mojeek.ico
- toolkit/components/search/tests/xpcshell/test_base_browser.js
- toolkit/components/securitylevel/SecurityLevel.sys.mjs
- + toolkit/content/aboutRightsMullvad.xhtml
- + toolkit/content/aboutTelemetryMullvad.xhtml
- toolkit/content/jar.mn
- + toolkit/locales/en-US/toolkit/global/mullvad-browser.ftl
- toolkit/mozapps/defaultagent/EventLog.h
- toolkit/mozapps/defaultagent/SetDefaultBrowser.cpp
- toolkit/mozapps/extensions/AddonManager.sys.mjs
- toolkit/mozapps/extensions/content/aboutaddons.css
- toolkit/mozapps/extensions/internal/XPIDatabase.sys.mjs
- toolkit/mozapps/extensions/internal/XPIProvider.sys.mjs
- toolkit/mozapps/update/updater/nightly_aurora_level3_primary.der
- toolkit/mozapps/update/updater/nightly_aurora_level3_secondary.der
- toolkit/mozapps/update/updater/release_primary.der
- toolkit/mozapps/update/updater/release_secondary.der
- + toolkit/themes/shared/icons/mullvadbrowser.png
- toolkit/themes/shared/minimal-toolkit.jar.inc.mn
- toolkit/xre/nsAppRunner.cpp
- tools/lint/fluent-lint/exclusions.yml
- widget/windows/WinTaskbar.cpp
- widget/windows/moz.build
The diff was not included because it is too large.
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/34…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/34…
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
[Git][tpo/applications/tor-browser-build][main] Bug 41851: Prepare Tor VPN 1.9.0Beta
by Dan Ballard (@dan) 14 Aug '26
by Dan Ballard (@dan) 14 Aug '26
14 Aug '26
Dan Ballard pushed to branch main at The Tor Project / Applications / tor-browser-build
Commits:
7076ba2e by Nicolas Vigier at 2026-08-14T09:31:09+02:00
Bug 41851: Prepare Tor VPN 1.9.0Beta
- - - - -
1 changed file:
- rbm.conf
Changes:
=====================================
rbm.conf
=====================================
@@ -341,9 +341,9 @@ targets:
torvpn:
var:
tor-vpn: 1
- torbrowser_version: '1.8.0Beta'
+ torbrowser_version: '1.9.0Beta'
torbrowser_build: 'build1'
- browser_release_date: '2026/06/25 10:00:00'
+ browser_release_date: '2026/08/14 07:30:00'
project-name: tor-vpn
projectname: torvpn
Project_Name: 'Tor VPN'
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