<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[282307] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/282307">282307</a></dd>
<dt>Author</dt> <dd>philn@webkit.org</dd>
<dt>Date</dt> <dd>2021-09-11 04:34:42 -0700 (Sat, 11 Sep 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkChangeLog">trunk/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformglibTestExpectations">trunk/LayoutTests/platform/glib/TestExpectations</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfglibGRefPtrcpp">trunk/Source/WTF/wtf/glib/GRefPtr.cpp</a></li>
<li><a href="#trunkSourceWTFwtfglibGRefPtrh">trunk/Source/WTF/wtf/glib/GRefPtr.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasessionMediaImageh">trunk/Source/WebCore/Modules/mediasession/MediaImage.h</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasessionMediaSessioncpp">trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesmediasessionMediaSessionh">trunk/Source/WebCore/Modules/mediasession/MediaSession.h</a></li>
<li><a href="#trunkSourceWebCorePlatformGTKcmake">trunk/Source/WebCore/PlatformGTK.cmake</a></li>
<li><a href="#trunkSourceWebCorePlatformWPEcmake">trunk/Source/WebCore/PlatformWPE.cmake</a></li>
<li><a href="#trunkSourceWebCoreplatformLogInitializationcpp">trunk/Source/WebCore/platform/LogInitialization.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformPlatformScreenh">trunk/Source/WebCore/platform/PlatformScreen.h</a></li>
<li><a href="#trunkSourceWebCoreplatformRemoteCommandListenercpp">trunk/Source/WebCore/platform/RemoteCommandListener.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformSourcesGLibtxt">trunk/Source/WebCore/platform/SourcesGLib.txt</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioPlatformMediaSessionManagercpp">trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsImageFrameh">trunk/Source/WebCore/platform/graphics/ImageFrame.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsImageOrientationh">trunk/Source/WebCore/platform/graphics/ImageOrientation.h</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitSharedWebProcessCreationParameterscpp">trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp</a></li>
<li><a href="#trunkSourceWebKitSharedWebProcessCreationParametersh">trunk/Source/WebKit/Shared/WebProcessCreationParameters.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessAPIglibWebKitSettingscpp">trunk/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessLauncherglibBubblewrapLaunchercpp">trunk/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessglibWebProcessPoolGLibcpp">trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp</a></li>
<li><a href="#trunkSourceWebKitWebProcessglibWebProcessGLibcpp">trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp</a></li>
<li><a href="#trunkSourcecmakeOptionsGTKcmake">trunk/Source/cmake/OptionsGTK.cmake</a></li>
<li><a href="#trunkSourcecmakeOptionsWPEcmake">trunk/Source/cmake/OptionsWPE.cmake</a></li>
<li><a href="#trunkSourcecmakeWebKitFeaturescmake">trunk/Source/cmake/WebKitFeatures.cmake</a></li>
<li><a href="#trunkToolsScriptswebkitpystylecheckerpy">trunk/Tools/Scripts/webkitpy/style/checker.py</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformaudioglibMediaSessionManagerGLibcpp">trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioglibMediaSessionManagerGLibh">trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.h</a></li>
<li><a href="#trunkSourceWebCoreplatformglibApplicationGLibcpp">trunk/Source/WebCore/platform/glib/ApplicationGLib.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformglibApplicationGLibh">trunk/Source/WebCore/platform/glib/ApplicationGLib.h</a></li>
<li><a href="#trunkSourceWebCoreplatformglibRemoteCommandListenerGLibcpp">trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformglibRemoteCommandListenerGLibh">trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/ChangeLog (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/ChangeLog  2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/ChangeLog     2021-09-11 11:34:42 UTC (rev 282307)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2021-09-11  Philippe Normand  <pnormand@igalia.com>
+
+        [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:
+
</ins><span class="cx"> 2021-09-08  Justin Michaud  <justin_michaud@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Change Justin Michaud's primary email to apple.com
</span></span></pre></div>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/LayoutTests/ChangeLog 2021-09-11 11:34:42 UTC (rev 282307)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2021-09-11  Philippe Normand  <pnormand@igalia.com>
+
+        [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.
+
</ins><span class="cx"> 2021-09-10  Alan Bujtas  <zalan@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Legacy Line Layout] Do not integral round the root inlinebox's top position
</span></span></pre></div>
<a id="trunkLayoutTestsplatformglibTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/glib/TestExpectations (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1418,11 +1418,6 @@
</span><span class="cx"> # Failing since added in r268138.
</span><span class="cx"> webkit.org/b/217815 imported/w3c/web-platform-tests/css/css-masking/clip-path/clip-path-filter-order.html [ ImageOnlyFailure ]
</span><span class="cx"> 
</span><del>-# 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 ]
-
</del><span class="cx"> # This test uses an MPEG-4 video
</span><span class="cx"> media/video-seek-to-current-time.html [ Skip ]
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2021-09-11  Philippe Normand  <pnormand@igalia.com>
+
+        [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:
+
</ins><span class="cx"> 2021-09-10  Alex Christensen  <achristensen@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Use std::not_fn instead of lambda in URLParser
</span></span></pre></div>
<a id="trunkSourceWTFwtfglibGRefPtrcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/glib/GRefPtr.cpp (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -195,6 +195,19 @@
</span><span class="cx">         g_date_time_unref(ptr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+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);
+}
+
</ins><span class="cx"> #if HAVE(GURI)
</span><span class="cx"> template <> GUri* refGPtr(GUri* ptr)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWTFwtfglibGRefPtrh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/glib/GRefPtr.h (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -24,10 +24,15 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(GLIB)
</span><span class="cx"> 
</span><del>-#include <wtf/HashTraits.h>
</del><span class="cx"> #include <algorithm>
</span><span class="cx"> #include <glib.h>
</span><ins>+#include <wtf/HashTraits.h>
</ins><span class="cx"> 
</span><ins>+extern "C" {
+    typedef struct _GDBusNodeInfo GDBusNodeInfo;
+    GDBusNodeInfo* g_dbus_node_info_ref(GDBusNodeInfo*);
+    void g_dbus_node_info_unref(GDBusNodeInfo*);
+};
</ins><span class="cx"> extern "C" void g_object_unref(gpointer);
</span><span class="cx"> extern "C" gpointer g_object_ref_sink(gpointer);
</span><span class="cx"> 
</span><span class="lines">@@ -242,6 +247,8 @@
</span><span class="cx"> template <> WTF_EXPORT_PRIVATE void derefGPtr(GMappedFile*);
</span><span class="cx"> template <> WTF_EXPORT_PRIVATE GDateTime* refGPtr(GDateTime* ptr);
</span><span class="cx"> template <> WTF_EXPORT_PRIVATE void derefGPtr(GDateTime* ptr);
</span><ins>+template <> WTF_EXPORT_PRIVATE GDBusNodeInfo* refGPtr(GDBusNodeInfo* ptr);
+template <> WTF_EXPORT_PRIVATE void derefGPtr(GDBusNodeInfo* ptr);
</ins><span class="cx"> 
</span><span class="cx"> #if HAVE(GURI)
</span><span class="cx"> template <> WTF_EXPORT_PRIVATE GUri* refGPtr(GUri*);
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,80 @@
</span><ins>+2021-09-11  Philippe Normand  <pnormand@igalia.com>
+
+        [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:
+
</ins><span class="cx"> 2021-09-10  Alan Bujtas  <zalan@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Legacy Line Layout] Do not integral round the root inlinebox's top position
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasessionMediaImageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasession/MediaImage.h (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -27,6 +27,9 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(MEDIA_SESSION)
</span><span class="cx"> 
</span><ins>+#include <wtf/Forward.h>
+#include <wtf/text/WTFString.h>
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> struct MediaImage {
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasessionMediaSessioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -51,9 +51,18 @@
</span><span class="cx">     return reinterpret_cast<const void*>(++logIdentifier);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static WTFLogChannel& logChannel() { return LogMedia; }
-static const char* logClassName() { return "MediaSession"; }
</del><ins>+#if !RELEASE_LOG_DISABLED
+static WTFLogChannel& logChannel()
+{
+    return LogMedia;
+}
</ins><span class="cx"> 
</span><ins>+static const char* logClassName()
+{
+    return "MediaSession";
+}
+#endif
+
</ins><span class="cx"> static PlatformMediaSession::RemoteControlCommandType platformCommandForMediaSessionAction(MediaSessionAction action)
</span><span class="cx"> {
</span><span class="cx">     static const auto commandMap = makeNeverDestroyed([] {
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesmediasessionMediaSessionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/mediasession/MediaSession.h (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -93,7 +93,9 @@
</span><span class="cx">     };
</span><span class="cx">     WEBCORE_EXPORT bool callActionHandler(const MediaSessionActionDetails&, TriggerGestureIndicator = TriggerGestureIndicator::Yes);
</span><span class="cx"> 
</span><ins>+#if !RELEASE_LOG_DISABLED
</ins><span class="cx">     const Logger& logger() const { return *m_logger.get(); }
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx">     class Observer : public CanMakeWeakPtr<Observer> {
</span><span class="cx">     public:
</span></span></pre></div>
<a id="trunkSourceWebCorePlatformGTKcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/PlatformGTK.cmake (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -26,7 +26,9 @@
</span><span class="cx">     "${WEBCORE_DIR}/editing/atk"
</span><span class="cx">     "${WEBCORE_DIR}/page/gtk"
</span><span class="cx">     "${WEBCORE_DIR}/platform/adwaita"
</span><ins>+    "${WEBCORE_DIR}/platform/audio/glib"
</ins><span class="cx">     "${WEBCORE_DIR}/platform/generic"
</span><ins>+    "${WEBCORE_DIR}/platform/glib"
</ins><span class="cx">     "${WEBCORE_DIR}/platform/gtk"
</span><span class="cx">     "${WEBCORE_DIR}/platform/graphics/egl"
</span><span class="cx">     "${WEBCORE_DIR}/platform/graphics/glx"
</span><span class="lines">@@ -53,6 +55,8 @@
</span><span class="cx"> list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
</span><span class="cx">     platform/adwaita/ScrollbarThemeAdwaita.h
</span><span class="cx"> 
</span><ins>+    platform/glib/ApplicationGLib.h
+
</ins><span class="cx">     platform/graphics/x11/PlatformDisplayX11.h
</span><span class="cx">     platform/graphics/x11/XErrorTrapper.h
</span><span class="cx">     platform/graphics/x11/XUniquePtr.h
</span></span></pre></div>
<a id="trunkSourceWebCorePlatformWPEcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/PlatformWPE.cmake (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -19,6 +19,8 @@
</span><span class="cx"> list(APPEND WebCore_PRIVATE_INCLUDE_DIRECTORIES
</span><span class="cx">     "${WEBCORE_DIR}/accessibility/atk"
</span><span class="cx">     "${WEBCORE_DIR}/platform/adwaita"
</span><ins>+    "${WEBCORE_DIR}/platform/audio/glib"
+    "${WEBCORE_DIR}/platform/glib"
</ins><span class="cx">     "${WEBCORE_DIR}/platform/graphics/egl"
</span><span class="cx">     "${WEBCORE_DIR}/platform/graphics/epoxy"
</span><span class="cx">     "${WEBCORE_DIR}/platform/graphics/glx"
</span><span class="lines">@@ -36,6 +38,8 @@
</span><span class="cx"> )
</span><span class="cx"> 
</span><span class="cx"> list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
</span><ins>+    platform/glib/ApplicationGLib.h
+
</ins><span class="cx">     platform/graphics/wayland/PlatformDisplayWayland.h
</span><span class="cx">     platform/graphics/wayland/WlUniquePtr.h
</span><span class="cx"> )
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformLogInitializationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/LogInitialization.cpp (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -65,6 +65,7 @@
</span><span class="cx"> 
</span><span class="cx"> WTFLogChannel* getLogChannel(const String& name)
</span><span class="cx"> {
</span><ins>+    UNUSED_PARAM(name);
</ins><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformPlatformScreenh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/PlatformScreen.h (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -48,6 +48,12 @@
</span><span class="cx"> typedef struct CGColorSpace *CGColorSpaceRef;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+// 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
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class DestinationColorSpace;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformRemoteCommandListenercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/RemoteCommandListener.cpp (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -30,6 +30,10 @@
</span><span class="cx"> #include "RemoteCommandListenerCocoa.h"
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if USE(GLIB)
+#include "RemoteCommandListenerGLib.h"
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> static RemoteCommandListener::CreationFunction& remoteCommandListenerCreationFunction()
</span><span class="lines">@@ -48,8 +52,11 @@
</span><span class="cx">     remoteCommandListenerCreationFunction() = [] (RemoteCommandListenerClient& client) {
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">         return RemoteCommandListenerCocoa::create(client);
</span><ins>+#elif USE(GLIB)
+        return RemoteCommandListenerGLib::create(client);
</ins><span class="cx"> #else
</span><del>-        return RemoteCommandListener::create(client);
</del><ins>+        UNUSED_PARAM(client);
+        return nullptr;
</ins><span class="cx"> #endif
</span><span class="cx">     };
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformSourcesGLibtxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/SourcesGLib.txt (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -22,11 +22,14 @@
</span><span class="cx"> // THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> 
</span><span class="cx"> platform/audio/glib/AudioBusGLib.cpp
</span><ins>+platform/audio/glib/MediaSessionManagerGLib.cpp
</ins><span class="cx"> 
</span><ins>+platform/glib/ApplicationGLib.cpp
</ins><span class="cx"> platform/glib/FileMonitorGLib.cpp
</span><span class="cx"> platform/glib/KeyedDecoderGlib.cpp
</span><span class="cx"> platform/glib/KeyedEncoderGlib.cpp
</span><span class="cx"> platform/glib/LowPowerModeNotifierGLib.cpp
</span><ins>+platform/glib/RemoteCommandListenerGLib.cpp
</ins><span class="cx"> platform/glib/SharedBufferGlib.cpp
</span><span class="cx"> platform/glib/UserAgentGLib.cpp
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioPlatformMediaSessionManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -74,12 +74,12 @@
</span><span class="cx">     return sharedPlatformMediaSessionManager().get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if !PLATFORM(COCOA)
</del><ins>+#if !PLATFORM(COCOA) && !USE(GLIB)
</ins><span class="cx"> std::unique_ptr<PlatformMediaSessionManager> PlatformMediaSessionManager::create()
</span><span class="cx"> {
</span><span class="cx">     return std::unique_ptr<PlatformMediaSessionManager>(new PlatformMediaSessionManager);
</span><span class="cx"> }
</span><del>-#endif // !PLATFORM(COCOA)
</del><ins>+#endif // !PLATFORM(COCOA) && !USE(GLIB)
</ins><span class="cx"> 
</span><span class="cx"> void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioglibMediaSessionManagerGLibcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp (0 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,613 @@
</span><ins>+/*
+ *  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)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioglibMediaSessionManagerGLibh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.h (0 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,118 @@
</span><ins>+/*
+ *  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)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformglibApplicationGLibcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/glib/ApplicationGLib.cpp (0 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+/*
+ *  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
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformglibApplicationGLibh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/glib/ApplicationGLib.h (0 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+/*
+ *  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)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformglibRemoteCommandListenerGLibcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.cpp (0 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/*
+ *  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
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformglibRemoteCommandListenerGLibh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.h (0 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+/*
+ *  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)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageFrameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ImageFrame.h (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -33,6 +33,12 @@
</span><span class="cx"> #include "NativeImage.h"
</span><span class="cx"> #include <wtf/Seconds.h>
</span><span class="cx"> 
</span><ins>+// 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
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class ImageFrame {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageOrientationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ImageOrientation.h (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -30,6 +30,12 @@
</span><span class="cx"> #include "FloatSize.h"
</span><span class="cx"> #include <wtf/EnumTraits.h>
</span><span class="cx"> 
</span><ins>+// 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
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> struct ImageOrientation {
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2021-09-11  Philippe Normand  <pnormand@igalia.com>
+
+        [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):
+
</ins><span class="cx"> 2021-09-10  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Implement navigation reporting for Cross-Origin-Opener-Policy
</span></span></pre></div>
<a id="trunkSourceWebKitSharedWebProcessCreationParameterscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -214,6 +214,10 @@
</span><span class="cx"> #if PLATFORM(GTK) || PLATFORM(WPE)
</span><span class="cx">     encoder << memoryPressureHandlerConfiguration;
</span><span class="cx"> #endif
</span><ins>+#if USE(GLIB)
+    encoder << applicationID;
+    encoder << applicationName;
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool WebProcessCreationParameters::decode(IPC::Decoder& decoder, WebProcessCreationParameters& parameters)
</span><span class="lines">@@ -587,6 +591,13 @@
</span><span class="cx">     parameters.memoryPressureHandlerConfiguration = WTFMove(*memoryPressureHandlerConfiguration);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if USE(GLIB)
+    if (!decoder.decode(parameters.applicationID))
+        return false;
+    if (!decoder.decode(parameters.applicationName))
+        return false;
+#endif
+
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitSharedWebProcessCreationParametersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Shared/WebProcessCreationParameters.h (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -260,6 +260,11 @@
</span><span class="cx"> #if PLATFORM(GTK) || PLATFORM(WPE)
</span><span class="cx">     std::optional<MemoryPressureHandler::Configuration> memoryPressureHandlerConfiguration;
</span><span class="cx"> #endif
</span><ins>+
+#if USE(GLIB)
+    String applicationID;
+    String applicationName;
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessAPIglibWebKitSettingscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -196,6 +196,13 @@
</span><span class="cx">     prefs->setPeerConnectionEnabled(true);
</span><span class="cx"> #endif
</span><span class="cx"> #endif
</span><ins>+
+    // 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
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void webKitSettingsSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessLauncherglibBubblewrapLaunchercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -130,6 +130,22 @@
</span><span class="cx">     return memfd;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+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;
+}
+
</ins><span class="cx"> static int createFlatpakInfo()
</span><span class="cx"> {
</span><span class="cx">     static NeverDestroyed<GUniquePtr<char>> data;
</span><span class="lines">@@ -138,13 +154,10 @@
</span><span class="cx">     if (!data.get()) {
</span><span class="cx">         // xdg-desktop-portal relates your name to certain permissions so we want
</span><span class="cx">         // them to be application unique which is best done via GApplication.
</span><del>-        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);
</del><ins>+        GUniqueOutPtr<GError> error;
+        const char* appID = applicationId(&error.outPtr());
</ins><span class="cx">         if (!appID)
</span><del>-            g_error("GApplication must have a valid ID for xdg-desktop-portal access in the WebKit sandbox.");
</del><ins>+            g_error("Unable to configure xdg-desktop-portal access in the WebKit sandbox: %s", error->message);
</ins><span class="cx"> 
</span><span class="cx">         GUniquePtr<GKeyFile> keyFile(g_key_file_new());
</span><span class="cx">         g_key_file_set_string(keyFile.get(), "Application", "name", appID);
</span><span class="lines">@@ -207,6 +220,16 @@
</span><span class="cx">         if (enableLogging)
</span><span class="cx">             proxyArgs.append("--log");
</span><span class="cx"> 
</span><ins>+        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
+
</ins><span class="cx">         proxyArgs.appendVector(m_permissions);
</span><span class="cx"> 
</span><span class="cx">         int proxyFd = argsToFd(proxyArgs, "dbus-proxy");
</span><span class="lines">@@ -236,7 +259,6 @@
</span><span class="cx"> 
</span><span class="cx">         ProcessLauncher::LaunchOptions launchOptions;
</span><span class="cx">         launchOptions.processType = ProcessLauncher::ProcessType::DBusProxy;
</span><del>-        GUniqueOutPtr<GError> error;
</del><span class="cx">         GRefPtr<GSubprocess> process = bubblewrapSpawn(launcher.get(), launchOptions, argv, &error.outPtr());
</span><span class="cx">         if (!process.get())
</span><span class="cx">             g_error("Failed to start dbus proxy: %s", error->message);
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessglibWebProcessPoolGLibcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -109,6 +109,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     parameters.memoryPressureHandlerConfiguration = m_configuration->memoryPressureHandlerConfiguration();
</span><ins>+
+    GApplication* app = g_application_get_default();
+    if (app)
+        parameters.applicationID = g_application_get_application_id(app);
+    parameters.applicationName = g_get_application_name();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebProcessPool::platformInvalidateContext()
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessglibWebProcessGLibcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include <WebCore/GStreamerCommon.h>
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#include <WebCore/ApplicationGLib.h>
</ins><span class="cx"> #include <WebCore/MemoryCache.h>
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(WAYLAND)
</span><span class="lines">@@ -108,6 +109,12 @@
</span><span class="cx"> 
</span><span class="cx">     if (parameters.memoryPressureHandlerConfiguration)
</span><span class="cx">         MemoryPressureHandler::singleton().setConfiguration(WTFMove(*parameters.memoryPressureHandlerConfiguration));
</span><ins>+
+    if (!parameters.applicationID.isEmpty())
+        WebCore::setApplicationID(parameters.applicationID);
+
+    if (!parameters.applicationName.isEmpty())
+        WebCore::setApplicationName(parameters.applicationName);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebProcess::platformSetWebsiteDataStoreParameters(WebProcessDataStoreParameters&&)
</span></span></pre></div>
<a id="trunkSourcecmakeOptionsGTKcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/cmake/OptionsGTK.cmake (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -153,6 +153,8 @@
</span><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_TIME PRIVATE ON)
</span><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_WEEK PRIVATE ON)
</span><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYOUT_FORMATTING_CONTEXT PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
</span><ins>+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})
</ins><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
</span><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
</span><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MOUSE_CURSOR_SCALE PRIVATE ON)
</span></span></pre></div>
<a id="trunkSourcecmakeOptionsWPEcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/cmake/OptionsWPE.cmake (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -51,6 +51,8 @@
</span><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FILTERS_LEVEL_2 PRIVATE ON)
</span><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GPU_PROCESS PRIVATE OFF)
</span><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYOUT_FORMATTING_CONTEXT PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
</span><ins>+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})
</ins><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
</span><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
</span><span class="cx"> WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
</span></span></pre></div>
<a id="trunkSourcecmakeWebKitFeaturescmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/cmake/WebKitFeatures.cmake (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -169,6 +169,9 @@
</span><span class="cx">     WEBKIT_OPTION_DEFINE(ENABLE_MATHML "Toggle MathML support" PRIVATE ON)
</span><span class="cx">     WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_CAPTURE "Toggle Media Capture support" PRIVATE OFF)
</span><span class="cx">     WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_CONTROLS_SCRIPT "Toggle definition of media controls in Javascript" PRIVATE ON)
</span><ins>+    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)
</ins><span class="cx">     WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_SOURCE "Toggle Media Source support" PRIVATE OFF)
</span><span class="cx">     WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_STATISTICS "Toggle Media Statistics support" PRIVATE OFF)
</span><span class="cx">     WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_STREAM "Toggle Media Stream support" PRIVATE OFF)
</span></span></pre></div>
<a id="trunkToolsScriptswebkitpystylecheckerpy"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/webkitpy/style/checker.py (282306 => 282307)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -181,6 +181,11 @@
</span><span class="cx">      ["-readability/enum_casing"]),
</span><span class="cx"> 
</span><span class="cx">     ([
</span><ins>+     # Forward declarations of GLib/GIO functions use underscores.
+     os.path.join('Source', 'WTF', 'wtf', 'glib', 'GRefPtr.h')],
+     ["-readability/naming/underscores"]),
+
+    ([
</ins><span class="cx">       # To use GStreamer GL without conflicts of GL symbols,
</span><span class="cx">       # we should include gst/gl/gl.h before including OpenGL[ES]Shims
</span><span class="cx">       os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'MediaPlayerPrivateGStreamer.cpp')],
</span></span></pre>
</div>
</div>

</body>
</html>