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:
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);