Title: [282307] trunk
Revision
282307
Author
[email protected]
Date
2021-09-11 04:34:42 -0700 (Sat, 11 Sep 2021)

Log Message

[GLIB] MediaSession is not enabled
https://bugs.webkit.org/show_bug.cgi?id=217991
<rdar://problem/70740119>

Reviewed by Michael Catanzaro.

.:

Enable MediaSession as an experimental build feature in CMake ports. The spec status is
currently Draft.

* Source/cmake/OptionsGTK.cmake:
* Source/cmake/OptionsWPE.cmake:
* Source/cmake/WebKitFeatures.cmake:

Source/WebCore:

Implementation of a GLib MediaSessionManager, able to provide a MPRIS DBus service, so that
third-party host tools can query the media playback status and potentially emit remote
control commands as well.

Covered by media-session layout tests now unskipped.

* Modules/mediasession/MediaImage.h:
* Modules/mediasession/MediaSession.cpp:
(WebCore::logChannel):
(WebCore::logClassName):
* Modules/mediasession/MediaSession.h:
* PlatformGTK.cmake:
* PlatformWPE.cmake:
* platform/LogInitialization.cpp:
(WebCore::getLogChannel):
* platform/PlatformScreen.h:
* platform/RemoteCommandListener.cpp:
(WebCore::RemoteCommandListener::resetCreationFunction):
* platform/SourcesGLib.txt:
* platform/audio/PlatformMediaSessionManager.cpp:
* platform/audio/glib/MediaSessionManagerGLib.cpp: Added.
(WebCore::PlatformMediaSessionManager::create):
(WebCore::MediaSessionManagerGLib::MediaSessionManagerGLib):
(WebCore::MediaSessionManagerGLib::~MediaSessionManagerGLib):
(WebCore::getCommand):
(WebCore::handleMethodCall):
(WebCore::getProperty):
(WebCore::handleGetProperty):
(WebCore::handleSetProperty):
(WebCore::MediaSessionManagerGLib::setupMpris):
(WebCore::MediaSessionManagerGLib::busAcquired):
(WebCore::MediaSessionManagerGLib::nameLost):
(WebCore::MediaSessionManagerGLib::beginInterruption):
(WebCore::MediaSessionManagerGLib::scheduleSessionStatusUpdate):
(WebCore::MediaSessionManagerGLib::sessionWillBeginPlayback):
(WebCore::MediaSessionManagerGLib::sessionDidEndRemoteScrubbing):
(WebCore::MediaSessionManagerGLib::addSession):
(WebCore::MediaSessionManagerGLib::removeSession):
(WebCore::MediaSessionManagerGLib::setCurrentSession):
(WebCore::MediaSessionManagerGLib::sessionWillEndPlayback):
(WebCore::MediaSessionManagerGLib::sessionStateChanged):
(WebCore::MediaSessionManagerGLib::clientCharacteristicsChanged):
(WebCore::MediaSessionManagerGLib::sessionCanProduceAudioChanged):
(WebCore::MediaSessionManagerGLib::addSupportedCommand):
(WebCore::MediaSessionManagerGLib::removeSupportedCommand):
(WebCore::MediaSessionManagerGLib::nowPlayingEligibleSession):
(WebCore::MediaSessionManagerGLib::updateNowPlayingInfo):
(WebCore::MediaSessionManagerGLib::getPlaybackStatusAsGVariant):
(WebCore::MediaSessionManagerGLib::getActiveSessionPosition):
(WebCore::MediaSessionManagerGLib::dispatch):
(WebCore::MediaSessionManagerGLib::emitPropertiesChanged):
* platform/audio/glib/MediaSessionManagerGLib.h: Added.
(WebCore::MediaSessionManagerGLib::nameAcquired):
(WebCore::MediaSessionManagerGLib::getMetadataAsGVariant const):
(WebCore::MediaSessionManagerGLib::providePresentingApplicationPIDIfNecessary):
* platform/glib/ApplicationGLib.cpp: Added.
(WebCore::setApplicationName):
(WebCore::getApplicationName):
(WebCore::setApplicationID):
(WebCore::getApplicationID):
* platform/glib/ApplicationGLib.h: Added.
* platform/glib/RemoteCommandListenerGLib.cpp: Added.
(WebCore::RemoteCommandListenerGLib::create):
(WebCore::RemoteCommandListenerGLib::updateSupportedCommands):
(WebCore::RemoteCommandListenerGLib::RemoteCommandListenerGLib):
* platform/glib/RemoteCommandListenerGLib.h: Added.
* platform/graphics/ImageFrame.h:
* platform/graphics/ImageOrientation.h:

Source/WebKit:

Pass Application name and unique ID from the UIProcess to the WebProcess in WPE and GTK
ports. The Bubblewrap launcher was also adapted to allow DBus MPRIS name ownership in the
sandboxed WebProcess.

* Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode const):
(WebKit::WebProcessCreationParameters::decode):
* Shared/WebProcessCreationParameters.h:
* UIProcess/API/glib/WebKitSettings.cpp:
(webKitSettingsConstructed):
* UIProcess/Launcher/glib/BubblewrapLauncher.cpp:
(WebKit::applicationId):
(WebKit::createFlatpakInfo):
(WebKit::XDGDBusProxyLauncher::launch):
* UIProcess/glib/WebProcessPoolGLib.cpp:
(WebKit::WebProcessPool::platformInitializeWebProcess):
* WebProcess/glib/WebProcessGLib.cpp:
(WebKit::WebProcess::platformInitializeWebProcess):

Source/WTF:

GRefPtr template specialization for GDBusNodeInfo.

* wtf/glib/GRefPtr.cpp:
(WTF::refGPtr):
(WTF::derefGPtr):
* wtf/glib/GRefPtr.h:

LayoutTests:

* platform/glib/TestExpectations: Unskip media-session tests.

Modified Paths

Added Paths

Diff

Modified: trunk/ChangeLog (282306 => 282307)


--- trunk/ChangeLog	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/ChangeLog	2021-09-11 11:34:42 UTC (rev 282307)
@@ -1,3 +1,18 @@
+2021-09-11  Philippe Normand  <[email protected]>
+
+        [GLIB] MediaSession is not enabled
+        https://bugs.webkit.org/show_bug.cgi?id=217991
+        <rdar://problem/70740119>
+
+        Reviewed by Michael Catanzaro.
+
+        Enable MediaSession as an experimental build feature in CMake ports. The spec status is
+        currently Draft.
+
+        * Source/cmake/OptionsGTK.cmake:
+        * Source/cmake/OptionsWPE.cmake:
+        * Source/cmake/WebKitFeatures.cmake:
+
 2021-09-08  Justin Michaud  <[email protected]>
 
         Change Justin Michaud's primary email to apple.com

Modified: trunk/LayoutTests/ChangeLog (282306 => 282307)


--- trunk/LayoutTests/ChangeLog	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/LayoutTests/ChangeLog	2021-09-11 11:34:42 UTC (rev 282307)
@@ -1,3 +1,13 @@
+2021-09-11  Philippe Normand  <[email protected]>
+
+        [GLIB] MediaSession is not enabled
+        https://bugs.webkit.org/show_bug.cgi?id=217991
+        <rdar://problem/70740119>
+
+        Reviewed by Michael Catanzaro.
+
+        * platform/glib/TestExpectations: Unskip media-session tests.
+
 2021-09-10  Alan Bujtas  <[email protected]>
 
         [Legacy Line Layout] Do not integral round the root inlinebox's top position

Modified: trunk/LayoutTests/platform/glib/TestExpectations (282306 => 282307)


--- trunk/LayoutTests/platform/glib/TestExpectations	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/LayoutTests/platform/glib/TestExpectations	2021-09-11 11:34:42 UTC (rev 282307)
@@ -1418,11 +1418,6 @@
 # Failing since added in r268138.
 webkit.org/b/217815 imported/w3c/web-platform-tests/css/css-masking/clip-path/clip-path-filter-order.html [ ImageOnlyFailure ]
 
-# MediaSession is not enabled in GTK/WPE.
-webkit.org/b/217991 imported/w3c/web-platform-tests/mediasession/ [ Skip ]
-webkit.org/b/217991 media/media-session/ [ Skip ]
-webkit.org/b/217991 fast/mediasession/ [ Skip ]
-
 # This test uses an MPEG-4 video
 media/video-seek-to-current-time.html [ Skip ]
 

Modified: trunk/Source/WTF/ChangeLog (282306 => 282307)


--- trunk/Source/WTF/ChangeLog	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WTF/ChangeLog	2021-09-11 11:34:42 UTC (rev 282307)
@@ -1,3 +1,18 @@
+2021-09-11  Philippe Normand  <[email protected]>
+
+        [GLIB] MediaSession is not enabled
+        https://bugs.webkit.org/show_bug.cgi?id=217991
+        <rdar://problem/70740119>
+
+        Reviewed by Michael Catanzaro.
+
+        GRefPtr template specialization for GDBusNodeInfo.
+
+        * wtf/glib/GRefPtr.cpp:
+        (WTF::refGPtr):
+        (WTF::derefGPtr):
+        * wtf/glib/GRefPtr.h:
+
 2021-09-10  Alex Christensen  <[email protected]>
 
         Use std::not_fn instead of lambda in URLParser

Modified: trunk/Source/WTF/wtf/glib/GRefPtr.cpp (282306 => 282307)


--- trunk/Source/WTF/wtf/glib/GRefPtr.cpp	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WTF/wtf/glib/GRefPtr.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -195,6 +195,19 @@
         g_date_time_unref(ptr);
 }
 
+template <> GDBusNodeInfo* refGPtr(GDBusNodeInfo* ptr)
+{
+    if (ptr)
+        g_dbus_node_info_ref(ptr);
+    return ptr;
+}
+
+template <> void derefGPtr(GDBusNodeInfo* ptr)
+{
+    if (ptr)
+        g_dbus_node_info_unref(ptr);
+}
+
 #if HAVE(GURI)
 template <> GUri* refGPtr(GUri* ptr)
 {

Modified: trunk/Source/WTF/wtf/glib/GRefPtr.h (282306 => 282307)


--- trunk/Source/WTF/wtf/glib/GRefPtr.h	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WTF/wtf/glib/GRefPtr.h	2021-09-11 11:34:42 UTC (rev 282307)
@@ -24,10 +24,15 @@
 
 #if USE(GLIB)
 
-#include <wtf/HashTraits.h>
 #include <algorithm>
 #include <glib.h>
+#include <wtf/HashTraits.h>
 
+extern "C" {
+    typedef struct _GDBusNodeInfo GDBusNodeInfo;
+    GDBusNodeInfo* g_dbus_node_info_ref(GDBusNodeInfo*);
+    void g_dbus_node_info_unref(GDBusNodeInfo*);
+};
 extern "C" void g_object_unref(gpointer);
 extern "C" gpointer g_object_ref_sink(gpointer);
 
@@ -242,6 +247,8 @@
 template <> WTF_EXPORT_PRIVATE void derefGPtr(GMappedFile*);
 template <> WTF_EXPORT_PRIVATE GDateTime* refGPtr(GDateTime* ptr);
 template <> WTF_EXPORT_PRIVATE void derefGPtr(GDateTime* ptr);
+template <> WTF_EXPORT_PRIVATE GDBusNodeInfo* refGPtr(GDBusNodeInfo* ptr);
+template <> WTF_EXPORT_PRIVATE void derefGPtr(GDBusNodeInfo* ptr);
 
 #if HAVE(GURI)
 template <> WTF_EXPORT_PRIVATE GUri* refGPtr(GUri*);

Modified: trunk/Source/WebCore/ChangeLog (282306 => 282307)


--- trunk/Source/WebCore/ChangeLog	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/ChangeLog	2021-09-11 11:34:42 UTC (rev 282307)
@@ -1,3 +1,80 @@
+2021-09-11  Philippe Normand  <[email protected]>
+
+        [GLIB] MediaSession is not enabled
+        https://bugs.webkit.org/show_bug.cgi?id=217991
+        <rdar://problem/70740119>
+
+        Reviewed by Michael Catanzaro.
+
+        Implementation of a GLib MediaSessionManager, able to provide a MPRIS DBus service, so that
+        third-party host tools can query the media playback status and potentially emit remote
+        control commands as well.
+
+        Covered by media-session layout tests now unskipped.
+
+        * Modules/mediasession/MediaImage.h:
+        * Modules/mediasession/MediaSession.cpp:
+        (WebCore::logChannel):
+        (WebCore::logClassName):
+        * Modules/mediasession/MediaSession.h:
+        * PlatformGTK.cmake:
+        * PlatformWPE.cmake:
+        * platform/LogInitialization.cpp:
+        (WebCore::getLogChannel):
+        * platform/PlatformScreen.h:
+        * platform/RemoteCommandListener.cpp:
+        (WebCore::RemoteCommandListener::resetCreationFunction):
+        * platform/SourcesGLib.txt:
+        * platform/audio/PlatformMediaSessionManager.cpp:
+        * platform/audio/glib/MediaSessionManagerGLib.cpp: Added.
+        (WebCore::PlatformMediaSessionManager::create):
+        (WebCore::MediaSessionManagerGLib::MediaSessionManagerGLib):
+        (WebCore::MediaSessionManagerGLib::~MediaSessionManagerGLib):
+        (WebCore::getCommand):
+        (WebCore::handleMethodCall):
+        (WebCore::getProperty):
+        (WebCore::handleGetProperty):
+        (WebCore::handleSetProperty):
+        (WebCore::MediaSessionManagerGLib::setupMpris):
+        (WebCore::MediaSessionManagerGLib::busAcquired):
+        (WebCore::MediaSessionManagerGLib::nameLost):
+        (WebCore::MediaSessionManagerGLib::beginInterruption):
+        (WebCore::MediaSessionManagerGLib::scheduleSessionStatusUpdate):
+        (WebCore::MediaSessionManagerGLib::sessionWillBeginPlayback):
+        (WebCore::MediaSessionManagerGLib::sessionDidEndRemoteScrubbing):
+        (WebCore::MediaSessionManagerGLib::addSession):
+        (WebCore::MediaSessionManagerGLib::removeSession):
+        (WebCore::MediaSessionManagerGLib::setCurrentSession):
+        (WebCore::MediaSessionManagerGLib::sessionWillEndPlayback):
+        (WebCore::MediaSessionManagerGLib::sessionStateChanged):
+        (WebCore::MediaSessionManagerGLib::clientCharacteristicsChanged):
+        (WebCore::MediaSessionManagerGLib::sessionCanProduceAudioChanged):
+        (WebCore::MediaSessionManagerGLib::addSupportedCommand):
+        (WebCore::MediaSessionManagerGLib::removeSupportedCommand):
+        (WebCore::MediaSessionManagerGLib::nowPlayingEligibleSession):
+        (WebCore::MediaSessionManagerGLib::updateNowPlayingInfo):
+        (WebCore::MediaSessionManagerGLib::getPlaybackStatusAsGVariant):
+        (WebCore::MediaSessionManagerGLib::getActiveSessionPosition):
+        (WebCore::MediaSessionManagerGLib::dispatch):
+        (WebCore::MediaSessionManagerGLib::emitPropertiesChanged):
+        * platform/audio/glib/MediaSessionManagerGLib.h: Added.
+        (WebCore::MediaSessionManagerGLib::nameAcquired):
+        (WebCore::MediaSessionManagerGLib::getMetadataAsGVariant const):
+        (WebCore::MediaSessionManagerGLib::providePresentingApplicationPIDIfNecessary):
+        * platform/glib/ApplicationGLib.cpp: Added.
+        (WebCore::setApplicationName):
+        (WebCore::getApplicationName):
+        (WebCore::setApplicationID):
+        (WebCore::getApplicationID):
+        * platform/glib/ApplicationGLib.h: Added.
+        * platform/glib/RemoteCommandListenerGLib.cpp: Added.
+        (WebCore::RemoteCommandListenerGLib::create):
+        (WebCore::RemoteCommandListenerGLib::updateSupportedCommands):
+        (WebCore::RemoteCommandListenerGLib::RemoteCommandListenerGLib):
+        * platform/glib/RemoteCommandListenerGLib.h: Added.
+        * platform/graphics/ImageFrame.h:
+        * platform/graphics/ImageOrientation.h:
+
 2021-09-10  Alan Bujtas  <[email protected]>
 
         [Legacy Line Layout] Do not integral round the root inlinebox's top position

Modified: trunk/Source/WebCore/Modules/mediasession/MediaImage.h (282306 => 282307)


--- trunk/Source/WebCore/Modules/mediasession/MediaImage.h	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/Modules/mediasession/MediaImage.h	2021-09-11 11:34:42 UTC (rev 282307)
@@ -27,6 +27,9 @@
 
 #if ENABLE(MEDIA_SESSION)
 
+#include <wtf/Forward.h>
+#include <wtf/text/WTFString.h>
+
 namespace WebCore {
 
 struct MediaImage {

Modified: trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp (282306 => 282307)


--- trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -51,9 +51,18 @@
     return reinterpret_cast<const void*>(++logIdentifier);
 }
 
-static WTFLogChannel& logChannel() { return LogMedia; }
-static const char* logClassName() { return "MediaSession"; }
+#if !RELEASE_LOG_DISABLED
+static WTFLogChannel& logChannel()
+{
+    return LogMedia;
+}
 
+static const char* logClassName()
+{
+    return "MediaSession";
+}
+#endif
+
 static PlatformMediaSession::RemoteControlCommandType platformCommandForMediaSessionAction(MediaSessionAction action)
 {
     static const auto commandMap = makeNeverDestroyed([] {

Modified: trunk/Source/WebCore/Modules/mediasession/MediaSession.h (282306 => 282307)


--- trunk/Source/WebCore/Modules/mediasession/MediaSession.h	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/Modules/mediasession/MediaSession.h	2021-09-11 11:34:42 UTC (rev 282307)
@@ -93,7 +93,9 @@
     };
     WEBCORE_EXPORT bool callActionHandler(const MediaSessionActionDetails&, TriggerGestureIndicator = TriggerGestureIndicator::Yes);
 
+#if !RELEASE_LOG_DISABLED
     const Logger& logger() const { return *m_logger.get(); }
+#endif
 
     class Observer : public CanMakeWeakPtr<Observer> {
     public:

Modified: trunk/Source/WebCore/PlatformGTK.cmake (282306 => 282307)


--- trunk/Source/WebCore/PlatformGTK.cmake	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/PlatformGTK.cmake	2021-09-11 11:34:42 UTC (rev 282307)
@@ -26,7 +26,9 @@
     "${WEBCORE_DIR}/editing/atk"
     "${WEBCORE_DIR}/page/gtk"
     "${WEBCORE_DIR}/platform/adwaita"
+    "${WEBCORE_DIR}/platform/audio/glib"
     "${WEBCORE_DIR}/platform/generic"
+    "${WEBCORE_DIR}/platform/glib"
     "${WEBCORE_DIR}/platform/gtk"
     "${WEBCORE_DIR}/platform/graphics/egl"
     "${WEBCORE_DIR}/platform/graphics/glx"
@@ -53,6 +55,8 @@
 list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
     platform/adwaita/ScrollbarThemeAdwaita.h
 
+    platform/glib/ApplicationGLib.h
+
     platform/graphics/x11/PlatformDisplayX11.h
     platform/graphics/x11/XErrorTrapper.h
     platform/graphics/x11/XUniquePtr.h

Modified: trunk/Source/WebCore/PlatformWPE.cmake (282306 => 282307)


--- trunk/Source/WebCore/PlatformWPE.cmake	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/PlatformWPE.cmake	2021-09-11 11:34:42 UTC (rev 282307)
@@ -19,6 +19,8 @@
 list(APPEND WebCore_PRIVATE_INCLUDE_DIRECTORIES
     "${WEBCORE_DIR}/accessibility/atk"
     "${WEBCORE_DIR}/platform/adwaita"
+    "${WEBCORE_DIR}/platform/audio/glib"
+    "${WEBCORE_DIR}/platform/glib"
     "${WEBCORE_DIR}/platform/graphics/egl"
     "${WEBCORE_DIR}/platform/graphics/epoxy"
     "${WEBCORE_DIR}/platform/graphics/glx"
@@ -36,6 +38,8 @@
 )
 
 list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
+    platform/glib/ApplicationGLib.h
+
     platform/graphics/wayland/PlatformDisplayWayland.h
     platform/graphics/wayland/WlUniquePtr.h
 )

Modified: trunk/Source/WebCore/platform/LogInitialization.cpp (282306 => 282307)


--- trunk/Source/WebCore/platform/LogInitialization.cpp	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/LogInitialization.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -65,6 +65,7 @@
 
 WTFLogChannel* getLogChannel(const String& name)
 {
+    UNUSED_PARAM(name);
     return nullptr;
 }
 

Modified: trunk/Source/WebCore/platform/PlatformScreen.h (282306 => 282307)


--- trunk/Source/WebCore/platform/PlatformScreen.h	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/PlatformScreen.h	2021-09-11 11:34:42 UTC (rev 282307)
@@ -48,6 +48,12 @@
 typedef struct CGColorSpace *CGColorSpaceRef;
 #endif
 
+// X11 headers define a bunch of macros with common terms, interfering with WebCore and WTF enum values.
+// As a workaround, we explicitly undef them here.
+#if defined(None)
+#undef None
+#endif
+
 namespace WebCore {
 
 class DestinationColorSpace;

Modified: trunk/Source/WebCore/platform/RemoteCommandListener.cpp (282306 => 282307)


--- trunk/Source/WebCore/platform/RemoteCommandListener.cpp	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/RemoteCommandListener.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -30,6 +30,10 @@
 #include "RemoteCommandListenerCocoa.h"
 #endif
 
+#if USE(GLIB)
+#include "RemoteCommandListenerGLib.h"
+#endif
+
 namespace WebCore {
 
 static RemoteCommandListener::CreationFunction& remoteCommandListenerCreationFunction()
@@ -48,8 +52,11 @@
     remoteCommandListenerCreationFunction() = [] (RemoteCommandListenerClient& client) {
 #if PLATFORM(COCOA)
         return RemoteCommandListenerCocoa::create(client);
+#elif USE(GLIB)
+        return RemoteCommandListenerGLib::create(client);
 #else
-        return RemoteCommandListener::create(client);
+        UNUSED_PARAM(client);
+        return nullptr;
 #endif
     };
 }

Modified: trunk/Source/WebCore/platform/SourcesGLib.txt (282306 => 282307)


--- trunk/Source/WebCore/platform/SourcesGLib.txt	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/SourcesGLib.txt	2021-09-11 11:34:42 UTC (rev 282307)
@@ -22,11 +22,14 @@
 // THE POSSIBILITY OF SUCH DAMAGE.
 
 platform/audio/glib/AudioBusGLib.cpp
+platform/audio/glib/MediaSessionManagerGLib.cpp
 
+platform/glib/ApplicationGLib.cpp
 platform/glib/FileMonitorGLib.cpp
 platform/glib/KeyedDecoderGlib.cpp
 platform/glib/KeyedEncoderGlib.cpp
 platform/glib/LowPowerModeNotifierGLib.cpp
+platform/glib/RemoteCommandListenerGLib.cpp
 platform/glib/SharedBufferGlib.cpp
 platform/glib/UserAgentGLib.cpp
 

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (282306 => 282307)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -74,12 +74,12 @@
     return sharedPlatformMediaSessionManager().get();
 }
 
-#if !PLATFORM(COCOA)
+#if !PLATFORM(COCOA) && !USE(GLIB)
 std::unique_ptr<PlatformMediaSessionManager> PlatformMediaSessionManager::create()
 {
     return std::unique_ptr<PlatformMediaSessionManager>(new PlatformMediaSessionManager);
 }
-#endif // !PLATFORM(COCOA)
+#endif // !PLATFORM(COCOA) && !USE(GLIB)
 
 void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()
 {

Added: trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp (0 => 282307)


--- trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,613 @@
+/*
+ *  Copyright (C) 2021 Igalia S.L
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "MediaSessionManagerGLib.h"
+
+#if USE(GLIB)
+
+#include "ApplicationGLib.h"
+#include "AudioSession.h"
+#include "HTMLMediaElement.h"
+#include "MediaPlayer.h"
+#include "MediaStrategy.h"
+#include "NowPlayingInfo.h"
+#include "PlatformMediaSession.h"
+#include "PlatformStrategies.h"
+
+#include <gio/gio.h>
+#include <wtf/SortedArrayMap.h>
+
+// https://specifications.freedesktop.org/mpris-spec/latest/
+static const char s_mprisInterface[] =
+    "<node>"
+        "<interface name=\"org.mpris.MediaPlayer2\">"
+            "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "<method name=\"Raise\"/>"
+            "<method name=\"Quit\"/>"
+            "<property name=\"CanQuit\" type=\"b\" access=\"read\"/>"
+            "<property name=\"CanRaise\" type=\"b\" access=\"read\"/>"
+            "<property name=\"HasTrackList\" type=\"b\" access=\"read\"/>"
+            "<property name=\"Identity\" type=\"s\" access=\"read\"/>"
+            "<property name=\"DesktopEntry\" type=\"s\" access=\"read\"/>"
+            "<property name=\"SupportedUriSchemes\" type=\"as\" access=\"read\"/>"
+            "<property name=\"SupportedMimeTypes\" type=\"as\" access=\"read\"/>"
+        "</interface>"
+        "<interface name=\"org.mpris.MediaPlayer2.Player\">"
+            "<method name=\"Next\"/>"
+            "<method name=\"Previous\"/>"
+            "<method name=\"Pause\"/>"
+            "<method name=\"PlayPause\"/>"
+            "<method name=\"Stop\"/>"
+            "<method name=\"Play\"/>"
+            "<method name=\"Seek\">"
+                "<arg direction=\"in\" type=\"x\" name=\"Offset\"/>"
+            "</method>"
+            "<method name=\"SetPosition\">"
+                "<arg direction=\"in\" type=\"o\" name=\"TrackId\"/>"
+                "<arg direction=\"in\" type=\"x\" name=\"Position\"/>"
+            "</method>"
+            "<method name=\"OpenUri\">"
+                "<arg direction=\"in\" type=\"s\" name=\"Uri\"/>"
+            "</method>"
+            "<property name=\"PlaybackStatus\" type=\"s\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"Rate\" type=\"d\" access=\"readwrite\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"Metadata\" type=\"a{sv}\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"Volume\" type=\"d\" access=\"readwrite\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"Position\" type=\"x\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"false\"/>"
+            "</property>"
+            "<property name=\"MinimumRate\" type=\"d\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"MaximumRate\" type=\"d\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"CanGoNext\" type=\"b\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"CanGoPrevious\" type=\"b\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"CanPlay\" type=\"b\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"CanPause\" type=\"b\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"CanSeek\" type=\"b\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+            "</property>"
+            "<property name=\"CanControl\" type=\"b\" access=\"read\">"
+                "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"false\"/>"
+            "</property>"
+            "<signal name=\"Seeked\">"
+                "<arg name=\"Position\" type=\"x\"/>"
+            "</signal>"
+        "</interface>"
+    "</node>";
+
+#define DBUS_MPRIS_OBJECT_PATH "/org/mpris/MediaPlayer2"
+#define DBUS_MPRIS_PLAYER_INTERFACE "org.mpris.MediaPlayer2.Player"
+#define DBUS_MPRIS_TRACK_PATH "/org/mpris/MediaPlayer2/webkit"
+
+namespace WebCore {
+
+std::unique_ptr<PlatformMediaSessionManager> PlatformMediaSessionManager::create()
+{
+    return makeUnique<MediaSessionManagerGLib>();
+}
+
+MediaSessionManagerGLib::MediaSessionManagerGLib()
+    : m_nowPlayingManager(platformStrategies()->mediaStrategy().createNowPlayingManager())
+{
+}
+
+MediaSessionManagerGLib::~MediaSessionManagerGLib()
+{
+    if (m_ownerId)
+        g_bus_unown_name(m_ownerId);
+}
+
+static std::optional<PlatformMediaSession::RemoteControlCommandType> getCommand(const char* name)
+{
+    static const std::pair<ComparableASCIILiteral, PlatformMediaSession::RemoteControlCommandType> commandList[] = {
+        { "Next", PlatformMediaSession::NextTrackCommand },
+        { "Pause", PlatformMediaSession::PauseCommand },
+        { "Play", PlatformMediaSession::PlayCommand },
+        { "PlayPause", PlatformMediaSession::TogglePlayPauseCommand },
+        { "Previous", PlatformMediaSession::PreviousTrackCommand },
+        { "Seek", PlatformMediaSession::SeekToPlaybackPositionCommand },
+        { "Stop", PlatformMediaSession::StopCommand }
+    };
+
+    static const SortedArrayMap map { commandList };
+    auto value = map.get(name, PlatformMediaSession::RemoteControlCommandType::NoCommand);
+    if (value == PlatformMediaSession::RemoteControlCommandType::NoCommand)
+        return { };
+    return value;
+}
+
+static void handleMethodCall(GDBusConnection* /* connection */, const char* /* sender */, const char* objectPath, const char* interfaceName, const char* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData)
+{
+    ASSERT(isMainThread());
+    auto command = getCommand(methodName);
+    if (!command) {
+        g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "%s.%s.%s is not available now", objectPath, interfaceName, methodName);
+        return;
+    }
+    auto& manager = *reinterpret_cast<MediaSessionManagerGLib*>(userData);
+    PlatformMediaSession::RemoteCommandArgument argument;
+    if (*command == PlatformMediaSession::SeekToPlaybackPositionCommand) {
+        int64_t offset;
+        g_variant_get(parameters, "(x)", &offset);
+        argument.time = offset / 1000000;
+    }
+    manager.dispatch(*command, argument);
+    g_dbus_method_invocation_return_value(invocation, nullptr);
+}
+
+enum class MprisProperty : uint8_t {
+    NoProperty,
+    CanControl,
+    CanGoNext,
+    CanGoPrevious,
+    CanPause,
+    CanPlay,
+    CanQuit,
+    CanRaise,
+    CanSeek,
+    DesktopEntry,
+    GetMetadata,
+    GetPlaybackStatus,
+    GetPosition,
+    HasTrackList,
+    Identity,
+    SupportedMimeTypes,
+    SupportedUriSchemes,
+};
+
+static std::optional<MprisProperty> getMprisProperty(const char* propertyName)
+{
+    static constexpr std::pair<ComparableASCIILiteral, MprisProperty> propertiesList[] {
+        { "CanControl", MprisProperty::CanControl },
+        { "CanGoNext", MprisProperty::CanGoNext },
+        { "CanGoPrevious", MprisProperty::CanGoPrevious },
+        { "CanPause", MprisProperty::CanPause },
+        { "CanPlay", MprisProperty::CanPlay },
+        { "CanQuit", MprisProperty::CanQuit },
+        { "CanRaise", MprisProperty::CanRaise },
+        { "CanSeek", MprisProperty::CanSeek },
+        { "DesktopEntry", MprisProperty::DesktopEntry },
+        { "HasTrackList", MprisProperty::HasTrackList },
+        { "Identity", MprisProperty::Identity },
+        { "Metadata", MprisProperty::GetMetadata },
+        { "PlaybackStatus", MprisProperty::GetPlaybackStatus },
+        { "Position", MprisProperty::GetPosition },
+        { "SupportedMimeTypes", MprisProperty::SupportedMimeTypes },
+        { "SupportedUriSchemes", MprisProperty::SupportedUriSchemes }
+    };
+    static constexpr SortedArrayMap map { propertiesList };
+    auto value = map.get(propertyName, MprisProperty::NoProperty);
+    if (value == MprisProperty::NoProperty)
+        return { };
+    return value;
+}
+
+static GVariant* handleGetProperty(GDBusConnection*, const char* /* sender */, const char* objectPath, const char* interfaceName, const char* propertyName, GError** error, gpointer userData)
+{
+    ASSERT(isMainThread());
+    auto property = getMprisProperty(propertyName);
+    if (!property) {
+        g_set_error(error, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "%s.%s %s is not supported", objectPath, interfaceName, propertyName);
+        return nullptr;
+    }
+
+    auto& manager = *reinterpret_cast<MediaSessionManagerGLib*>(userData);
+    switch (property.value()) {
+    case MprisProperty::NoProperty:
+        break;
+    case MprisProperty::SupportedUriSchemes:
+    case MprisProperty::SupportedMimeTypes:
+        return g_variant_new_strv(nullptr, 0);
+    case MprisProperty::GetPlaybackStatus:
+        return manager.getPlaybackStatusAsGVariant({ });
+    case MprisProperty::GetMetadata: {
+        auto* variant = manager.getMetadataAsGVariant();
+        if (!variant)
+            return nullptr;
+        return g_variant_ref(variant);
+    }
+    case MprisProperty::GetPosition:
+        return manager.getActiveSessionPosition();
+    case MprisProperty::Identity:
+        return g_variant_new_string(getApplicationName());
+    case MprisProperty::DesktopEntry:
+        return g_variant_new_string("");
+    case MprisProperty::HasTrackList:
+    case MprisProperty::CanQuit:
+    case MprisProperty::CanRaise:
+        return g_variant_new_boolean(false);
+    case MprisProperty::CanSeek:
+    case MprisProperty::CanControl:
+    case MprisProperty::CanGoNext:
+    case MprisProperty::CanGoPrevious:
+    case MprisProperty::CanPlay:
+    case MprisProperty::CanPause:
+        return g_variant_new_boolean(true);
+    }
+
+    return nullptr;
+}
+
+static gboolean handleSetProperty(GDBusConnection*, const char* /* sender */, const char* /* objectPath */, const char* interfaceName, const char* propertyName, GVariant*, GError** error, gpointer)
+{
+    ASSERT(isMainThread());
+    g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "%s:%s setting is not supported", interfaceName, propertyName);
+    return FALSE;
+}
+
+static const GDBusInterfaceVTable gInterfaceVTable = {
+    handleMethodCall, handleGetProperty, handleSetProperty, { nullptr }
+};
+
+bool MediaSessionManagerGLib::setupMpris()
+{
+    if (m_ownerId)
+        return true;
+
+    const auto& applicationID = getApplicationID();
+    m_instanceId = applicationID.isEmpty() ? makeString("org.mpris.MediaPlayer2.webkit.instance", getpid()) : makeString("org.mpris.MediaPlayer2.", applicationID.ascii().data());
+
+    m_ownerId = g_bus_own_name(G_BUS_TYPE_SESSION, m_instanceId.ascii().data(),
+        G_BUS_NAME_OWNER_FLAGS_NONE, reinterpret_cast<GBusAcquiredCallback>(+[](GDBusConnection* connection, const gchar*, gpointer userData) {
+            auto& manager = *reinterpret_cast<MediaSessionManagerGLib*>(userData);
+            manager.busAcquired(connection);
+        }),
+        reinterpret_cast<GBusNameAcquiredCallback>(+[](GDBusConnection* connection, const char*, gpointer userData) {
+            auto& manager = *reinterpret_cast<MediaSessionManagerGLib*>(userData);
+            manager.nameAcquired(connection);
+        }),
+        reinterpret_cast<GBusNameLostCallback>(+[](GDBusConnection* connection, const char*, gpointer userData) {
+            auto& manager = *reinterpret_cast<MediaSessionManagerGLib*>(userData);
+            manager.nameLost(connection);
+        }), this, nullptr);
+
+    GUniqueOutPtr<GError> error;
+    m_mprisInterface = adoptGRef(g_dbus_node_info_new_for_xml(s_mprisInterface, &error.outPtr()));
+    if (!m_mprisInterface) {
+        g_warning("Failed at parsing XML Interface definition: %s", error->message);
+        return false;
+    }
+
+    return true;
+}
+
+void MediaSessionManagerGLib::busAcquired(GDBusConnection* connection)
+{
+    GUniqueOutPtr<GError> error;
+    m_rootRegistrationId = g_dbus_connection_register_object(connection, DBUS_MPRIS_OBJECT_PATH, m_mprisInterface->interfaces[0],
+        &gInterfaceVTable, this, nullptr, &error.outPtr());
+
+    if (!m_rootRegistrationId) {
+        g_warning("Failed to register MPRIS D-Bus object: %s", error->message);
+        return;
+    }
+
+    m_playerRegistrationId = g_dbus_connection_register_object(connection, DBUS_MPRIS_OBJECT_PATH, m_mprisInterface->interfaces[1],
+        &gInterfaceVTable, this, nullptr, &error.outPtr());
+
+    if (!m_playerRegistrationId)
+        g_warning("Failed at MPRIS object registration: %s", error->message);
+}
+
+void MediaSessionManagerGLib::nameLost(GDBusConnection* connection)
+{
+    if (UNLIKELY(!m_connection)) {
+        g_warning("Unable to acquire MPRIS D-Bus session ownership for name %s", m_instanceId.ascii().data());
+        return;
+    }
+
+    m_connection = nullptr;
+    if (!m_rootRegistrationId)
+        return;
+
+    if (g_dbus_connection_unregister_object(connection, m_rootRegistrationId))
+        m_rootRegistrationId = 0;
+    else
+        g_warning("Unable to unregister MPRIS D-Bus object.");
+
+    if (!m_playerRegistrationId)
+        return;
+
+    if (g_dbus_connection_unregister_object(connection, m_playerRegistrationId))
+        m_playerRegistrationId = 0;
+    else
+        g_warning("Unable to unregister MPRIS D-Bus player object.");
+}
+
+void MediaSessionManagerGLib::beginInterruption(PlatformMediaSession::InterruptionType type)
+{
+    if (type == PlatformMediaSession::InterruptionType::SystemInterruption) {
+        forEachSession([] (auto& session) {
+            session.clearHasPlayedSinceLastInterruption();
+        });
+    }
+
+    PlatformMediaSessionManager::beginInterruption(type);
+}
+
+void MediaSessionManagerGLib::scheduleSessionStatusUpdate()
+{
+    callOnMainThread([this] () mutable {
+        m_nowPlayingManager->setSupportsSeeking(computeSupportsSeeking());
+        updateNowPlayingInfo();
+
+        forEachSession([] (auto& session) {
+            session.updateMediaUsageIfChanged();
+        });
+    });
+}
+
+bool MediaSessionManagerGLib::sessionWillBeginPlayback(PlatformMediaSession& session)
+{
+    if (!PlatformMediaSessionManager::sessionWillBeginPlayback(session))
+        return false;
+
+    scheduleSessionStatusUpdate();
+    return true;
+}
+
+void MediaSessionManagerGLib::sessionDidEndRemoteScrubbing(PlatformMediaSession&)
+{
+    scheduleSessionStatusUpdate();
+}
+
+void MediaSessionManagerGLib::addSession(PlatformMediaSession& session)
+{
+    if (!setupMpris())
+        return;
+
+    m_nowPlayingManager->addClient(*this);
+
+    PlatformMediaSessionManager::addSession(session);
+}
+
+void MediaSessionManagerGLib::removeSession(PlatformMediaSession& session)
+{
+    PlatformMediaSessionManager::removeSession(session);
+
+    if (hasNoSession()) {
+        m_nowPlayingManager->removeClient(*this);
+        if (m_ownerId)
+            g_bus_unown_name(m_ownerId);
+        m_ownerId = 0;
+    }
+    scheduleSessionStatusUpdate();
+}
+
+void MediaSessionManagerGLib::setCurrentSession(PlatformMediaSession& session)
+{
+    PlatformMediaSessionManager::setCurrentSession(session);
+
+    m_nowPlayingManager->updateSupportedCommands();
+}
+
+void MediaSessionManagerGLib::sessionWillEndPlayback(PlatformMediaSession& session, DelayCallingUpdateNowPlaying delayCallingUpdateNowPlaying)
+{
+    PlatformMediaSessionManager::sessionWillEndPlayback(session, delayCallingUpdateNowPlaying);
+
+    callOnMainThread([weakSession = makeWeakPtr(session)] {
+        if (weakSession)
+            weakSession->updateMediaUsageIfChanged();
+    });
+
+    if (delayCallingUpdateNowPlaying == DelayCallingUpdateNowPlaying::No)
+        updateNowPlayingInfo();
+    else {
+        callOnMainThread([this] {
+            updateNowPlayingInfo();
+        });
+    }
+}
+
+void MediaSessionManagerGLib::sessionStateChanged(PlatformMediaSession& session)
+{
+    PlatformMediaSessionManager::sessionStateChanged(session);
+
+    GVariantBuilder builder;
+    g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
+    g_variant_builder_add(&builder, "{sv}", "PlaybackStatus", getPlaybackStatusAsGVariant(&session));
+    emitPropertiesChanged(g_variant_new("(sa{sv}as)", DBUS_MPRIS_PLAYER_INTERFACE, &builder, nullptr));
+    g_variant_builder_clear(&builder);
+}
+
+void MediaSessionManagerGLib::clientCharacteristicsChanged(PlatformMediaSession& session)
+{
+    ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier());
+    if (m_isSeeking) {
+        m_isSeeking = false;
+        GUniqueOutPtr<GError> error;
+        int64_t position = session.nowPlayingInfo()->currentTime * 1000000;
+        if (!g_dbus_connection_emit_signal(m_connection.get(), nullptr, DBUS_MPRIS_OBJECT_PATH, DBUS_MPRIS_PLAYER_INTERFACE, "Seeked", g_variant_new("(x)", position), &error.outPtr()))
+            g_warning("Failed to emit MPRIS Seeked signal: %s", error->message);
+    }
+    scheduleSessionStatusUpdate();
+}
+
+void MediaSessionManagerGLib::sessionCanProduceAudioChanged()
+{
+    ALWAYS_LOG(LOGIDENTIFIER);
+    PlatformMediaSessionManager::sessionCanProduceAudioChanged();
+    scheduleSessionStatusUpdate();
+}
+
+void MediaSessionManagerGLib::addSupportedCommand(PlatformMediaSession::RemoteControlCommandType command)
+{
+    m_nowPlayingManager->addSupportedCommand(command);
+}
+
+void MediaSessionManagerGLib::removeSupportedCommand(PlatformMediaSession::RemoteControlCommandType command)
+{
+    m_nowPlayingManager->removeSupportedCommand(command);
+}
+
+RemoteCommandListener::RemoteCommandsSet MediaSessionManagerGLib::supportedCommands() const
+{
+    return m_nowPlayingManager->supportedCommands();
+}
+
+PlatformMediaSession* MediaSessionManagerGLib::nowPlayingEligibleSession()
+{
+    // FIXME: Fix this layering violation.
+    if (auto element = HTMLMediaElement::bestMediaElementForRemoteControls(MediaElementSession::PlaybackControlsPurpose::NowPlaying))
+        return &element->mediaSession();
+
+    return nullptr;
+}
+
+void MediaSessionManagerGLib::updateNowPlayingInfo()
+{
+    std::optional<NowPlayingInfo> nowPlayingInfo;
+    if (auto* session = nowPlayingEligibleSession())
+        nowPlayingInfo = session->nowPlayingInfo();
+
+    if (!nowPlayingInfo) {
+        if (m_registeredAsNowPlayingApplication) {
+            ALWAYS_LOG(LOGIDENTIFIER, "clearing now playing info");
+            m_nowPlayingManager->clearNowPlayingInfo();
+        }
+
+        m_registeredAsNowPlayingApplication = false;
+        m_nowPlayingActive = false;
+        m_lastUpdatedNowPlayingTitle = emptyString();
+        m_lastUpdatedNowPlayingDuration = NAN;
+        m_lastUpdatedNowPlayingElapsedTime = NAN;
+        m_lastUpdatedNowPlayingInfoUniqueIdentifier = { };
+        m_nowPlayingInfo.clear();
+        return;
+    }
+
+    m_haveEverRegisteredAsNowPlayingApplication = true;
+
+    if (m_nowPlayingManager->setNowPlayingInfo(*nowPlayingInfo))
+        ALWAYS_LOG(LOGIDENTIFIER, "title = \"", nowPlayingInfo->title, "\", isPlaying = ", nowPlayingInfo->isPlaying, ", duration = ", nowPlayingInfo->duration, ", now = ", nowPlayingInfo->currentTime, ", id = ", nowPlayingInfo->uniqueIdentifier.toUInt64(), ", registered = ", m_registeredAsNowPlayingApplication, ", src = "" nowPlayingInfo->artwork ? nowPlayingInfo->artwork->src : String(), "\"");
+
+    if (!m_registeredAsNowPlayingApplication) {
+        m_registeredAsNowPlayingApplication = true;
+        providePresentingApplicationPIDIfNecessary();
+    }
+
+    if (!nowPlayingInfo->title.isEmpty())
+        m_lastUpdatedNowPlayingTitle = nowPlayingInfo->title;
+
+    double duration = nowPlayingInfo->duration;
+    if (std::isfinite(duration) && duration != MediaPlayer::invalidTime())
+        m_lastUpdatedNowPlayingDuration = duration;
+
+    m_lastUpdatedNowPlayingInfoUniqueIdentifier = nowPlayingInfo->uniqueIdentifier;
+
+    double currentTime = nowPlayingInfo->currentTime;
+    if (std::isfinite(currentTime) && currentTime != MediaPlayer::invalidTime() && nowPlayingInfo->supportsSeeking)
+        m_lastUpdatedNowPlayingElapsedTime = currentTime;
+
+    m_nowPlayingActive = nowPlayingInfo->allowsNowPlayingControlsVisibility;
+
+    GVariantBuilder builder;
+    g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
+    g_variant_builder_add(&builder, "{sv}", "mpris:trackid", g_variant_new("o", DBUS_MPRIS_TRACK_PATH));
+    g_variant_builder_add(&builder, "{sv}", "mpris:length", g_variant_new_int64(nowPlayingInfo->duration * 1000000));
+    g_variant_builder_add(&builder, "{sv}", "xesam:title", g_variant_new_string(nowPlayingInfo->title.utf8().data()));
+    g_variant_builder_add(&builder, "{sv}", "xesam:album", g_variant_new_string(nowPlayingInfo->album.utf8().data()));
+    if (nowPlayingInfo->artwork)
+        g_variant_builder_add(&builder, "{sv}", "mpris:artUrl", g_variant_new_string(nowPlayingInfo->artwork->src.utf8().data()));
+
+    GVariantBuilder artistBuilder;
+    g_variant_builder_init(&artistBuilder, G_VARIANT_TYPE("as"));
+    g_variant_builder_add(&artistBuilder, "s", nowPlayingInfo->artist.utf8().data());
+    g_variant_builder_add(&builder, "{sv}", "xesam:artist", g_variant_builder_end(&artistBuilder));
+
+    m_nowPlayingInfo = g_variant_builder_end(&builder);
+
+    GVariantBuilder propertiesBuilder;
+    g_variant_builder_init(&propertiesBuilder, G_VARIANT_TYPE("a{sv}"));
+    g_variant_builder_add(&propertiesBuilder, "{sv}", "Metadata", m_nowPlayingInfo.get());
+    emitPropertiesChanged(g_variant_new("(sa{sv}as)", DBUS_MPRIS_PLAYER_INTERFACE, &propertiesBuilder, nullptr));
+    g_variant_builder_clear(&propertiesBuilder);
+}
+
+GVariant* MediaSessionManagerGLib::getPlaybackStatusAsGVariant(std::optional<const PlatformMediaSession*> session)
+{
+    auto state = [this, session = WTFMove(session)]() -> PlatformMediaSession::State {
+        if (session)
+            return session.value()->state();
+
+        auto* nowPlayingSession = nowPlayingEligibleSession();
+        if (nowPlayingSession)
+            return nowPlayingSession->state();
+
+        return PlatformMediaSession::State::Idle;
+    }();
+
+    switch (state) {
+    case PlatformMediaSession::State::Autoplaying:
+    case PlatformMediaSession::State::Playing:
+        return g_variant_new_string("Playing");
+    case PlatformMediaSession::State::Paused:
+        return g_variant_new_string("Paused");
+    case PlatformMediaSession::State::Idle:
+    case PlatformMediaSession::State::Interrupted:
+        return g_variant_new_string("Stopped");
+    }
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+GVariant* MediaSessionManagerGLib::getActiveSessionPosition()
+{
+    auto* session = nowPlayingEligibleSession();
+    return g_variant_new_int64(session ? session->nowPlayingInfo()->currentTime * 1000000 : 0);
+}
+
+void MediaSessionManagerGLib::dispatch(PlatformMediaSession::RemoteControlCommandType platformCommand, PlatformMediaSession::RemoteCommandArgument argument)
+{
+    m_isSeeking = platformCommand == PlatformMediaSession::SeekToPlaybackPositionCommand;
+    m_nowPlayingManager->didReceiveRemoteControlCommand(platformCommand, argument);
+}
+
+void MediaSessionManagerGLib::emitPropertiesChanged(GVariant* parameters)
+{
+    if (!m_connection)
+        return;
+
+    GUniqueOutPtr<GError> error;
+    if (!g_dbus_connection_emit_signal(m_connection.get(), nullptr, DBUS_MPRIS_OBJECT_PATH, "org.freedesktop.DBus.Properties", "PropertiesChanged", parameters, &error.outPtr()))
+        g_warning("Failed to emit MPRIS properties changed: %s", error->message);
+}
+
+} // namespace WebCore
+
+#endif // USE(GLIB)

Added: trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.h (0 => 282307)


--- trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.h	2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,118 @@
+/*
+ *  Copyright (C) 2021 Igalia S.L
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#pragma once
+
+#if USE(GLIB)
+
+#include "NowPlayingManager.h"
+#include "PlatformMediaSessionManager.h"
+#include <wtf/glib/GRefPtr.h>
+
+namespace WebCore {
+
+struct NowPlayingInfo;
+
+class MediaSessionManagerGLib
+    : public PlatformMediaSessionManager
+    , private NowPlayingManager::Client {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    MediaSessionManagerGLib();
+    ~MediaSessionManagerGLib();
+
+    bool setupMpris();
+
+    void beginInterruption(PlatformMediaSession::InterruptionType) final;
+
+    bool hasActiveNowPlayingSession() const final { return m_nowPlayingActive; }
+    String lastUpdatedNowPlayingTitle() const final { return m_lastUpdatedNowPlayingTitle; }
+    double lastUpdatedNowPlayingDuration() const final { return m_lastUpdatedNowPlayingDuration; }
+    double lastUpdatedNowPlayingElapsedTime() const final { return m_lastUpdatedNowPlayingElapsedTime; }
+    MediaUniqueIdentifier lastUpdatedNowPlayingInfoUniqueIdentifier() const final { return m_lastUpdatedNowPlayingInfoUniqueIdentifier; }
+    bool registeredAsNowPlayingApplication() const final { return m_registeredAsNowPlayingApplication; }
+    bool haveEverRegisteredAsNowPlayingApplication() const final { return m_haveEverRegisteredAsNowPlayingApplication; }
+
+    void busAcquired(GDBusConnection*);
+    void nameAcquired(GDBusConnection* connection) { m_connection = connection; }
+    void nameLost(GDBusConnection*);
+    GVariant* getMetadataAsGVariant() const { return m_nowPlayingInfo.get(); }
+    GVariant* getPlaybackStatusAsGVariant(std::optional<const PlatformMediaSession*>);
+    GVariant* getActiveSessionPosition();
+    void dispatch(PlatformMediaSession::RemoteControlCommandType, PlatformMediaSession::RemoteCommandArgument);
+
+protected:
+    void scheduleSessionStatusUpdate() final;
+    void updateNowPlayingInfo();
+
+    void removeSession(PlatformMediaSession&) final;
+    void addSession(PlatformMediaSession&) final;
+    void setCurrentSession(PlatformMediaSession&) final;
+
+    bool sessionWillBeginPlayback(PlatformMediaSession&) override;
+    void sessionWillEndPlayback(PlatformMediaSession&, DelayCallingUpdateNowPlaying) override;
+    void sessionStateChanged(PlatformMediaSession&) override;
+    void sessionDidEndRemoteScrubbing(PlatformMediaSession&) final;
+    void clientCharacteristicsChanged(PlatformMediaSession&) final;
+    void sessionCanProduceAudioChanged() final;
+
+    virtual void providePresentingApplicationPIDIfNecessary() { }
+
+    PlatformMediaSession* nowPlayingEligibleSession();
+
+    void addSupportedCommand(PlatformMediaSession::RemoteControlCommandType) final;
+    void removeSupportedCommand(PlatformMediaSession::RemoteControlCommandType) final;
+    RemoteCommandListener::RemoteCommandsSet supportedCommands() const final;
+
+    void resetHaveEverRegisteredAsNowPlayingApplicationForTesting() final { m_haveEverRegisteredAsNowPlayingApplication = false; };
+
+private:
+    void emitPropertiesChanged(GVariant*);
+
+#if !RELEASE_LOG_DISABLED
+    const char* logClassName() const override { return "MediaSessionManagerGLib"; }
+#endif
+
+    // NowPlayingManager::Client
+    void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType type, const PlatformMediaSession::RemoteCommandArgument& argument) final { processDidReceiveRemoteControlCommand(type, argument); }
+
+    String m_instanceId;
+    unsigned m_ownerId { 0 };
+    unsigned m_rootRegistrationId { 0 };
+    unsigned m_playerRegistrationId { 0 };
+    bool m_isSeeking { false };
+    GRefPtr<GDBusConnection> m_connection;
+    GRefPtr<GDBusNodeInfo> m_mprisInterface;
+    GRefPtr<GVariant> m_nowPlayingInfo;
+
+    bool m_nowPlayingActive { false };
+    bool m_registeredAsNowPlayingApplication { false };
+    bool m_haveEverRegisteredAsNowPlayingApplication { false };
+
+    // For testing purposes only.
+    String m_lastUpdatedNowPlayingTitle;
+    double m_lastUpdatedNowPlayingDuration { NAN };
+    double m_lastUpdatedNowPlayingElapsedTime { NAN };
+    MediaUniqueIdentifier m_lastUpdatedNowPlayingInfoUniqueIdentifier;
+
+    const std::unique_ptr<NowPlayingManager> m_nowPlayingManager;
+};
+
+} // namespace WebCore
+
+#endif // USE(GLIB)

Added: trunk/Source/WebCore/platform/glib/ApplicationGLib.cpp (0 => 282307)


--- trunk/Source/WebCore/platform/glib/ApplicationGLib.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/glib/ApplicationGLib.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (C) 2021 Igalia S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "ApplicationGLib.h"
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static String gApplicationName;
+static String gApplicationID;
+
+void setApplicationName(const String& applicationName)
+{
+    gApplicationName = applicationName;
+}
+
+const char* getApplicationName()
+{
+    if (!gApplicationName.isEmpty())
+        return gApplicationName.ascii().data();
+    return "WebKit";
+}
+
+void setApplicationID(const String& applicationID)
+{
+    gApplicationID = applicationID;
+}
+
+const String& getApplicationID()
+{
+    return gApplicationID;
+}
+
+} // namespace WebCore

Added: trunk/Source/WebCore/platform/glib/ApplicationGLib.h (0 => 282307)


--- trunk/Source/WebCore/platform/glib/ApplicationGLib.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/glib/ApplicationGLib.h	2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2021 Igalia S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#pragma once
+
+#if USE(GLIB)
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+WEBCORE_EXPORT void setApplicationName(const String&);
+WEBCORE_EXPORT const char* getApplicationName();
+
+WEBCORE_EXPORT void setApplicationID(const String&);
+WEBCORE_EXPORT const String& getApplicationID();
+
+} // namespace WebCore
+
+#endif // USE(GLIB)

Added: trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.cpp (0 => 282307)


--- trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (C) 2021 Igalia S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "RemoteCommandListenerGLib.h"
+
+#if USE(GLIB)
+
+namespace WebCore {
+
+std::unique_ptr<RemoteCommandListenerGLib> RemoteCommandListenerGLib::create(RemoteCommandListenerClient& client)
+{
+    return makeUnique<RemoteCommandListenerGLib>(client);
+}
+
+void RemoteCommandListenerGLib::updateSupportedCommands()
+{
+    // Remote commands are handled as user-triggered MPRIS actions in MediaSessionManagerGLib.
+}
+
+RemoteCommandListenerGLib::RemoteCommandListenerGLib(RemoteCommandListenerClient& client)
+    : RemoteCommandListener(client)
+{
+}
+
+RemoteCommandListenerGLib::~RemoteCommandListenerGLib() = default;
+
+}
+
+#endif

Added: trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.h (0 => 282307)


--- trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.h	2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (C) 2021 Igalia S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#pragma once
+
+#include "RemoteCommandListener.h"
+
+#if USE(GLIB)
+
+namespace WebCore {
+
+class RemoteCommandListenerGLib : public RemoteCommandListener {
+public:
+    static std::unique_ptr<RemoteCommandListenerGLib> create(RemoteCommandListenerClient&);
+    explicit RemoteCommandListenerGLib(RemoteCommandListenerClient&);
+    virtual ~RemoteCommandListenerGLib();
+
+private:
+    void updateSupportedCommands() final;
+
+    const RemoteCommandsSet& defaultCommands();
+};
+
+}
+
+#endif // USE(GLIB)

Modified: trunk/Source/WebCore/platform/graphics/ImageFrame.h (282306 => 282307)


--- trunk/Source/WebCore/platform/graphics/ImageFrame.h	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/graphics/ImageFrame.h	2021-09-11 11:34:42 UTC (rev 282307)
@@ -33,6 +33,12 @@
 #include "NativeImage.h"
 #include <wtf/Seconds.h>
 
+// X11 headers define a bunch of macros with common terms, interfering with WebCore and WTF enum values.
+// As a workaround, we explicitly undef them here.
+#if defined(None)
+#undef None
+#endif
+
 namespace WebCore {
 
 class ImageFrame {

Modified: trunk/Source/WebCore/platform/graphics/ImageOrientation.h (282306 => 282307)


--- trunk/Source/WebCore/platform/graphics/ImageOrientation.h	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/graphics/ImageOrientation.h	2021-09-11 11:34:42 UTC (rev 282307)
@@ -30,6 +30,12 @@
 #include "FloatSize.h"
 #include <wtf/EnumTraits.h>
 
+// X11 headers define a bunch of macros with common terms, interfering with WebCore and WTF enum values.
+// As a workaround, we explicitly undef them here.
+#if defined(None)
+#undef None
+#endif
+
 namespace WebCore {
 
 struct ImageOrientation {

Modified: trunk/Source/WebKit/ChangeLog (282306 => 282307)


--- trunk/Source/WebKit/ChangeLog	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/ChangeLog	2021-09-11 11:34:42 UTC (rev 282307)
@@ -1,3 +1,30 @@
+2021-09-11  Philippe Normand  <[email protected]>
+
+        [GLIB] MediaSession is not enabled
+        https://bugs.webkit.org/show_bug.cgi?id=217991
+        <rdar://problem/70740119>
+
+        Reviewed by Michael Catanzaro.
+
+        Pass Application name and unique ID from the UIProcess to the WebProcess in WPE and GTK
+        ports. The Bubblewrap launcher was also adapted to allow DBus MPRIS name ownership in the
+        sandboxed WebProcess.
+
+        * Shared/WebProcessCreationParameters.cpp:
+        (WebKit::WebProcessCreationParameters::encode const):
+        (WebKit::WebProcessCreationParameters::decode):
+        * Shared/WebProcessCreationParameters.h:
+        * UIProcess/API/glib/WebKitSettings.cpp:
+        (webKitSettingsConstructed):
+        * UIProcess/Launcher/glib/BubblewrapLauncher.cpp:
+        (WebKit::applicationId):
+        (WebKit::createFlatpakInfo):
+        (WebKit::XDGDBusProxyLauncher::launch):
+        * UIProcess/glib/WebProcessPoolGLib.cpp:
+        (WebKit::WebProcessPool::platformInitializeWebProcess):
+        * WebProcess/glib/WebProcessGLib.cpp:
+        (WebKit::WebProcess::platformInitializeWebProcess):
+
 2021-09-10  Chris Dumez  <[email protected]>
 
         Implement navigation reporting for Cross-Origin-Opener-Policy

Modified: trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp (282306 => 282307)


--- trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -214,6 +214,10 @@
 #if PLATFORM(GTK) || PLATFORM(WPE)
     encoder << memoryPressureHandlerConfiguration;
 #endif
+#if USE(GLIB)
+    encoder << applicationID;
+    encoder << applicationName;
+#endif
 }
 
 bool WebProcessCreationParameters::decode(IPC::Decoder& decoder, WebProcessCreationParameters& parameters)
@@ -587,6 +591,13 @@
     parameters.memoryPressureHandlerConfiguration = WTFMove(*memoryPressureHandlerConfiguration);
 #endif
 
+#if USE(GLIB)
+    if (!decoder.decode(parameters.applicationID))
+        return false;
+    if (!decoder.decode(parameters.applicationName))
+        return false;
+#endif
+
     return true;
 }
 

Modified: trunk/Source/WebKit/Shared/WebProcessCreationParameters.h (282306 => 282307)


--- trunk/Source/WebKit/Shared/WebProcessCreationParameters.h	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/Shared/WebProcessCreationParameters.h	2021-09-11 11:34:42 UTC (rev 282307)
@@ -260,6 +260,11 @@
 #if PLATFORM(GTK) || PLATFORM(WPE)
     std::optional<MemoryPressureHandler::Configuration> memoryPressureHandlerConfiguration;
 #endif
+
+#if USE(GLIB)
+    String applicationID;
+    String applicationName;
+#endif
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp (282306 => 282307)


--- trunk/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -196,6 +196,13 @@
     prefs->setPeerConnectionEnabled(true);
 #endif
 #endif
+
+    // FIXME: Expose API for this when this feature is officially non-experimental.
+#if ENABLE(MEDIA_SESSION)
+    prefs->setMediaSessionEnabled(true);
+    prefs->setMediaSessionCoordinatorEnabled(true);
+    prefs->setMediaSessionPlaylistEnabled(true);
+#endif
 }
 
 static void webKitSettingsSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)

Modified: trunk/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp (282306 => 282307)


--- trunk/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -130,6 +130,22 @@
     return memfd;
 }
 
+static const char* applicationId(GError** error)
+{
+    GApplication* app = g_application_get_default();
+    if (!app) {
+        g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "GApplication is required.");
+        return nullptr;
+    }
+
+    const char* appID = g_application_get_application_id(app);
+    if (!appID) {
+        g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "GApplication must have a valid ID.");
+        return nullptr;
+    }
+    return appID;
+}
+
 static int createFlatpakInfo()
 {
     static NeverDestroyed<GUniquePtr<char>> data;
@@ -138,13 +154,10 @@
     if (!data.get()) {
         // xdg-desktop-portal relates your name to certain permissions so we want
         // them to be application unique which is best done via GApplication.
-        GApplication* app = g_application_get_default();
-        if (!app)
-            g_error("GApplication is required for xdg-desktop-portal access in the WebKit sandbox.");
-
-        const char* appID = g_application_get_application_id(app);
+        GUniqueOutPtr<GError> error;
+        const char* appID = applicationId(&error.outPtr());
         if (!appID)
-            g_error("GApplication must have a valid ID for xdg-desktop-portal access in the WebKit sandbox.");
+            g_error("Unable to configure xdg-desktop-portal access in the WebKit sandbox: %s", error->message);
 
         GUniquePtr<GKeyFile> keyFile(g_key_file_new());
         g_key_file_set_string(keyFile.get(), "Application", "name", appID);
@@ -207,6 +220,16 @@
         if (enableLogging)
             proxyArgs.append("--log");
 
+        GUniqueOutPtr<GError> error;
+#if ENABLE(MEDIA_SESSION)
+        const char* appID = applicationId(&error.outPtr());
+        if (!appID)
+            g_warning("Unable to own D-Bus MPRIS name in the WebKit sandbox: %s", error->message);
+
+        auto mprisSessionID = makeString("--own=org.mpris.MediaPlayer2.", appID);
+        proxyArgs.append(mprisSessionID.ascii().data());
+#endif
+
         proxyArgs.appendVector(m_permissions);
 
         int proxyFd = argsToFd(proxyArgs, "dbus-proxy");
@@ -236,7 +259,6 @@
 
         ProcessLauncher::LaunchOptions launchOptions;
         launchOptions.processType = ProcessLauncher::ProcessType::DBusProxy;
-        GUniqueOutPtr<GError> error;
         GRefPtr<GSubprocess> process = bubblewrapSpawn(launcher.get(), launchOptions, argv, &error.outPtr());
         if (!process.get())
             g_error("Failed to start dbus proxy: %s", error->message);

Modified: trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp (282306 => 282307)


--- trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -109,6 +109,11 @@
 #endif
 
     parameters.memoryPressureHandlerConfiguration = m_configuration->memoryPressureHandlerConfiguration();
+
+    GApplication* app = g_application_get_default();
+    if (app)
+        parameters.applicationID = g_application_get_application_id(app);
+    parameters.applicationName = g_get_application_name();
 }
 
 void WebProcessPool::platformInvalidateContext()

Modified: trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp (282306 => 282307)


--- trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp	2021-09-11 11:34:42 UTC (rev 282307)
@@ -35,6 +35,7 @@
 #include <WebCore/GStreamerCommon.h>
 #endif
 
+#include <WebCore/ApplicationGLib.h>
 #include <WebCore/MemoryCache.h>
 
 #if PLATFORM(WAYLAND)
@@ -108,6 +109,12 @@
 
     if (parameters.memoryPressureHandlerConfiguration)
         MemoryPressureHandler::singleton().setConfiguration(WTFMove(*parameters.memoryPressureHandlerConfiguration));
+
+    if (!parameters.applicationID.isEmpty())
+        WebCore::setApplicationID(parameters.applicationID);
+
+    if (!parameters.applicationName.isEmpty())
+        WebCore::setApplicationName(parameters.applicationName);
 }
 
 void WebProcess::platformSetWebsiteDataStoreParameters(WebProcessDataStoreParameters&&)

Modified: trunk/Source/cmake/OptionsGTK.cmake (282306 => 282307)


--- trunk/Source/cmake/OptionsGTK.cmake	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/cmake/OptionsGTK.cmake	2021-09-11 11:34:42 UTC (rev 282307)
@@ -153,6 +153,8 @@
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_TIME PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_WEEK PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYOUT_FORMATTING_CONTEXT PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION_PLAYLIST PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MOUSE_CURSOR_SCALE PRIVATE ON)

Modified: trunk/Source/cmake/OptionsWPE.cmake (282306 => 282307)


--- trunk/Source/cmake/OptionsWPE.cmake	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/cmake/OptionsWPE.cmake	2021-09-11 11:34:42 UTC (rev 282307)
@@ -51,6 +51,8 @@
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FILTERS_LEVEL_2 PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GPU_PROCESS PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYOUT_FORMATTING_CONTEXT PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION_PLAYLIST PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)

Modified: trunk/Source/cmake/WebKitFeatures.cmake (282306 => 282307)


--- trunk/Source/cmake/WebKitFeatures.cmake	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/cmake/WebKitFeatures.cmake	2021-09-11 11:34:42 UTC (rev 282307)
@@ -169,6 +169,9 @@
     WEBKIT_OPTION_DEFINE(ENABLE_MATHML "Toggle MathML support" PRIVATE ON)
     WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_CAPTURE "Toggle Media Capture support" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_CONTROLS_SCRIPT "Toggle definition of media controls in _javascript_" PRIVATE ON)
+    WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_SESSION "Toggle Media Session support" PRIVATE OFF)
+    WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_SESSION_COORDINATOR "Toggle Media Session Coordinator support" PRIVATE OFF)
+    WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_SESSION_PLAYLIST "Toggle Media Session Playlist support" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_SOURCE "Toggle Media Source support" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_STATISTICS "Toggle Media Statistics support" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_STREAM "Toggle Media Stream support" PRIVATE OFF)

Modified: trunk/Tools/Scripts/webkitpy/style/checker.py (282306 => 282307)


--- trunk/Tools/Scripts/webkitpy/style/checker.py	2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Tools/Scripts/webkitpy/style/checker.py	2021-09-11 11:34:42 UTC (rev 282307)
@@ -181,6 +181,11 @@
      ["-readability/enum_casing"]),
 
     ([
+     # Forward declarations of GLib/GIO functions use underscores.
+     os.path.join('Source', 'WTF', 'wtf', 'glib', 'GRefPtr.h')],
+     ["-readability/naming/underscores"]),
+
+    ([
       # To use GStreamer GL without conflicts of GL symbols,
       # we should include gst/gl/gl.h before including OpenGL[ES]Shims
       os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'MediaPlayerPrivateGStreamer.cpp')],
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to