Diff
Modified: trunk/ChangeLog (282306 => 282307)
--- trunk/ChangeLog 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/ChangeLog 2021-09-11 11:34:42 UTC (rev 282307)
@@ -1,3 +1,18 @@
+2021-09-11 Philippe Normand <[email protected]>
+
+ [GLIB] MediaSession is not enabled
+ https://bugs.webkit.org/show_bug.cgi?id=217991
+ <rdar://problem/70740119>
+
+ Reviewed by Michael Catanzaro.
+
+ Enable MediaSession as an experimental build feature in CMake ports. The spec status is
+ currently Draft.
+
+ * Source/cmake/OptionsGTK.cmake:
+ * Source/cmake/OptionsWPE.cmake:
+ * Source/cmake/WebKitFeatures.cmake:
+
2021-09-08 Justin Michaud <[email protected]>
Change Justin Michaud's primary email to apple.com
Modified: trunk/LayoutTests/ChangeLog (282306 => 282307)
--- trunk/LayoutTests/ChangeLog 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/LayoutTests/ChangeLog 2021-09-11 11:34:42 UTC (rev 282307)
@@ -1,3 +1,13 @@
+2021-09-11 Philippe Normand <[email protected]>
+
+ [GLIB] MediaSession is not enabled
+ https://bugs.webkit.org/show_bug.cgi?id=217991
+ <rdar://problem/70740119>
+
+ Reviewed by Michael Catanzaro.
+
+ * platform/glib/TestExpectations: Unskip media-session tests.
+
2021-09-10 Alan Bujtas <[email protected]>
[Legacy Line Layout] Do not integral round the root inlinebox's top position
Modified: trunk/LayoutTests/platform/glib/TestExpectations (282306 => 282307)
--- trunk/LayoutTests/platform/glib/TestExpectations 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/LayoutTests/platform/glib/TestExpectations 2021-09-11 11:34:42 UTC (rev 282307)
@@ -1418,11 +1418,6 @@
# Failing since added in r268138.
webkit.org/b/217815 imported/w3c/web-platform-tests/css/css-masking/clip-path/clip-path-filter-order.html [ ImageOnlyFailure ]
-# MediaSession is not enabled in GTK/WPE.
-webkit.org/b/217991 imported/w3c/web-platform-tests/mediasession/ [ Skip ]
-webkit.org/b/217991 media/media-session/ [ Skip ]
-webkit.org/b/217991 fast/mediasession/ [ Skip ]
-
# This test uses an MPEG-4 video
media/video-seek-to-current-time.html [ Skip ]
Modified: trunk/Source/WTF/ChangeLog (282306 => 282307)
--- trunk/Source/WTF/ChangeLog 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WTF/ChangeLog 2021-09-11 11:34:42 UTC (rev 282307)
@@ -1,3 +1,18 @@
+2021-09-11 Philippe Normand <[email protected]>
+
+ [GLIB] MediaSession is not enabled
+ https://bugs.webkit.org/show_bug.cgi?id=217991
+ <rdar://problem/70740119>
+
+ Reviewed by Michael Catanzaro.
+
+ GRefPtr template specialization for GDBusNodeInfo.
+
+ * wtf/glib/GRefPtr.cpp:
+ (WTF::refGPtr):
+ (WTF::derefGPtr):
+ * wtf/glib/GRefPtr.h:
+
2021-09-10 Alex Christensen <[email protected]>
Use std::not_fn instead of lambda in URLParser
Modified: trunk/Source/WTF/wtf/glib/GRefPtr.cpp (282306 => 282307)
--- trunk/Source/WTF/wtf/glib/GRefPtr.cpp 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WTF/wtf/glib/GRefPtr.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -195,6 +195,19 @@
g_date_time_unref(ptr);
}
+template <> GDBusNodeInfo* refGPtr(GDBusNodeInfo* ptr)
+{
+ if (ptr)
+ g_dbus_node_info_ref(ptr);
+ return ptr;
+}
+
+template <> void derefGPtr(GDBusNodeInfo* ptr)
+{
+ if (ptr)
+ g_dbus_node_info_unref(ptr);
+}
+
#if HAVE(GURI)
template <> GUri* refGPtr(GUri* ptr)
{
Modified: trunk/Source/WTF/wtf/glib/GRefPtr.h (282306 => 282307)
--- trunk/Source/WTF/wtf/glib/GRefPtr.h 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WTF/wtf/glib/GRefPtr.h 2021-09-11 11:34:42 UTC (rev 282307)
@@ -24,10 +24,15 @@
#if USE(GLIB)
-#include <wtf/HashTraits.h>
#include <algorithm>
#include <glib.h>
+#include <wtf/HashTraits.h>
+extern "C" {
+ typedef struct _GDBusNodeInfo GDBusNodeInfo;
+ GDBusNodeInfo* g_dbus_node_info_ref(GDBusNodeInfo*);
+ void g_dbus_node_info_unref(GDBusNodeInfo*);
+};
extern "C" void g_object_unref(gpointer);
extern "C" gpointer g_object_ref_sink(gpointer);
@@ -242,6 +247,8 @@
template <> WTF_EXPORT_PRIVATE void derefGPtr(GMappedFile*);
template <> WTF_EXPORT_PRIVATE GDateTime* refGPtr(GDateTime* ptr);
template <> WTF_EXPORT_PRIVATE void derefGPtr(GDateTime* ptr);
+template <> WTF_EXPORT_PRIVATE GDBusNodeInfo* refGPtr(GDBusNodeInfo* ptr);
+template <> WTF_EXPORT_PRIVATE void derefGPtr(GDBusNodeInfo* ptr);
#if HAVE(GURI)
template <> WTF_EXPORT_PRIVATE GUri* refGPtr(GUri*);
Modified: trunk/Source/WebCore/ChangeLog (282306 => 282307)
--- trunk/Source/WebCore/ChangeLog 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/ChangeLog 2021-09-11 11:34:42 UTC (rev 282307)
@@ -1,3 +1,80 @@
+2021-09-11 Philippe Normand <[email protected]>
+
+ [GLIB] MediaSession is not enabled
+ https://bugs.webkit.org/show_bug.cgi?id=217991
+ <rdar://problem/70740119>
+
+ Reviewed by Michael Catanzaro.
+
+ Implementation of a GLib MediaSessionManager, able to provide a MPRIS DBus service, so that
+ third-party host tools can query the media playback status and potentially emit remote
+ control commands as well.
+
+ Covered by media-session layout tests now unskipped.
+
+ * Modules/mediasession/MediaImage.h:
+ * Modules/mediasession/MediaSession.cpp:
+ (WebCore::logChannel):
+ (WebCore::logClassName):
+ * Modules/mediasession/MediaSession.h:
+ * PlatformGTK.cmake:
+ * PlatformWPE.cmake:
+ * platform/LogInitialization.cpp:
+ (WebCore::getLogChannel):
+ * platform/PlatformScreen.h:
+ * platform/RemoteCommandListener.cpp:
+ (WebCore::RemoteCommandListener::resetCreationFunction):
+ * platform/SourcesGLib.txt:
+ * platform/audio/PlatformMediaSessionManager.cpp:
+ * platform/audio/glib/MediaSessionManagerGLib.cpp: Added.
+ (WebCore::PlatformMediaSessionManager::create):
+ (WebCore::MediaSessionManagerGLib::MediaSessionManagerGLib):
+ (WebCore::MediaSessionManagerGLib::~MediaSessionManagerGLib):
+ (WebCore::getCommand):
+ (WebCore::handleMethodCall):
+ (WebCore::getProperty):
+ (WebCore::handleGetProperty):
+ (WebCore::handleSetProperty):
+ (WebCore::MediaSessionManagerGLib::setupMpris):
+ (WebCore::MediaSessionManagerGLib::busAcquired):
+ (WebCore::MediaSessionManagerGLib::nameLost):
+ (WebCore::MediaSessionManagerGLib::beginInterruption):
+ (WebCore::MediaSessionManagerGLib::scheduleSessionStatusUpdate):
+ (WebCore::MediaSessionManagerGLib::sessionWillBeginPlayback):
+ (WebCore::MediaSessionManagerGLib::sessionDidEndRemoteScrubbing):
+ (WebCore::MediaSessionManagerGLib::addSession):
+ (WebCore::MediaSessionManagerGLib::removeSession):
+ (WebCore::MediaSessionManagerGLib::setCurrentSession):
+ (WebCore::MediaSessionManagerGLib::sessionWillEndPlayback):
+ (WebCore::MediaSessionManagerGLib::sessionStateChanged):
+ (WebCore::MediaSessionManagerGLib::clientCharacteristicsChanged):
+ (WebCore::MediaSessionManagerGLib::sessionCanProduceAudioChanged):
+ (WebCore::MediaSessionManagerGLib::addSupportedCommand):
+ (WebCore::MediaSessionManagerGLib::removeSupportedCommand):
+ (WebCore::MediaSessionManagerGLib::nowPlayingEligibleSession):
+ (WebCore::MediaSessionManagerGLib::updateNowPlayingInfo):
+ (WebCore::MediaSessionManagerGLib::getPlaybackStatusAsGVariant):
+ (WebCore::MediaSessionManagerGLib::getActiveSessionPosition):
+ (WebCore::MediaSessionManagerGLib::dispatch):
+ (WebCore::MediaSessionManagerGLib::emitPropertiesChanged):
+ * platform/audio/glib/MediaSessionManagerGLib.h: Added.
+ (WebCore::MediaSessionManagerGLib::nameAcquired):
+ (WebCore::MediaSessionManagerGLib::getMetadataAsGVariant const):
+ (WebCore::MediaSessionManagerGLib::providePresentingApplicationPIDIfNecessary):
+ * platform/glib/ApplicationGLib.cpp: Added.
+ (WebCore::setApplicationName):
+ (WebCore::getApplicationName):
+ (WebCore::setApplicationID):
+ (WebCore::getApplicationID):
+ * platform/glib/ApplicationGLib.h: Added.
+ * platform/glib/RemoteCommandListenerGLib.cpp: Added.
+ (WebCore::RemoteCommandListenerGLib::create):
+ (WebCore::RemoteCommandListenerGLib::updateSupportedCommands):
+ (WebCore::RemoteCommandListenerGLib::RemoteCommandListenerGLib):
+ * platform/glib/RemoteCommandListenerGLib.h: Added.
+ * platform/graphics/ImageFrame.h:
+ * platform/graphics/ImageOrientation.h:
+
2021-09-10 Alan Bujtas <[email protected]>
[Legacy Line Layout] Do not integral round the root inlinebox's top position
Modified: trunk/Source/WebCore/Modules/mediasession/MediaImage.h (282306 => 282307)
--- trunk/Source/WebCore/Modules/mediasession/MediaImage.h 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/Modules/mediasession/MediaImage.h 2021-09-11 11:34:42 UTC (rev 282307)
@@ -27,6 +27,9 @@
#if ENABLE(MEDIA_SESSION)
+#include <wtf/Forward.h>
+#include <wtf/text/WTFString.h>
+
namespace WebCore {
struct MediaImage {
Modified: trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp (282306 => 282307)
--- trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -51,9 +51,18 @@
return reinterpret_cast<const void*>(++logIdentifier);
}
-static WTFLogChannel& logChannel() { return LogMedia; }
-static const char* logClassName() { return "MediaSession"; }
+#if !RELEASE_LOG_DISABLED
+static WTFLogChannel& logChannel()
+{
+ return LogMedia;
+}
+static const char* logClassName()
+{
+ return "MediaSession";
+}
+#endif
+
static PlatformMediaSession::RemoteControlCommandType platformCommandForMediaSessionAction(MediaSessionAction action)
{
static const auto commandMap = makeNeverDestroyed([] {
Modified: trunk/Source/WebCore/Modules/mediasession/MediaSession.h (282306 => 282307)
--- trunk/Source/WebCore/Modules/mediasession/MediaSession.h 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/Modules/mediasession/MediaSession.h 2021-09-11 11:34:42 UTC (rev 282307)
@@ -93,7 +93,9 @@
};
WEBCORE_EXPORT bool callActionHandler(const MediaSessionActionDetails&, TriggerGestureIndicator = TriggerGestureIndicator::Yes);
+#if !RELEASE_LOG_DISABLED
const Logger& logger() const { return *m_logger.get(); }
+#endif
class Observer : public CanMakeWeakPtr<Observer> {
public:
Modified: trunk/Source/WebCore/PlatformGTK.cmake (282306 => 282307)
--- trunk/Source/WebCore/PlatformGTK.cmake 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/PlatformGTK.cmake 2021-09-11 11:34:42 UTC (rev 282307)
@@ -26,7 +26,9 @@
"${WEBCORE_DIR}/editing/atk"
"${WEBCORE_DIR}/page/gtk"
"${WEBCORE_DIR}/platform/adwaita"
+ "${WEBCORE_DIR}/platform/audio/glib"
"${WEBCORE_DIR}/platform/generic"
+ "${WEBCORE_DIR}/platform/glib"
"${WEBCORE_DIR}/platform/gtk"
"${WEBCORE_DIR}/platform/graphics/egl"
"${WEBCORE_DIR}/platform/graphics/glx"
@@ -53,6 +55,8 @@
list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
platform/adwaita/ScrollbarThemeAdwaita.h
+ platform/glib/ApplicationGLib.h
+
platform/graphics/x11/PlatformDisplayX11.h
platform/graphics/x11/XErrorTrapper.h
platform/graphics/x11/XUniquePtr.h
Modified: trunk/Source/WebCore/PlatformWPE.cmake (282306 => 282307)
--- trunk/Source/WebCore/PlatformWPE.cmake 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/PlatformWPE.cmake 2021-09-11 11:34:42 UTC (rev 282307)
@@ -19,6 +19,8 @@
list(APPEND WebCore_PRIVATE_INCLUDE_DIRECTORIES
"${WEBCORE_DIR}/accessibility/atk"
"${WEBCORE_DIR}/platform/adwaita"
+ "${WEBCORE_DIR}/platform/audio/glib"
+ "${WEBCORE_DIR}/platform/glib"
"${WEBCORE_DIR}/platform/graphics/egl"
"${WEBCORE_DIR}/platform/graphics/epoxy"
"${WEBCORE_DIR}/platform/graphics/glx"
@@ -36,6 +38,8 @@
)
list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
+ platform/glib/ApplicationGLib.h
+
platform/graphics/wayland/PlatformDisplayWayland.h
platform/graphics/wayland/WlUniquePtr.h
)
Modified: trunk/Source/WebCore/platform/LogInitialization.cpp (282306 => 282307)
--- trunk/Source/WebCore/platform/LogInitialization.cpp 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/LogInitialization.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -65,6 +65,7 @@
WTFLogChannel* getLogChannel(const String& name)
{
+ UNUSED_PARAM(name);
return nullptr;
}
Modified: trunk/Source/WebCore/platform/PlatformScreen.h (282306 => 282307)
--- trunk/Source/WebCore/platform/PlatformScreen.h 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/PlatformScreen.h 2021-09-11 11:34:42 UTC (rev 282307)
@@ -48,6 +48,12 @@
typedef struct CGColorSpace *CGColorSpaceRef;
#endif
+// X11 headers define a bunch of macros with common terms, interfering with WebCore and WTF enum values.
+// As a workaround, we explicitly undef them here.
+#if defined(None)
+#undef None
+#endif
+
namespace WebCore {
class DestinationColorSpace;
Modified: trunk/Source/WebCore/platform/RemoteCommandListener.cpp (282306 => 282307)
--- trunk/Source/WebCore/platform/RemoteCommandListener.cpp 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/RemoteCommandListener.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -30,6 +30,10 @@
#include "RemoteCommandListenerCocoa.h"
#endif
+#if USE(GLIB)
+#include "RemoteCommandListenerGLib.h"
+#endif
+
namespace WebCore {
static RemoteCommandListener::CreationFunction& remoteCommandListenerCreationFunction()
@@ -48,8 +52,11 @@
remoteCommandListenerCreationFunction() = [] (RemoteCommandListenerClient& client) {
#if PLATFORM(COCOA)
return RemoteCommandListenerCocoa::create(client);
+#elif USE(GLIB)
+ return RemoteCommandListenerGLib::create(client);
#else
- return RemoteCommandListener::create(client);
+ UNUSED_PARAM(client);
+ return nullptr;
#endif
};
}
Modified: trunk/Source/WebCore/platform/SourcesGLib.txt (282306 => 282307)
--- trunk/Source/WebCore/platform/SourcesGLib.txt 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/SourcesGLib.txt 2021-09-11 11:34:42 UTC (rev 282307)
@@ -22,11 +22,14 @@
// THE POSSIBILITY OF SUCH DAMAGE.
platform/audio/glib/AudioBusGLib.cpp
+platform/audio/glib/MediaSessionManagerGLib.cpp
+platform/glib/ApplicationGLib.cpp
platform/glib/FileMonitorGLib.cpp
platform/glib/KeyedDecoderGlib.cpp
platform/glib/KeyedEncoderGlib.cpp
platform/glib/LowPowerModeNotifierGLib.cpp
+platform/glib/RemoteCommandListenerGLib.cpp
platform/glib/SharedBufferGlib.cpp
platform/glib/UserAgentGLib.cpp
Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (282306 => 282307)
--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -74,12 +74,12 @@
return sharedPlatformMediaSessionManager().get();
}
-#if !PLATFORM(COCOA)
+#if !PLATFORM(COCOA) && !USE(GLIB)
std::unique_ptr<PlatformMediaSessionManager> PlatformMediaSessionManager::create()
{
return std::unique_ptr<PlatformMediaSessionManager>(new PlatformMediaSessionManager);
}
-#endif // !PLATFORM(COCOA)
+#endif // !PLATFORM(COCOA) && !USE(GLIB)
void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()
{
Added: trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp (0 => 282307)
--- trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp (rev 0)
+++ trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,613 @@
+/*
+ * Copyright (C) 2021 Igalia S.L
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "MediaSessionManagerGLib.h"
+
+#if USE(GLIB)
+
+#include "ApplicationGLib.h"
+#include "AudioSession.h"
+#include "HTMLMediaElement.h"
+#include "MediaPlayer.h"
+#include "MediaStrategy.h"
+#include "NowPlayingInfo.h"
+#include "PlatformMediaSession.h"
+#include "PlatformStrategies.h"
+
+#include <gio/gio.h>
+#include <wtf/SortedArrayMap.h>
+
+// https://specifications.freedesktop.org/mpris-spec/latest/
+static const char s_mprisInterface[] =
+ "<node>"
+ "<interface name=\"org.mpris.MediaPlayer2\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "<method name=\"Raise\"/>"
+ "<method name=\"Quit\"/>"
+ "<property name=\"CanQuit\" type=\"b\" access=\"read\"/>"
+ "<property name=\"CanRaise\" type=\"b\" access=\"read\"/>"
+ "<property name=\"HasTrackList\" type=\"b\" access=\"read\"/>"
+ "<property name=\"Identity\" type=\"s\" access=\"read\"/>"
+ "<property name=\"DesktopEntry\" type=\"s\" access=\"read\"/>"
+ "<property name=\"SupportedUriSchemes\" type=\"as\" access=\"read\"/>"
+ "<property name=\"SupportedMimeTypes\" type=\"as\" access=\"read\"/>"
+ "</interface>"
+ "<interface name=\"org.mpris.MediaPlayer2.Player\">"
+ "<method name=\"Next\"/>"
+ "<method name=\"Previous\"/>"
+ "<method name=\"Pause\"/>"
+ "<method name=\"PlayPause\"/>"
+ "<method name=\"Stop\"/>"
+ "<method name=\"Play\"/>"
+ "<method name=\"Seek\">"
+ "<arg direction=\"in\" type=\"x\" name=\"Offset\"/>"
+ "</method>"
+ "<method name=\"SetPosition\">"
+ "<arg direction=\"in\" type=\"o\" name=\"TrackId\"/>"
+ "<arg direction=\"in\" type=\"x\" name=\"Position\"/>"
+ "</method>"
+ "<method name=\"OpenUri\">"
+ "<arg direction=\"in\" type=\"s\" name=\"Uri\"/>"
+ "</method>"
+ "<property name=\"PlaybackStatus\" type=\"s\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"Rate\" type=\"d\" access=\"readwrite\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"Metadata\" type=\"a{sv}\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"Volume\" type=\"d\" access=\"readwrite\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"Position\" type=\"x\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"false\"/>"
+ "</property>"
+ "<property name=\"MinimumRate\" type=\"d\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"MaximumRate\" type=\"d\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"CanGoNext\" type=\"b\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"CanGoPrevious\" type=\"b\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"CanPlay\" type=\"b\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"CanPause\" type=\"b\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"CanSeek\" type=\"b\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>"
+ "</property>"
+ "<property name=\"CanControl\" type=\"b\" access=\"read\">"
+ "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"false\"/>"
+ "</property>"
+ "<signal name=\"Seeked\">"
+ "<arg name=\"Position\" type=\"x\"/>"
+ "</signal>"
+ "</interface>"
+ "</node>";
+
+#define DBUS_MPRIS_OBJECT_PATH "/org/mpris/MediaPlayer2"
+#define DBUS_MPRIS_PLAYER_INTERFACE "org.mpris.MediaPlayer2.Player"
+#define DBUS_MPRIS_TRACK_PATH "/org/mpris/MediaPlayer2/webkit"
+
+namespace WebCore {
+
+std::unique_ptr<PlatformMediaSessionManager> PlatformMediaSessionManager::create()
+{
+ return makeUnique<MediaSessionManagerGLib>();
+}
+
+MediaSessionManagerGLib::MediaSessionManagerGLib()
+ : m_nowPlayingManager(platformStrategies()->mediaStrategy().createNowPlayingManager())
+{
+}
+
+MediaSessionManagerGLib::~MediaSessionManagerGLib()
+{
+ if (m_ownerId)
+ g_bus_unown_name(m_ownerId);
+}
+
+static std::optional<PlatformMediaSession::RemoteControlCommandType> getCommand(const char* name)
+{
+ static const std::pair<ComparableASCIILiteral, PlatformMediaSession::RemoteControlCommandType> commandList[] = {
+ { "Next", PlatformMediaSession::NextTrackCommand },
+ { "Pause", PlatformMediaSession::PauseCommand },
+ { "Play", PlatformMediaSession::PlayCommand },
+ { "PlayPause", PlatformMediaSession::TogglePlayPauseCommand },
+ { "Previous", PlatformMediaSession::PreviousTrackCommand },
+ { "Seek", PlatformMediaSession::SeekToPlaybackPositionCommand },
+ { "Stop", PlatformMediaSession::StopCommand }
+ };
+
+ static const SortedArrayMap map { commandList };
+ auto value = map.get(name, PlatformMediaSession::RemoteControlCommandType::NoCommand);
+ if (value == PlatformMediaSession::RemoteControlCommandType::NoCommand)
+ return { };
+ return value;
+}
+
+static void handleMethodCall(GDBusConnection* /* connection */, const char* /* sender */, const char* objectPath, const char* interfaceName, const char* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData)
+{
+ ASSERT(isMainThread());
+ auto command = getCommand(methodName);
+ if (!command) {
+ g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "%s.%s.%s is not available now", objectPath, interfaceName, methodName);
+ return;
+ }
+ auto& manager = *reinterpret_cast<MediaSessionManagerGLib*>(userData);
+ PlatformMediaSession::RemoteCommandArgument argument;
+ if (*command == PlatformMediaSession::SeekToPlaybackPositionCommand) {
+ int64_t offset;
+ g_variant_get(parameters, "(x)", &offset);
+ argument.time = offset / 1000000;
+ }
+ manager.dispatch(*command, argument);
+ g_dbus_method_invocation_return_value(invocation, nullptr);
+}
+
+enum class MprisProperty : uint8_t {
+ NoProperty,
+ CanControl,
+ CanGoNext,
+ CanGoPrevious,
+ CanPause,
+ CanPlay,
+ CanQuit,
+ CanRaise,
+ CanSeek,
+ DesktopEntry,
+ GetMetadata,
+ GetPlaybackStatus,
+ GetPosition,
+ HasTrackList,
+ Identity,
+ SupportedMimeTypes,
+ SupportedUriSchemes,
+};
+
+static std::optional<MprisProperty> getMprisProperty(const char* propertyName)
+{
+ static constexpr std::pair<ComparableASCIILiteral, MprisProperty> propertiesList[] {
+ { "CanControl", MprisProperty::CanControl },
+ { "CanGoNext", MprisProperty::CanGoNext },
+ { "CanGoPrevious", MprisProperty::CanGoPrevious },
+ { "CanPause", MprisProperty::CanPause },
+ { "CanPlay", MprisProperty::CanPlay },
+ { "CanQuit", MprisProperty::CanQuit },
+ { "CanRaise", MprisProperty::CanRaise },
+ { "CanSeek", MprisProperty::CanSeek },
+ { "DesktopEntry", MprisProperty::DesktopEntry },
+ { "HasTrackList", MprisProperty::HasTrackList },
+ { "Identity", MprisProperty::Identity },
+ { "Metadata", MprisProperty::GetMetadata },
+ { "PlaybackStatus", MprisProperty::GetPlaybackStatus },
+ { "Position", MprisProperty::GetPosition },
+ { "SupportedMimeTypes", MprisProperty::SupportedMimeTypes },
+ { "SupportedUriSchemes", MprisProperty::SupportedUriSchemes }
+ };
+ static constexpr SortedArrayMap map { propertiesList };
+ auto value = map.get(propertyName, MprisProperty::NoProperty);
+ if (value == MprisProperty::NoProperty)
+ return { };
+ return value;
+}
+
+static GVariant* handleGetProperty(GDBusConnection*, const char* /* sender */, const char* objectPath, const char* interfaceName, const char* propertyName, GError** error, gpointer userData)
+{
+ ASSERT(isMainThread());
+ auto property = getMprisProperty(propertyName);
+ if (!property) {
+ g_set_error(error, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "%s.%s %s is not supported", objectPath, interfaceName, propertyName);
+ return nullptr;
+ }
+
+ auto& manager = *reinterpret_cast<MediaSessionManagerGLib*>(userData);
+ switch (property.value()) {
+ case MprisProperty::NoProperty:
+ break;
+ case MprisProperty::SupportedUriSchemes:
+ case MprisProperty::SupportedMimeTypes:
+ return g_variant_new_strv(nullptr, 0);
+ case MprisProperty::GetPlaybackStatus:
+ return manager.getPlaybackStatusAsGVariant({ });
+ case MprisProperty::GetMetadata: {
+ auto* variant = manager.getMetadataAsGVariant();
+ if (!variant)
+ return nullptr;
+ return g_variant_ref(variant);
+ }
+ case MprisProperty::GetPosition:
+ return manager.getActiveSessionPosition();
+ case MprisProperty::Identity:
+ return g_variant_new_string(getApplicationName());
+ case MprisProperty::DesktopEntry:
+ return g_variant_new_string("");
+ case MprisProperty::HasTrackList:
+ case MprisProperty::CanQuit:
+ case MprisProperty::CanRaise:
+ return g_variant_new_boolean(false);
+ case MprisProperty::CanSeek:
+ case MprisProperty::CanControl:
+ case MprisProperty::CanGoNext:
+ case MprisProperty::CanGoPrevious:
+ case MprisProperty::CanPlay:
+ case MprisProperty::CanPause:
+ return g_variant_new_boolean(true);
+ }
+
+ return nullptr;
+}
+
+static gboolean handleSetProperty(GDBusConnection*, const char* /* sender */, const char* /* objectPath */, const char* interfaceName, const char* propertyName, GVariant*, GError** error, gpointer)
+{
+ ASSERT(isMainThread());
+ g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "%s:%s setting is not supported", interfaceName, propertyName);
+ return FALSE;
+}
+
+static const GDBusInterfaceVTable gInterfaceVTable = {
+ handleMethodCall, handleGetProperty, handleSetProperty, { nullptr }
+};
+
+bool MediaSessionManagerGLib::setupMpris()
+{
+ if (m_ownerId)
+ return true;
+
+ const auto& applicationID = getApplicationID();
+ m_instanceId = applicationID.isEmpty() ? makeString("org.mpris.MediaPlayer2.webkit.instance", getpid()) : makeString("org.mpris.MediaPlayer2.", applicationID.ascii().data());
+
+ m_ownerId = g_bus_own_name(G_BUS_TYPE_SESSION, m_instanceId.ascii().data(),
+ G_BUS_NAME_OWNER_FLAGS_NONE, reinterpret_cast<GBusAcquiredCallback>(+[](GDBusConnection* connection, const gchar*, gpointer userData) {
+ auto& manager = *reinterpret_cast<MediaSessionManagerGLib*>(userData);
+ manager.busAcquired(connection);
+ }),
+ reinterpret_cast<GBusNameAcquiredCallback>(+[](GDBusConnection* connection, const char*, gpointer userData) {
+ auto& manager = *reinterpret_cast<MediaSessionManagerGLib*>(userData);
+ manager.nameAcquired(connection);
+ }),
+ reinterpret_cast<GBusNameLostCallback>(+[](GDBusConnection* connection, const char*, gpointer userData) {
+ auto& manager = *reinterpret_cast<MediaSessionManagerGLib*>(userData);
+ manager.nameLost(connection);
+ }), this, nullptr);
+
+ GUniqueOutPtr<GError> error;
+ m_mprisInterface = adoptGRef(g_dbus_node_info_new_for_xml(s_mprisInterface, &error.outPtr()));
+ if (!m_mprisInterface) {
+ g_warning("Failed at parsing XML Interface definition: %s", error->message);
+ return false;
+ }
+
+ return true;
+}
+
+void MediaSessionManagerGLib::busAcquired(GDBusConnection* connection)
+{
+ GUniqueOutPtr<GError> error;
+ m_rootRegistrationId = g_dbus_connection_register_object(connection, DBUS_MPRIS_OBJECT_PATH, m_mprisInterface->interfaces[0],
+ &gInterfaceVTable, this, nullptr, &error.outPtr());
+
+ if (!m_rootRegistrationId) {
+ g_warning("Failed to register MPRIS D-Bus object: %s", error->message);
+ return;
+ }
+
+ m_playerRegistrationId = g_dbus_connection_register_object(connection, DBUS_MPRIS_OBJECT_PATH, m_mprisInterface->interfaces[1],
+ &gInterfaceVTable, this, nullptr, &error.outPtr());
+
+ if (!m_playerRegistrationId)
+ g_warning("Failed at MPRIS object registration: %s", error->message);
+}
+
+void MediaSessionManagerGLib::nameLost(GDBusConnection* connection)
+{
+ if (UNLIKELY(!m_connection)) {
+ g_warning("Unable to acquire MPRIS D-Bus session ownership for name %s", m_instanceId.ascii().data());
+ return;
+ }
+
+ m_connection = nullptr;
+ if (!m_rootRegistrationId)
+ return;
+
+ if (g_dbus_connection_unregister_object(connection, m_rootRegistrationId))
+ m_rootRegistrationId = 0;
+ else
+ g_warning("Unable to unregister MPRIS D-Bus object.");
+
+ if (!m_playerRegistrationId)
+ return;
+
+ if (g_dbus_connection_unregister_object(connection, m_playerRegistrationId))
+ m_playerRegistrationId = 0;
+ else
+ g_warning("Unable to unregister MPRIS D-Bus player object.");
+}
+
+void MediaSessionManagerGLib::beginInterruption(PlatformMediaSession::InterruptionType type)
+{
+ if (type == PlatformMediaSession::InterruptionType::SystemInterruption) {
+ forEachSession([] (auto& session) {
+ session.clearHasPlayedSinceLastInterruption();
+ });
+ }
+
+ PlatformMediaSessionManager::beginInterruption(type);
+}
+
+void MediaSessionManagerGLib::scheduleSessionStatusUpdate()
+{
+ callOnMainThread([this] () mutable {
+ m_nowPlayingManager->setSupportsSeeking(computeSupportsSeeking());
+ updateNowPlayingInfo();
+
+ forEachSession([] (auto& session) {
+ session.updateMediaUsageIfChanged();
+ });
+ });
+}
+
+bool MediaSessionManagerGLib::sessionWillBeginPlayback(PlatformMediaSession& session)
+{
+ if (!PlatformMediaSessionManager::sessionWillBeginPlayback(session))
+ return false;
+
+ scheduleSessionStatusUpdate();
+ return true;
+}
+
+void MediaSessionManagerGLib::sessionDidEndRemoteScrubbing(PlatformMediaSession&)
+{
+ scheduleSessionStatusUpdate();
+}
+
+void MediaSessionManagerGLib::addSession(PlatformMediaSession& session)
+{
+ if (!setupMpris())
+ return;
+
+ m_nowPlayingManager->addClient(*this);
+
+ PlatformMediaSessionManager::addSession(session);
+}
+
+void MediaSessionManagerGLib::removeSession(PlatformMediaSession& session)
+{
+ PlatformMediaSessionManager::removeSession(session);
+
+ if (hasNoSession()) {
+ m_nowPlayingManager->removeClient(*this);
+ if (m_ownerId)
+ g_bus_unown_name(m_ownerId);
+ m_ownerId = 0;
+ }
+ scheduleSessionStatusUpdate();
+}
+
+void MediaSessionManagerGLib::setCurrentSession(PlatformMediaSession& session)
+{
+ PlatformMediaSessionManager::setCurrentSession(session);
+
+ m_nowPlayingManager->updateSupportedCommands();
+}
+
+void MediaSessionManagerGLib::sessionWillEndPlayback(PlatformMediaSession& session, DelayCallingUpdateNowPlaying delayCallingUpdateNowPlaying)
+{
+ PlatformMediaSessionManager::sessionWillEndPlayback(session, delayCallingUpdateNowPlaying);
+
+ callOnMainThread([weakSession = makeWeakPtr(session)] {
+ if (weakSession)
+ weakSession->updateMediaUsageIfChanged();
+ });
+
+ if (delayCallingUpdateNowPlaying == DelayCallingUpdateNowPlaying::No)
+ updateNowPlayingInfo();
+ else {
+ callOnMainThread([this] {
+ updateNowPlayingInfo();
+ });
+ }
+}
+
+void MediaSessionManagerGLib::sessionStateChanged(PlatformMediaSession& session)
+{
+ PlatformMediaSessionManager::sessionStateChanged(session);
+
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(&builder, "{sv}", "PlaybackStatus", getPlaybackStatusAsGVariant(&session));
+ emitPropertiesChanged(g_variant_new("(sa{sv}as)", DBUS_MPRIS_PLAYER_INTERFACE, &builder, nullptr));
+ g_variant_builder_clear(&builder);
+}
+
+void MediaSessionManagerGLib::clientCharacteristicsChanged(PlatformMediaSession& session)
+{
+ ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier());
+ if (m_isSeeking) {
+ m_isSeeking = false;
+ GUniqueOutPtr<GError> error;
+ int64_t position = session.nowPlayingInfo()->currentTime * 1000000;
+ if (!g_dbus_connection_emit_signal(m_connection.get(), nullptr, DBUS_MPRIS_OBJECT_PATH, DBUS_MPRIS_PLAYER_INTERFACE, "Seeked", g_variant_new("(x)", position), &error.outPtr()))
+ g_warning("Failed to emit MPRIS Seeked signal: %s", error->message);
+ }
+ scheduleSessionStatusUpdate();
+}
+
+void MediaSessionManagerGLib::sessionCanProduceAudioChanged()
+{
+ ALWAYS_LOG(LOGIDENTIFIER);
+ PlatformMediaSessionManager::sessionCanProduceAudioChanged();
+ scheduleSessionStatusUpdate();
+}
+
+void MediaSessionManagerGLib::addSupportedCommand(PlatformMediaSession::RemoteControlCommandType command)
+{
+ m_nowPlayingManager->addSupportedCommand(command);
+}
+
+void MediaSessionManagerGLib::removeSupportedCommand(PlatformMediaSession::RemoteControlCommandType command)
+{
+ m_nowPlayingManager->removeSupportedCommand(command);
+}
+
+RemoteCommandListener::RemoteCommandsSet MediaSessionManagerGLib::supportedCommands() const
+{
+ return m_nowPlayingManager->supportedCommands();
+}
+
+PlatformMediaSession* MediaSessionManagerGLib::nowPlayingEligibleSession()
+{
+ // FIXME: Fix this layering violation.
+ if (auto element = HTMLMediaElement::bestMediaElementForRemoteControls(MediaElementSession::PlaybackControlsPurpose::NowPlaying))
+ return &element->mediaSession();
+
+ return nullptr;
+}
+
+void MediaSessionManagerGLib::updateNowPlayingInfo()
+{
+ std::optional<NowPlayingInfo> nowPlayingInfo;
+ if (auto* session = nowPlayingEligibleSession())
+ nowPlayingInfo = session->nowPlayingInfo();
+
+ if (!nowPlayingInfo) {
+ if (m_registeredAsNowPlayingApplication) {
+ ALWAYS_LOG(LOGIDENTIFIER, "clearing now playing info");
+ m_nowPlayingManager->clearNowPlayingInfo();
+ }
+
+ m_registeredAsNowPlayingApplication = false;
+ m_nowPlayingActive = false;
+ m_lastUpdatedNowPlayingTitle = emptyString();
+ m_lastUpdatedNowPlayingDuration = NAN;
+ m_lastUpdatedNowPlayingElapsedTime = NAN;
+ m_lastUpdatedNowPlayingInfoUniqueIdentifier = { };
+ m_nowPlayingInfo.clear();
+ return;
+ }
+
+ m_haveEverRegisteredAsNowPlayingApplication = true;
+
+ if (m_nowPlayingManager->setNowPlayingInfo(*nowPlayingInfo))
+ ALWAYS_LOG(LOGIDENTIFIER, "title = \"", nowPlayingInfo->title, "\", isPlaying = ", nowPlayingInfo->isPlaying, ", duration = ", nowPlayingInfo->duration, ", now = ", nowPlayingInfo->currentTime, ", id = ", nowPlayingInfo->uniqueIdentifier.toUInt64(), ", registered = ", m_registeredAsNowPlayingApplication, ", src = "" nowPlayingInfo->artwork ? nowPlayingInfo->artwork->src : String(), "\"");
+
+ if (!m_registeredAsNowPlayingApplication) {
+ m_registeredAsNowPlayingApplication = true;
+ providePresentingApplicationPIDIfNecessary();
+ }
+
+ if (!nowPlayingInfo->title.isEmpty())
+ m_lastUpdatedNowPlayingTitle = nowPlayingInfo->title;
+
+ double duration = nowPlayingInfo->duration;
+ if (std::isfinite(duration) && duration != MediaPlayer::invalidTime())
+ m_lastUpdatedNowPlayingDuration = duration;
+
+ m_lastUpdatedNowPlayingInfoUniqueIdentifier = nowPlayingInfo->uniqueIdentifier;
+
+ double currentTime = nowPlayingInfo->currentTime;
+ if (std::isfinite(currentTime) && currentTime != MediaPlayer::invalidTime() && nowPlayingInfo->supportsSeeking)
+ m_lastUpdatedNowPlayingElapsedTime = currentTime;
+
+ m_nowPlayingActive = nowPlayingInfo->allowsNowPlayingControlsVisibility;
+
+ GVariantBuilder builder;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(&builder, "{sv}", "mpris:trackid", g_variant_new("o", DBUS_MPRIS_TRACK_PATH));
+ g_variant_builder_add(&builder, "{sv}", "mpris:length", g_variant_new_int64(nowPlayingInfo->duration * 1000000));
+ g_variant_builder_add(&builder, "{sv}", "xesam:title", g_variant_new_string(nowPlayingInfo->title.utf8().data()));
+ g_variant_builder_add(&builder, "{sv}", "xesam:album", g_variant_new_string(nowPlayingInfo->album.utf8().data()));
+ if (nowPlayingInfo->artwork)
+ g_variant_builder_add(&builder, "{sv}", "mpris:artUrl", g_variant_new_string(nowPlayingInfo->artwork->src.utf8().data()));
+
+ GVariantBuilder artistBuilder;
+ g_variant_builder_init(&artistBuilder, G_VARIANT_TYPE("as"));
+ g_variant_builder_add(&artistBuilder, "s", nowPlayingInfo->artist.utf8().data());
+ g_variant_builder_add(&builder, "{sv}", "xesam:artist", g_variant_builder_end(&artistBuilder));
+
+ m_nowPlayingInfo = g_variant_builder_end(&builder);
+
+ GVariantBuilder propertiesBuilder;
+ g_variant_builder_init(&propertiesBuilder, G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(&propertiesBuilder, "{sv}", "Metadata", m_nowPlayingInfo.get());
+ emitPropertiesChanged(g_variant_new("(sa{sv}as)", DBUS_MPRIS_PLAYER_INTERFACE, &propertiesBuilder, nullptr));
+ g_variant_builder_clear(&propertiesBuilder);
+}
+
+GVariant* MediaSessionManagerGLib::getPlaybackStatusAsGVariant(std::optional<const PlatformMediaSession*> session)
+{
+ auto state = [this, session = WTFMove(session)]() -> PlatformMediaSession::State {
+ if (session)
+ return session.value()->state();
+
+ auto* nowPlayingSession = nowPlayingEligibleSession();
+ if (nowPlayingSession)
+ return nowPlayingSession->state();
+
+ return PlatformMediaSession::State::Idle;
+ }();
+
+ switch (state) {
+ case PlatformMediaSession::State::Autoplaying:
+ case PlatformMediaSession::State::Playing:
+ return g_variant_new_string("Playing");
+ case PlatformMediaSession::State::Paused:
+ return g_variant_new_string("Paused");
+ case PlatformMediaSession::State::Idle:
+ case PlatformMediaSession::State::Interrupted:
+ return g_variant_new_string("Stopped");
+ }
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+GVariant* MediaSessionManagerGLib::getActiveSessionPosition()
+{
+ auto* session = nowPlayingEligibleSession();
+ return g_variant_new_int64(session ? session->nowPlayingInfo()->currentTime * 1000000 : 0);
+}
+
+void MediaSessionManagerGLib::dispatch(PlatformMediaSession::RemoteControlCommandType platformCommand, PlatformMediaSession::RemoteCommandArgument argument)
+{
+ m_isSeeking = platformCommand == PlatformMediaSession::SeekToPlaybackPositionCommand;
+ m_nowPlayingManager->didReceiveRemoteControlCommand(platformCommand, argument);
+}
+
+void MediaSessionManagerGLib::emitPropertiesChanged(GVariant* parameters)
+{
+ if (!m_connection)
+ return;
+
+ GUniqueOutPtr<GError> error;
+ if (!g_dbus_connection_emit_signal(m_connection.get(), nullptr, DBUS_MPRIS_OBJECT_PATH, "org.freedesktop.DBus.Properties", "PropertiesChanged", parameters, &error.outPtr()))
+ g_warning("Failed to emit MPRIS properties changed: %s", error->message);
+}
+
+} // namespace WebCore
+
+#endif // USE(GLIB)
Added: trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.h (0 => 282307)
--- trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.h (rev 0)
+++ trunk/Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.h 2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2021 Igalia S.L
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+#if USE(GLIB)
+
+#include "NowPlayingManager.h"
+#include "PlatformMediaSessionManager.h"
+#include <wtf/glib/GRefPtr.h>
+
+namespace WebCore {
+
+struct NowPlayingInfo;
+
+class MediaSessionManagerGLib
+ : public PlatformMediaSessionManager
+ , private NowPlayingManager::Client {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ MediaSessionManagerGLib();
+ ~MediaSessionManagerGLib();
+
+ bool setupMpris();
+
+ void beginInterruption(PlatformMediaSession::InterruptionType) final;
+
+ bool hasActiveNowPlayingSession() const final { return m_nowPlayingActive; }
+ String lastUpdatedNowPlayingTitle() const final { return m_lastUpdatedNowPlayingTitle; }
+ double lastUpdatedNowPlayingDuration() const final { return m_lastUpdatedNowPlayingDuration; }
+ double lastUpdatedNowPlayingElapsedTime() const final { return m_lastUpdatedNowPlayingElapsedTime; }
+ MediaUniqueIdentifier lastUpdatedNowPlayingInfoUniqueIdentifier() const final { return m_lastUpdatedNowPlayingInfoUniqueIdentifier; }
+ bool registeredAsNowPlayingApplication() const final { return m_registeredAsNowPlayingApplication; }
+ bool haveEverRegisteredAsNowPlayingApplication() const final { return m_haveEverRegisteredAsNowPlayingApplication; }
+
+ void busAcquired(GDBusConnection*);
+ void nameAcquired(GDBusConnection* connection) { m_connection = connection; }
+ void nameLost(GDBusConnection*);
+ GVariant* getMetadataAsGVariant() const { return m_nowPlayingInfo.get(); }
+ GVariant* getPlaybackStatusAsGVariant(std::optional<const PlatformMediaSession*>);
+ GVariant* getActiveSessionPosition();
+ void dispatch(PlatformMediaSession::RemoteControlCommandType, PlatformMediaSession::RemoteCommandArgument);
+
+protected:
+ void scheduleSessionStatusUpdate() final;
+ void updateNowPlayingInfo();
+
+ void removeSession(PlatformMediaSession&) final;
+ void addSession(PlatformMediaSession&) final;
+ void setCurrentSession(PlatformMediaSession&) final;
+
+ bool sessionWillBeginPlayback(PlatformMediaSession&) override;
+ void sessionWillEndPlayback(PlatformMediaSession&, DelayCallingUpdateNowPlaying) override;
+ void sessionStateChanged(PlatformMediaSession&) override;
+ void sessionDidEndRemoteScrubbing(PlatformMediaSession&) final;
+ void clientCharacteristicsChanged(PlatformMediaSession&) final;
+ void sessionCanProduceAudioChanged() final;
+
+ virtual void providePresentingApplicationPIDIfNecessary() { }
+
+ PlatformMediaSession* nowPlayingEligibleSession();
+
+ void addSupportedCommand(PlatformMediaSession::RemoteControlCommandType) final;
+ void removeSupportedCommand(PlatformMediaSession::RemoteControlCommandType) final;
+ RemoteCommandListener::RemoteCommandsSet supportedCommands() const final;
+
+ void resetHaveEverRegisteredAsNowPlayingApplicationForTesting() final { m_haveEverRegisteredAsNowPlayingApplication = false; };
+
+private:
+ void emitPropertiesChanged(GVariant*);
+
+#if !RELEASE_LOG_DISABLED
+ const char* logClassName() const override { return "MediaSessionManagerGLib"; }
+#endif
+
+ // NowPlayingManager::Client
+ void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType type, const PlatformMediaSession::RemoteCommandArgument& argument) final { processDidReceiveRemoteControlCommand(type, argument); }
+
+ String m_instanceId;
+ unsigned m_ownerId { 0 };
+ unsigned m_rootRegistrationId { 0 };
+ unsigned m_playerRegistrationId { 0 };
+ bool m_isSeeking { false };
+ GRefPtr<GDBusConnection> m_connection;
+ GRefPtr<GDBusNodeInfo> m_mprisInterface;
+ GRefPtr<GVariant> m_nowPlayingInfo;
+
+ bool m_nowPlayingActive { false };
+ bool m_registeredAsNowPlayingApplication { false };
+ bool m_haveEverRegisteredAsNowPlayingApplication { false };
+
+ // For testing purposes only.
+ String m_lastUpdatedNowPlayingTitle;
+ double m_lastUpdatedNowPlayingDuration { NAN };
+ double m_lastUpdatedNowPlayingElapsedTime { NAN };
+ MediaUniqueIdentifier m_lastUpdatedNowPlayingInfoUniqueIdentifier;
+
+ const std::unique_ptr<NowPlayingManager> m_nowPlayingManager;
+};
+
+} // namespace WebCore
+
+#endif // USE(GLIB)
Added: trunk/Source/WebCore/platform/glib/ApplicationGLib.cpp (0 => 282307)
--- trunk/Source/WebCore/platform/glib/ApplicationGLib.cpp (rev 0)
+++ trunk/Source/WebCore/platform/glib/ApplicationGLib.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "ApplicationGLib.h"
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static String gApplicationName;
+static String gApplicationID;
+
+void setApplicationName(const String& applicationName)
+{
+ gApplicationName = applicationName;
+}
+
+const char* getApplicationName()
+{
+ if (!gApplicationName.isEmpty())
+ return gApplicationName.ascii().data();
+ return "WebKit";
+}
+
+void setApplicationID(const String& applicationID)
+{
+ gApplicationID = applicationID;
+}
+
+const String& getApplicationID()
+{
+ return gApplicationID;
+}
+
+} // namespace WebCore
Added: trunk/Source/WebCore/platform/glib/ApplicationGLib.h (0 => 282307)
--- trunk/Source/WebCore/platform/glib/ApplicationGLib.h (rev 0)
+++ trunk/Source/WebCore/platform/glib/ApplicationGLib.h 2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+#if USE(GLIB)
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+WEBCORE_EXPORT void setApplicationName(const String&);
+WEBCORE_EXPORT const char* getApplicationName();
+
+WEBCORE_EXPORT void setApplicationID(const String&);
+WEBCORE_EXPORT const String& getApplicationID();
+
+} // namespace WebCore
+
+#endif // USE(GLIB)
Added: trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.cpp (0 => 282307)
--- trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.cpp (rev 0)
+++ trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "RemoteCommandListenerGLib.h"
+
+#if USE(GLIB)
+
+namespace WebCore {
+
+std::unique_ptr<RemoteCommandListenerGLib> RemoteCommandListenerGLib::create(RemoteCommandListenerClient& client)
+{
+ return makeUnique<RemoteCommandListenerGLib>(client);
+}
+
+void RemoteCommandListenerGLib::updateSupportedCommands()
+{
+ // Remote commands are handled as user-triggered MPRIS actions in MediaSessionManagerGLib.
+}
+
+RemoteCommandListenerGLib::RemoteCommandListenerGLib(RemoteCommandListenerClient& client)
+ : RemoteCommandListener(client)
+{
+}
+
+RemoteCommandListenerGLib::~RemoteCommandListenerGLib() = default;
+
+}
+
+#endif
Added: trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.h (0 => 282307)
--- trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.h (rev 0)
+++ trunk/Source/WebCore/platform/glib/RemoteCommandListenerGLib.h 2021-09-11 11:34:42 UTC (rev 282307)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+
+#include "RemoteCommandListener.h"
+
+#if USE(GLIB)
+
+namespace WebCore {
+
+class RemoteCommandListenerGLib : public RemoteCommandListener {
+public:
+ static std::unique_ptr<RemoteCommandListenerGLib> create(RemoteCommandListenerClient&);
+ explicit RemoteCommandListenerGLib(RemoteCommandListenerClient&);
+ virtual ~RemoteCommandListenerGLib();
+
+private:
+ void updateSupportedCommands() final;
+
+ const RemoteCommandsSet& defaultCommands();
+};
+
+}
+
+#endif // USE(GLIB)
Modified: trunk/Source/WebCore/platform/graphics/ImageFrame.h (282306 => 282307)
--- trunk/Source/WebCore/platform/graphics/ImageFrame.h 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/graphics/ImageFrame.h 2021-09-11 11:34:42 UTC (rev 282307)
@@ -33,6 +33,12 @@
#include "NativeImage.h"
#include <wtf/Seconds.h>
+// X11 headers define a bunch of macros with common terms, interfering with WebCore and WTF enum values.
+// As a workaround, we explicitly undef them here.
+#if defined(None)
+#undef None
+#endif
+
namespace WebCore {
class ImageFrame {
Modified: trunk/Source/WebCore/platform/graphics/ImageOrientation.h (282306 => 282307)
--- trunk/Source/WebCore/platform/graphics/ImageOrientation.h 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebCore/platform/graphics/ImageOrientation.h 2021-09-11 11:34:42 UTC (rev 282307)
@@ -30,6 +30,12 @@
#include "FloatSize.h"
#include <wtf/EnumTraits.h>
+// X11 headers define a bunch of macros with common terms, interfering with WebCore and WTF enum values.
+// As a workaround, we explicitly undef them here.
+#if defined(None)
+#undef None
+#endif
+
namespace WebCore {
struct ImageOrientation {
Modified: trunk/Source/WebKit/ChangeLog (282306 => 282307)
--- trunk/Source/WebKit/ChangeLog 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/ChangeLog 2021-09-11 11:34:42 UTC (rev 282307)
@@ -1,3 +1,30 @@
+2021-09-11 Philippe Normand <[email protected]>
+
+ [GLIB] MediaSession is not enabled
+ https://bugs.webkit.org/show_bug.cgi?id=217991
+ <rdar://problem/70740119>
+
+ Reviewed by Michael Catanzaro.
+
+ Pass Application name and unique ID from the UIProcess to the WebProcess in WPE and GTK
+ ports. The Bubblewrap launcher was also adapted to allow DBus MPRIS name ownership in the
+ sandboxed WebProcess.
+
+ * Shared/WebProcessCreationParameters.cpp:
+ (WebKit::WebProcessCreationParameters::encode const):
+ (WebKit::WebProcessCreationParameters::decode):
+ * Shared/WebProcessCreationParameters.h:
+ * UIProcess/API/glib/WebKitSettings.cpp:
+ (webKitSettingsConstructed):
+ * UIProcess/Launcher/glib/BubblewrapLauncher.cpp:
+ (WebKit::applicationId):
+ (WebKit::createFlatpakInfo):
+ (WebKit::XDGDBusProxyLauncher::launch):
+ * UIProcess/glib/WebProcessPoolGLib.cpp:
+ (WebKit::WebProcessPool::platformInitializeWebProcess):
+ * WebProcess/glib/WebProcessGLib.cpp:
+ (WebKit::WebProcess::platformInitializeWebProcess):
+
2021-09-10 Chris Dumez <[email protected]>
Implement navigation reporting for Cross-Origin-Opener-Policy
Modified: trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp (282306 => 282307)
--- trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -214,6 +214,10 @@
#if PLATFORM(GTK) || PLATFORM(WPE)
encoder << memoryPressureHandlerConfiguration;
#endif
+#if USE(GLIB)
+ encoder << applicationID;
+ encoder << applicationName;
+#endif
}
bool WebProcessCreationParameters::decode(IPC::Decoder& decoder, WebProcessCreationParameters& parameters)
@@ -587,6 +591,13 @@
parameters.memoryPressureHandlerConfiguration = WTFMove(*memoryPressureHandlerConfiguration);
#endif
+#if USE(GLIB)
+ if (!decoder.decode(parameters.applicationID))
+ return false;
+ if (!decoder.decode(parameters.applicationName))
+ return false;
+#endif
+
return true;
}
Modified: trunk/Source/WebKit/Shared/WebProcessCreationParameters.h (282306 => 282307)
--- trunk/Source/WebKit/Shared/WebProcessCreationParameters.h 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/Shared/WebProcessCreationParameters.h 2021-09-11 11:34:42 UTC (rev 282307)
@@ -260,6 +260,11 @@
#if PLATFORM(GTK) || PLATFORM(WPE)
std::optional<MemoryPressureHandler::Configuration> memoryPressureHandlerConfiguration;
#endif
+
+#if USE(GLIB)
+ String applicationID;
+ String applicationName;
+#endif
};
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp (282306 => 282307)
--- trunk/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitSettings.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -196,6 +196,13 @@
prefs->setPeerConnectionEnabled(true);
#endif
#endif
+
+ // FIXME: Expose API for this when this feature is officially non-experimental.
+#if ENABLE(MEDIA_SESSION)
+ prefs->setMediaSessionEnabled(true);
+ prefs->setMediaSessionCoordinatorEnabled(true);
+ prefs->setMediaSessionPlaylistEnabled(true);
+#endif
}
static void webKitSettingsSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
Modified: trunk/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp (282306 => 282307)
--- trunk/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/UIProcess/Launcher/glib/BubblewrapLauncher.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -130,6 +130,22 @@
return memfd;
}
+static const char* applicationId(GError** error)
+{
+ GApplication* app = g_application_get_default();
+ if (!app) {
+ g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "GApplication is required.");
+ return nullptr;
+ }
+
+ const char* appID = g_application_get_application_id(app);
+ if (!appID) {
+ g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "GApplication must have a valid ID.");
+ return nullptr;
+ }
+ return appID;
+}
+
static int createFlatpakInfo()
{
static NeverDestroyed<GUniquePtr<char>> data;
@@ -138,13 +154,10 @@
if (!data.get()) {
// xdg-desktop-portal relates your name to certain permissions so we want
// them to be application unique which is best done via GApplication.
- GApplication* app = g_application_get_default();
- if (!app)
- g_error("GApplication is required for xdg-desktop-portal access in the WebKit sandbox.");
-
- const char* appID = g_application_get_application_id(app);
+ GUniqueOutPtr<GError> error;
+ const char* appID = applicationId(&error.outPtr());
if (!appID)
- g_error("GApplication must have a valid ID for xdg-desktop-portal access in the WebKit sandbox.");
+ g_error("Unable to configure xdg-desktop-portal access in the WebKit sandbox: %s", error->message);
GUniquePtr<GKeyFile> keyFile(g_key_file_new());
g_key_file_set_string(keyFile.get(), "Application", "name", appID);
@@ -207,6 +220,16 @@
if (enableLogging)
proxyArgs.append("--log");
+ GUniqueOutPtr<GError> error;
+#if ENABLE(MEDIA_SESSION)
+ const char* appID = applicationId(&error.outPtr());
+ if (!appID)
+ g_warning("Unable to own D-Bus MPRIS name in the WebKit sandbox: %s", error->message);
+
+ auto mprisSessionID = makeString("--own=org.mpris.MediaPlayer2.", appID);
+ proxyArgs.append(mprisSessionID.ascii().data());
+#endif
+
proxyArgs.appendVector(m_permissions);
int proxyFd = argsToFd(proxyArgs, "dbus-proxy");
@@ -236,7 +259,6 @@
ProcessLauncher::LaunchOptions launchOptions;
launchOptions.processType = ProcessLauncher::ProcessType::DBusProxy;
- GUniqueOutPtr<GError> error;
GRefPtr<GSubprocess> process = bubblewrapSpawn(launcher.get(), launchOptions, argv, &error.outPtr());
if (!process.get())
g_error("Failed to start dbus proxy: %s", error->message);
Modified: trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp (282306 => 282307)
--- trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -109,6 +109,11 @@
#endif
parameters.memoryPressureHandlerConfiguration = m_configuration->memoryPressureHandlerConfiguration();
+
+ GApplication* app = g_application_get_default();
+ if (app)
+ parameters.applicationID = g_application_get_application_id(app);
+ parameters.applicationName = g_get_application_name();
}
void WebProcessPool::platformInvalidateContext()
Modified: trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp (282306 => 282307)
--- trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp 2021-09-11 11:34:42 UTC (rev 282307)
@@ -35,6 +35,7 @@
#include <WebCore/GStreamerCommon.h>
#endif
+#include <WebCore/ApplicationGLib.h>
#include <WebCore/MemoryCache.h>
#if PLATFORM(WAYLAND)
@@ -108,6 +109,12 @@
if (parameters.memoryPressureHandlerConfiguration)
MemoryPressureHandler::singleton().setConfiguration(WTFMove(*parameters.memoryPressureHandlerConfiguration));
+
+ if (!parameters.applicationID.isEmpty())
+ WebCore::setApplicationID(parameters.applicationID);
+
+ if (!parameters.applicationName.isEmpty())
+ WebCore::setApplicationName(parameters.applicationName);
}
void WebProcess::platformSetWebsiteDataStoreParameters(WebProcessDataStoreParameters&&)
Modified: trunk/Source/cmake/OptionsGTK.cmake (282306 => 282307)
--- trunk/Source/cmake/OptionsGTK.cmake 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/cmake/OptionsGTK.cmake 2021-09-11 11:34:42 UTC (rev 282307)
@@ -153,6 +153,8 @@
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_TIME PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_WEEK PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYOUT_FORMATTING_CONTEXT PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION_PLAYLIST PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MOUSE_CURSOR_SCALE PRIVATE ON)
Modified: trunk/Source/cmake/OptionsWPE.cmake (282306 => 282307)
--- trunk/Source/cmake/OptionsWPE.cmake 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/cmake/OptionsWPE.cmake 2021-09-11 11:34:42 UTC (rev 282307)
@@ -51,6 +51,8 @@
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FILTERS_LEVEL_2 PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GPU_PROCESS PRIVATE OFF)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYOUT_FORMATTING_CONTEXT PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION_PLAYLIST PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
Modified: trunk/Source/cmake/WebKitFeatures.cmake (282306 => 282307)
--- trunk/Source/cmake/WebKitFeatures.cmake 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Source/cmake/WebKitFeatures.cmake 2021-09-11 11:34:42 UTC (rev 282307)
@@ -169,6 +169,9 @@
WEBKIT_OPTION_DEFINE(ENABLE_MATHML "Toggle MathML support" PRIVATE ON)
WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_CAPTURE "Toggle Media Capture support" PRIVATE OFF)
WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_CONTROLS_SCRIPT "Toggle definition of media controls in _javascript_" PRIVATE ON)
+ WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_SESSION "Toggle Media Session support" PRIVATE OFF)
+ WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_SESSION_COORDINATOR "Toggle Media Session Coordinator support" PRIVATE OFF)
+ WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_SESSION_PLAYLIST "Toggle Media Session Playlist support" PRIVATE OFF)
WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_SOURCE "Toggle Media Source support" PRIVATE OFF)
WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_STATISTICS "Toggle Media Statistics support" PRIVATE OFF)
WEBKIT_OPTION_DEFINE(ENABLE_MEDIA_STREAM "Toggle Media Stream support" PRIVATE OFF)
Modified: trunk/Tools/Scripts/webkitpy/style/checker.py (282306 => 282307)
--- trunk/Tools/Scripts/webkitpy/style/checker.py 2021-09-11 04:24:18 UTC (rev 282306)
+++ trunk/Tools/Scripts/webkitpy/style/checker.py 2021-09-11 11:34:42 UTC (rev 282307)
@@ -181,6 +181,11 @@
["-readability/enum_casing"]),
([
+ # Forward declarations of GLib/GIO functions use underscores.
+ os.path.join('Source', 'WTF', 'wtf', 'glib', 'GRefPtr.h')],
+ ["-readability/naming/underscores"]),
+
+ ([
# To use GStreamer GL without conflicts of GL symbols,
# we should include gst/gl/gl.h before including OpenGL[ES]Shims
os.path.join('Source', 'WebCore', 'platform', 'graphics', 'gstreamer', 'MediaPlayerPrivateGStreamer.cpp')],