tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 8c0f16b2545cdbc3f3e34ccf8dea42d2ca8a951a
parent 56635eab0757ee86d92de23c1e950fb7c86d0dde
Author: Tom Schuster <tschuster@mozilla.com>
Date:   Mon, 10 Nov 2025 14:09:15 +0000

Bug 1944033 - Update Linux/MPRIS to use the image from the child. r=media-playback-reviewers,aosmond

Differential Revision: https://phabricator.services.mozilla.com/D271046

Diffstat:
Mdom/media/mediacontrol/MediaControlUtils.h | 13++++++++++---
Mwidget/gtk/MPRISServiceHandler.cpp | 121+++++++++++++++++++------------------------------------------------------------
Mwidget/gtk/MPRISServiceHandler.h | 10----------
3 files changed, 38 insertions(+), 106 deletions(-)

diff --git a/dom/media/mediacontrol/MediaControlUtils.h b/dom/media/mediacontrol/MediaControlUtils.h @@ -15,6 +15,8 @@ #include "mozilla/dom/MediaControllerBinding.h" #include "nsReadableUtils.h" #include "nsServiceManagerUtils.h" +#include "gfxDrawable.h" +#include "ImageOps.h" extern mozilla::LazyLogModule gMediaControlLog; @@ -94,19 +96,24 @@ inline bool IsImageIn(const nsTArray<MediaImage>& aArtwork, // The image buffer would be allocated in aStream whose size is aSize and the // buffer head is aBuffer -inline nsresult GetEncodedImageBuffer(imgIContainer* aImage, +inline nsresult GetEncodedImageBuffer(gfx::DataSourceSurface* aSurface, const nsACString& aMimeType, nsIInputStream** aStream, uint32_t* aSize, char** aBuffer) { - MOZ_ASSERT(aImage); + MOZ_ASSERT(aSurface); nsCOMPtr<imgITools> imgTools = do_GetService("@mozilla.org/image/tools;1"); if (!imgTools) { return NS_ERROR_FAILURE; } + RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable( + aSurface, aSurface->GetSize()); + nsCOMPtr<imgIContainer> image = + image::ImageOps::CreateFromDrawable(drawable); + nsCOMPtr<nsIInputStream> inputStream; - nsresult rv = imgTools->EncodeImage(aImage, aMimeType, u""_ns, + nsresult rv = imgTools->EncodeImage(image, aMimeType, u""_ns, getter_AddRefs(inputStream)); if (NS_FAILED(rv)) { return rv; diff --git a/widget/gtk/MPRISServiceHandler.cpp b/widget/gtk/MPRISServiceHandler.cpp @@ -531,38 +531,37 @@ GVariant* MPRISServiceHandler::GetPlaybackStatus() const { void MPRISServiceHandler::SetMediaMetadata( const dom::MediaMetadataBase& aMetadata) { - // Reset the index of the next available image to be fetched in the artwork, - // before checking the fetching process should be started or not. The image - // fetching process could be skipped if the image being fetching currently is - // in the artwork. If the current image fetching fails, the next availabe - // candidate should be the first image in the latest artwork - mNextImageIndex = 0; - - // No need to fetch a MPRIS image if - // 1) MPRIS image is being fetched, and the one in fetching is in the artwork - // 2) MPRIS image is not being fetched, and the one in use is in the artwork - if (!mFetchingUrl.IsEmpty()) { - if (dom::IsImageIn(aMetadata.mArtwork, mFetchingUrl)) { - LOGMPRIS( - "No need to load MPRIS image. The one being processed is in the " - "artwork"); - // Set MPRIS without the image first. The image will be loaded to MPRIS - // asynchronously once it's fetched and saved into a local file - SetMediaMetadataInternal(aMetadata); - return; + SetMediaMetadataInternal(aMetadata); + + for (const dom::MediaImageData& image : aMetadata.mArtwork) { + if (!image.mDataSurface) { + continue; } - } else if (!mCurrentImageUrl.IsEmpty()) { - if (dom::IsImageIn(aMetadata.mArtwork, mCurrentImageUrl)) { - LOGMPRIS("No need to load MPRIS image. The one in use is in the artwork"); - SetMediaMetadataInternal(aMetadata, false); - return; + + if (mCurrentImageUrl == image.mSrc) { + LOGMPRIS("Artwork image URL did not change"); + break; } - } - // Set MPRIS without the image first then load the image to MPRIS - // asynchronously - SetMediaMetadataInternal(aMetadata); - LoadImageAtIndex(mNextImageIndex++); + uint32_t size = 0; + char* data = nullptr; + // Only used to hold the image data + nsCOMPtr<nsIInputStream> inputStream; + + nsresult rv = dom::GetEncodedImageBuffer( + image.mDataSurface, mMimeType, getter_AddRefs(inputStream), &size, &data); + if (NS_FAILED(rv) || !inputStream || size == 0 || !data) { + LOGMPRIS("Failed to get the image buffer info. Try next image"); + continue; + } + + if (SetImageToDisplay(data, size)) { + mCurrentImageUrl = image.mSrc; + LOGMPRIS("The MPRIS image is updated to the image from: %s", + NS_ConvertUTF16toUTF8(mCurrentImageUrl).get()); + break; + } + } } bool MPRISServiceHandler::EmitMetadataChanged() const { @@ -588,76 +587,12 @@ void MPRISServiceHandler::SetMediaMetadataInternal( void MPRISServiceHandler::ClearMetadata() { mMPRISMetadata.Clear(); - mImageFetchRequest.DisconnectIfExists(); RemoveAllLocalImages(); mCurrentImageUrl.Truncate(); - mFetchingUrl.Truncate(); - mNextImageIndex = 0; mSupportedKeys = 0; EmitMetadataChanged(); } -void MPRISServiceHandler::LoadImageAtIndex(const size_t aIndex) { - MOZ_ASSERT(NS_IsMainThread()); - - if (aIndex >= mMPRISMetadata.mArtwork.Length()) { - LOGMPRIS("Stop loading image to MPRIS. No available image"); - mImageFetchRequest.DisconnectIfExists(); - return; - } - - const dom::MediaImage& image = mMPRISMetadata.mArtwork[aIndex]; - - if (!dom::IsValidImageUrl(image.mSrc)) { - LOGMPRIS("Skip the image with invalid URL. Try next image"); - LoadImageAtIndex(mNextImageIndex++); - return; - } - - mImageFetchRequest.DisconnectIfExists(); - mFetchingUrl = image.mSrc; - - mImageFetcher = MakeUnique<dom::FetchImageHelper>(image); - RefPtr<MPRISServiceHandler> self = this; - mImageFetcher->FetchImage() - ->Then( - AbstractThread::MainThread(), __func__, - [this, self](const nsCOMPtr<imgIContainer>& aImage) { - LOGMPRIS("The image is fetched successfully"); - mImageFetchRequest.Complete(); - - uint32_t size = 0; - char* data = nullptr; - // Only used to hold the image data - nsCOMPtr<nsIInputStream> inputStream; - nsresult rv = dom::GetEncodedImageBuffer( - aImage, mMimeType, getter_AddRefs(inputStream), &size, &data); - if (NS_FAILED(rv) || !inputStream || size == 0 || !data) { - LOGMPRIS("Failed to get the image buffer info. Try next image"); - LoadImageAtIndex(mNextImageIndex++); - return; - } - - if (SetImageToDisplay(data, size)) { - mCurrentImageUrl = mFetchingUrl; - LOGMPRIS("The MPRIS image is updated to the image from: %s", - NS_ConvertUTF16toUTF8(mCurrentImageUrl).get()); - } else { - LOGMPRIS("Failed to set image to MPRIS"); - mCurrentImageUrl.Truncate(); - } - - mFetchingUrl.Truncate(); - }, - [this, self](bool) { - LOGMPRIS("Failed to fetch image. Try next image"); - mImageFetchRequest.Complete(); - mFetchingUrl.Truncate(); - LoadImageAtIndex(mNextImageIndex++); - }) - ->Track(mImageFetchRequest); -} - bool MPRISServiceHandler::SetImageToDisplay(const char* aImageData, uint32_t aDataSize) { if (!RenewLocalImageFile(aImageData, aDataSize)) { diff --git a/widget/gtk/MPRISServiceHandler.h b/widget/gtk/MPRISServiceHandler.h @@ -8,7 +8,6 @@ #define WIDGET_GTK_MPRIS_SERVICE_HANDLER_H_ #include <gio/gio.h> -#include "mozilla/dom/FetchImageHelper.h" #include "mozilla/dom/MediaControlKeySource.h" #include "mozilla/UniquePtr.h" #include "nsIFile.h" @@ -140,17 +139,8 @@ class MPRISServiceHandler final : public dom::MediaControlKeySource { nsCOMPtr<nsIFile> mLocalImageFile; nsCOMPtr<nsIFile> mLocalImageFolder; - UniquePtr<dom::FetchImageHelper> mImageFetcher; - MozPromiseRequestHolder<dom::ImagePromise> mImageFetchRequest; - - nsString mFetchingUrl; nsString mCurrentImageUrl; - size_t mNextImageIndex = 0; - - // Load the image at index aIndex of the metadta's artwork to MPRIS - // asynchronously - void LoadImageAtIndex(const size_t aIndex); bool SetImageToDisplay(const char* aImageData, uint32_t aDataSize); bool RenewLocalImageFile(const char* aImageData, uint32_t aDataSize);