From b0bbc80821c8429ba36a17197f2f58440acb8fe0 Mon Sep 17 00:00:00 2001 From: Coroiu Cristina <ccoroiu@mozilla.com> Date: Wed, 12 Feb 2020 12:13:03 +0200 Subject: [PATCH] Backed out changeset b4dc366c9161 (bug 1353652) for build bustage on linux32 at build/src/widget/gtk/MPRISServiceHandler.cpp a=backout --- .clang-format-ignore | 3 - widget/gtk/MPRISInterfaceDescription.h | 115 ---- widget/gtk/MPRISServiceHandler.cpp | 648 --------------------- widget/gtk/MPRISServiceHandler.h | 162 ------ widget/gtk/MediaKeysEventSourceFactory.cpp | 4 +- widget/gtk/moz.build | 1 - 6 files changed, 2 insertions(+), 931 deletions(-) delete mode 100644 widget/gtk/MPRISInterfaceDescription.h delete mode 100644 widget/gtk/MPRISServiceHandler.cpp delete mode 100644 widget/gtk/MPRISServiceHandler.h diff --git a/.clang-format-ignore b/.clang-format-ignore index e11ac133ced57..2ead0193e7195 100644 --- a/.clang-format-ignore +++ b/.clang-format-ignore @@ -59,9 +59,6 @@ tools/clang-tidy/test/.* # We are testing the incorrect formatting. tools/lint/test/files/file-whitespace/ -# Contains an XML definition and formatting would break the layout -widget/gtk/MPRISInterfaceDescription.h - # The XPTCall stubs files have some inline assembly macros # that get reformatted badly. See bug 1510781. xpcom/reflect/xptcall/md/win32/.* diff --git a/widget/gtk/MPRISInterfaceDescription.h b/widget/gtk/MPRISInterfaceDescription.h deleted file mode 100644 index 9ff4393237e45..0000000000000 --- a/widget/gtk/MPRISInterfaceDescription.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef WIDGET_GTK_MPRIS_INTERFACE_DESCRIPTION_H_ -#define WIDGET_GTK_MPRIS_INTERFACE_DESCRIPTION_H_ - -#include <gio/gio.h> - -extern const gchar introspection_xml[] = - // adopted from https://github.com/freedesktop/mpris-spec/blob/master/spec/org.mpris.MediaPlayer2.xml - // everything starting with tp can be removed, as it is used for HTML Spec Documentation Generation - "<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\"/>" - #ifdef MPRIS_FULLSCREEN - "<property name=\"Fullscreen\" type=\"b\" access=\"readwrite\">" - "<annotation name=\"org.mpris.MediaPlayer2.property.optional\" value=\"true\"/>" - "</property>" - "<property name=\"CanSetFullscreen\" type=\"b\" access=\"read\">" - "<annotation name=\"org.mpris.MediaPlayer2.property.optional\" value=\"true\"/>" - "</property>" - #endif - "<property name=\"CanRaise\" type=\"b\" access=\"read\"/>" - "<property name=\"HasTrackList\" type=\"b\" access=\"read\"/>" - "<property name=\"Identity\" type=\"s\" access=\"read\"/>" - #ifdef MPRIS_DESKTOP_ENTRY - "<property name=\"DesktopEntry\" type=\"s\" access=\"read\">" - "<annotation name=\"org.mpris.MediaPlayer2.property.optional\" value=\"true\"/>" - "</property>" - #endif - "<property name=\"SupportedUriSchemes\" type=\"as\" access=\"read\"/>" - "<property name=\"SupportedMimeTypes\" type=\"as\" access=\"read\"/>" - "</interface>" - // Note that every property emits a changed signal (which is default) apart from Position. - "<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>" - #ifdef MPRIS_LOOP_STATUS - "<property name=\"LoopStatus\" type=\"s\" access=\"readwrite\">" - "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>" - "<annotation name=\"org.mpris.MediaPlayer2.property.optional\" value=\"true\"/>" - "</property>" - #endif - "<property name=\"Rate\" type=\"d\" access=\"readwrite\">" - "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>" - "</property>" - #ifdef MRPIS_SHUFFLE - "<property name=\"Shuffle\" type=\"b\" access=\"readwrite\">" - "<annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"true\"/>" - "<annotation name=\"org.mpris.MediaPlayer2.property.optional\" value=\"true\"/>" - "</property>" - #endif - "<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>"; - -#endif // WIDGET_GTK_MPRIS_INTERFACE_DESCRIPTION_H_ diff --git a/widget/gtk/MPRISServiceHandler.cpp b/widget/gtk/MPRISServiceHandler.cpp deleted file mode 100644 index 198f8b6b2818d..0000000000000 --- a/widget/gtk/MPRISServiceHandler.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "MPRISServiceHandler.h" - -#include <unordered_map> - -#include "MPRISInterfaceDescription.h" -#include "mozilla/dom/MediaControlUtils.h" -#include "mozilla/Maybe.h" -#include "mozilla/Sprintf.h" - -// avoid redefined macro in unified build -#undef LOG -#define LOG(msg, ...) \ - MOZ_LOG(gMediaControlLog, LogLevel::Debug, \ - ("MPRISServiceHandler=%p, " msg, this, ##__VA_ARGS__)) - -namespace mozilla { -namespace widget { - -enum class Method : uint8_t { - eQuit, - eRaise, - eNext, - ePrevious, - ePause, - ePlayPause, - eStop, - ePlay, - eSeek, - eSetPosition, - eOpenUri, - eUnknown -}; - -static inline Method GetMethod(const gchar* aMethodName) { - const std::unordered_map<std::string, Method> map = { - {"Quit", Method::eQuit}, {"Raise", Method::eRaise}, - {"Next", Method::eNext}, {"Previous", Method::ePrevious}, - {"Pause", Method::ePause}, {"PlayPause", Method::ePlayPause}, - {"Stop", Method::eStop}, {"Play", Method::ePlay}, - {"Seek", Method::eSeek}, {"SetPosition", Method::eSetPosition}, - {"OpenUri", Method::eOpenUri}}; - - auto it = map.find(aMethodName); - return (it == map.end() ? Method::eUnknown : it->second); -} - -static void HandleMethodCall(GDBusConnection* aConnection, const gchar* aSender, - const gchar* aObjectPath, - const gchar* aInterfaceName, - const gchar* aMethodName, GVariant* aParameters, - GDBusMethodInvocation* aInvocation, - gpointer aUserData) { - MOZ_ASSERT(aUserData); - MOZ_ASSERT(NS_IsMainThread()); - MPRISServiceHandler* handler = static_cast<MPRISServiceHandler*>(aUserData); - std::string error; - - switch (GetMethod(aMethodName)) { - case Method::eUnknown: - g_dbus_method_invocation_return_error( - aInvocation, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid Method"); - return; - case Method::eQuit: - if (handler->CanQuit()) { - handler->Quit(); - } else { - error = "Cannot invoke Quit() when CanQuit() returns false"; - } - break; - case Method::eRaise: - if (handler->CanRaise()) { - handler->Raise(); - } else { - error = "Cannot invoke Raise() when CanRaise() returns false"; - } - break; - case Method::eNext: - if (handler->CanGoNext()) { - handler->Next(); - } else { - error = "Cannot invoke Next() when CanGoNext() returns false"; - } - break; - case Method::ePrevious: - if (handler->CanGoPrevious()) { - handler->Previous(); - } else { - error = "Cannot invoke Previous() when CanGoPrevious() returns false"; - } - break; - case Method::ePause: - if (handler->CanPause()) { - handler->Pause(); - } else { - error = "Cannot invoke Pause() when CanPause() returns false"; - } - break; - case Method::ePlayPause: - // According to Spec this should only fail if canPause is false, but Play - // may be forbidden due to CanPlay. This means in theory even though - // CanPlay is false, this method would be able to Play something which - // means when CanPause is false, CanPlay _has to be_ false as well. - if (handler->CanPlay() && handler->CanPause()) { - handler->PlayPause(); - } else { - error = - "Cannot invoke PlayPause() when either CanPlay() or CanPause() " - "returns false"; - } - break; - case Method::eStop: - handler->Stop(); // Stop is mandatory - break; - case Method::ePlay: - if (handler->CanPlay()) { - handler->Play(); - } else { - error = "Cannot invoke Play() when CanPlay() returns false"; - } - break; - case Method::eSeek: - if (handler->CanSeek()) { - gint64 position; - g_variant_get(aParameters, "(x)", &position); - handler->Seek(position); - } else { - error = "Cannot invoke Seek() when CanSeek() returns false"; - } - break; - case Method::eSetPosition: - if (handler->CanSeek()) { - gchar* trackId; - gint64 position; - g_variant_get(aParameters, "(ox)", &trackId, &position); - handler->SetPosition(trackId, position); - } else { - error = "Cannot invoke SetPosition() when CanSeek() returns false"; - } - break; - case Method::eOpenUri: - gchar* uri; - g_variant_get(aParameters, "(s)", &uri); - if (!handler->OpenUri(uri)) { - error = "Could not open URI"; - } - break; - } - - if (!error.empty()) { - g_dbus_method_invocation_return_error( - aInvocation, G_IO_ERROR, G_IO_ERROR_READ_ONLY, "%s", error.c_str()); - } -} - -enum class Property : uint8_t { - eIdentity, - eHasTrackList, - eCanRaise, - eCanQuit, - eSupportedUriSchemes, - eSupportedMimeTypes, - eCanGoNext, - eCanGoPrevious, - eCanPlay, - eCanPause, - eCanSeek, - eCanControl, - eGetVolume, - eGetPosition, - eGetMinimumRate, - eGetMaximumRate, - eGetRate, - eGetPlaybackStatus, - eGetMetadata, - eUnknown -}; - -static inline Property GetProperty(const gchar* aPropertyName) { - const std::unordered_map<std::string, Property> map = { - {"Identity", Property::eIdentity}, - {"HasTrackList", Property::eHasTrackList}, - {"CanRaise", Property::eCanRaise}, - {"CanQuit", Property::eCanQuit}, - {"SupportedUriSchemes", Property::eSupportedUriSchemes}, - {"SupportedMimeTypes", Property::eSupportedMimeTypes}, - {"CanGoNext", Property::eCanGoNext}, - {"CanGoPrevious", Property::eCanGoPrevious}, - {"CanPlay", Property::eCanPlay}, - {"CanPause", Property::eCanPause}, - {"CanSeek", Property::eCanSeek}, - {"CanControl", Property::eCanControl}, - {"Volume", Property::eGetVolume}, - {"Position", Property::eGetPosition}, - {"MinimumRate", Property::eGetMinimumRate}, - {"MaximumRate", Property::eGetMaximumRate}, - {"Rate", Property::eGetRate}, - {"PlaybackStatus", Property::eGetPlaybackStatus}, - {"Metadata", Property::eGetMetadata}}; - - auto it = map.find(aPropertyName); - return (it == map.end() ? Property::eUnknown : it->second); -} - -static GVariant* HandleGetProperty(GDBusConnection* aConnection, - const gchar* aSender, - const gchar* aObjectPath, - const gchar* aInterfaceName, - const gchar* aPropertyName, GError** aError, - gpointer aUserData) { - MOZ_ASSERT(aUserData); - MOZ_ASSERT(NS_IsMainThread()); - MPRISServiceHandler* handler = static_cast<MPRISServiceHandler*>(aUserData); - - switch (GetProperty(aPropertyName)) { - case Property::eUnknown: - g_set_error(aError, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown Property"); - return nullptr; - case Property::eIdentity: - return g_variant_new_string(handler->Identity()); - case Property::eHasTrackList: - return g_variant_new_boolean(handler->HasTrackList()); - case Property::eCanRaise: - return g_variant_new_boolean(handler->CanRaise()); - case Property::eCanQuit: - return g_variant_new_boolean(handler->CanQuit()); - case Property::eSupportedUriSchemes: - return handler->SupportedUriSchemes(); - case Property::eSupportedMimeTypes: - return handler->SupportedMimeTypes(); - case Property::eCanGoNext: - return g_variant_new_boolean(handler->CanGoNext()); - case Property::eCanGoPrevious: - return g_variant_new_boolean(handler->CanGoPrevious()); - case Property::eCanPlay: - return g_variant_new_boolean(handler->CanPlay()); - case Property::eCanPause: - return g_variant_new_boolean(handler->CanPause()); - case Property::eCanSeek: - return g_variant_new_boolean(handler->CanSeek()); - case Property::eCanControl: - return g_variant_new_boolean(handler->CanControl()); - case Property::eGetVolume: - return g_variant_new_double(handler->GetVolume()); - case Property::eGetPosition: - return g_variant_new_int64(handler->GetPosition()); - case Property::eGetMinimumRate: - return g_variant_new_double(handler->GetMinimumRate()); - case Property::eGetMaximumRate: - return g_variant_new_double(handler->GetMaximumRate()); - case Property::eGetRate: - return g_variant_new_double(handler->GetRate()); - case Property::eGetPlaybackStatus: - if (GVariant* state = handler->GetPlaybackStatus()) { - return state; - } - g_set_error(aError, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid Playback Status"); - return nullptr; - case Property::eGetMetadata: - std::vector<struct MPRISMetadata> list = handler->GetDefaultMetadata(); - GVariantBuilder builder; - g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); - for (auto const& data : list) { - g_variant_builder_add(&builder, "{sv}", data.mKey, data.mValue); - } - return g_variant_builder_end(&builder); - } - - MOZ_ASSERT_UNREACHABLE("Switch Statement incomplete"); - return nullptr; -} - -static gboolean HandleSetProperty(GDBusConnection* aConnection, - const gchar* aSender, - const gchar* aObjectPath, - const gchar* aInterfaceName, - const gchar* aPropertyName, GVariant* aValue, - GError** aError, gpointer aUserData) { - MOZ_ASSERT(aUserData); - MOZ_ASSERT(NS_IsMainThread()); - MPRISServiceHandler* handler = static_cast<MPRISServiceHandler*>(aUserData); - - if (g_strcmp0(aPropertyName, "Volume") == 0) { - if (!handler->SetVolume(g_variant_get_double(aValue))) { - g_set_error(aError, G_IO_ERROR, G_IO_ERROR_FAILED, - "Could not set the Volume"); - return false; - } - } else if (g_strcmp0(aPropertyName, "Rate") == 0) { - if (!handler->SetRate(g_variant_get_double(aValue))) { - g_set_error(aError, G_IO_ERROR, G_IO_ERROR_FAILED, - "Could not set the Rate"); - return false; - } - } else { - g_set_error(aError, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown Property"); - return false; - } - - GVariantBuilder - propertiesBuilder; // a builder for the list of changed properties - g_variant_builder_init(&propertiesBuilder, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add(&propertiesBuilder, "{sv}", aPropertyName, aValue); - - return g_dbus_connection_emit_signal( - aConnection, nullptr, aObjectPath, "org.freedesktop.DBus.Properties", - "PropertiesChanged", - g_variant_new("(sa{sv}as)", aInterfaceName, &propertiesBuilder, nullptr), - aError); -} - -static const GDBusInterfaceVTable gInterfaceVTable = { - HandleMethodCall, HandleGetProperty, HandleSetProperty}; - -void MPRISServiceHandler::OnNameAcquiredStatic(GDBusConnection* aConnection, - const gchar* aName, - gpointer aUserData) { - MOZ_ASSERT(aUserData); - static_cast<MPRISServiceHandler*>(aUserData)->OnNameAcquired(aConnection, - aName); -} - -void MPRISServiceHandler::OnNameLostStatic(GDBusConnection* aConnection, - const gchar* aName, - gpointer aUserData) { - MOZ_ASSERT(aUserData); - static_cast<MPRISServiceHandler*>(aUserData)->OnNameLost(aConnection, aName); -} - -void MPRISServiceHandler::OnBusAcquiredStatic(GDBusConnection* aConnection, - const gchar* aName, - gpointer aUserData) { - MOZ_ASSERT(aUserData); - static_cast<MPRISServiceHandler*>(aUserData)->OnBusAcquired(aConnection, - aName); -} - -void MPRISServiceHandler::OnNameAcquired(GDBusConnection* aConnection, - const gchar* aName) { - LOG("OnNameAcquired: %s", aName); - mConnection = aConnection; -} - -void MPRISServiceHandler::OnNameLost(GDBusConnection* aConnection, - const gchar* aName) { - LOG("OnNameLost: %s", aName); - mConnection = nullptr; - if (!mRootRegistrationId) { - return; - } - - if (g_dbus_connection_unregister_object(aConnection, mRootRegistrationId)) { - mRootRegistrationId = 0; - } else { - // Note: Most code examples in the internet probably dont't even check the - // result here, but - // according to the spec it _can_ return false. - LOG("Unable to unregister root object from within onNameLost!"); - } - - if (!mPlayerRegistrationId) { - return; - } - - if (g_dbus_connection_unregister_object(aConnection, mPlayerRegistrationId)) { - mPlayerRegistrationId = 0; - } else { - // Note: Most code examples in the internet probably dont't even check the - // result here, but - // according to the spec it _can_ return false. - LOG("Unable to unregister object from within onNameLost!"); - } -} - -void MPRISServiceHandler::OnBusAcquired(GDBusConnection* aConnection, - const gchar* aName) { - GError* error = nullptr; - LOG("OnBusAcquired: %s", aName); - - mRootRegistrationId = g_dbus_connection_register_object( - aConnection, DBUS_MPRIS_OBJECT_PATH, mIntrospectionData->interfaces[0], - &gInterfaceVTable, this, /* user_data */ - nullptr, /* user_data_free_func */ - &error); /* GError** */ - - if (mRootRegistrationId == 0) { - LOG("Failed at root registration: %s", - error ? error->message : "Unknown Error"); - if (error) { - g_error_free(error); - } - return; - } - - mPlayerRegistrationId = g_dbus_connection_register_object( - aConnection, DBUS_MPRIS_OBJECT_PATH, mIntrospectionData->interfaces[1], - &gInterfaceVTable, this, /* user_data */ - nullptr, /* user_data_free_func */ - &error); /* GError** */ - - if (mPlayerRegistrationId == 0) { - LOG("Failed at object registration %s", - error ? error->message : "Unknown Error"); - if (error) { - g_error_free(error); - } - } -} - -bool MPRISServiceHandler::Open() { - MOZ_ASSERT(!mInitialized); - MOZ_ASSERT(NS_IsMainThread()); - GError* error = nullptr; - gchar serviceName[256]; - SprintfLiteral(serviceName, DBUS_MRPIS_SERVICE_NAME ".instance%d", getpid()); - mOwnerId = - g_bus_own_name(G_BUS_TYPE_SESSION, serviceName, - // Enter a waiting queue until this service name is free - // (likely another FF instance is running/has been crashed) - G_BUS_NAME_OWNER_FLAGS_NONE, OnBusAcquiredStatic, - OnNameAcquiredStatic, OnNameLostStatic, this, nullptr); - - /* parse introspection data */ - mIntrospectionData = g_dbus_node_info_new_for_xml(introspection_xml, &error); - - if (!mIntrospectionData) { - LOG("Failed at parsing XML Interface definition %s", - error ? error->message : "Unknown Error"); - if (error) { - g_error_free(error); - } - return false; - } - - mInitialized = true; - return true; -} - -MPRISServiceHandler::~MPRISServiceHandler() { - MOZ_ASSERT(!mInitialized); // Close hasn't been called! -} - -void MPRISServiceHandler::Close() { - gchar serviceName[256]; - SprintfLiteral(serviceName, DBUS_MRPIS_SERVICE_NAME ".instance%d", getpid()); - - OnNameLost(mConnection, serviceName); - - if (mOwnerId != 0) { - g_bus_unown_name(mOwnerId); - } - if (mIntrospectionData) { - g_dbus_node_info_unref(mIntrospectionData); - } - - mInitialized = false; - MediaControlKeysEventSource::Close(); -} - -bool MPRISServiceHandler::IsOpened() const { return mInitialized; } - -bool MPRISServiceHandler::HasTrackList() { return false; } - -const char* MPRISServiceHandler::Identity() { return "Mozilla Firefox"; } - -GVariant* MPRISServiceHandler::SupportedUriSchemes() { - GVariantBuilder builder; - g_variant_builder_init(&builder, G_VARIANT_TYPE("as")); - return g_variant_builder_end(&builder); -} - -GVariant* MPRISServiceHandler::SupportedMimeTypes() { - GVariantBuilder builder; - g_variant_builder_init(&builder, G_VARIANT_TYPE("as")); - return g_variant_builder_end(&builder); -} - -constexpr bool MPRISServiceHandler::CanRaise() { return false; } - -void MPRISServiceHandler::Raise() { - MOZ_ASSERT_UNREACHABLE("CanRaise is false, this method is not implemented"); -} - -constexpr bool MPRISServiceHandler::CanQuit() { return false; } - -void MPRISServiceHandler::Quit() { - MOZ_ASSERT_UNREACHABLE("CanQuit is false, this method is not implemented"); -} - -bool MPRISServiceHandler::CanGoNext() const { return true; } - -bool MPRISServiceHandler::CanGoPrevious() const { return true; } - -bool MPRISServiceHandler::CanPlay() const { return true; } - -bool MPRISServiceHandler::CanPause() const { return true; } - -// We don't support Seeking or Setting/Getting the Position yet -bool MPRISServiceHandler::CanSeek() const { return false; } - -bool MPRISServiceHandler::CanControl() const { - return true; // we don't support LoopStatus, Shuffle, Rate or Volume, but at - // least KDE blocks Play/Pause when CanControl is false. -} - -// We don't support getting the volume (yet) so return a dummy value. -double MPRISServiceHandler::GetVolume() const { return 1.0f; } - -// we don't support setting the volume yet, so this is a no-op -bool MPRISServiceHandler::SetVolume(double aVolume) { - if (aVolume > 1.0f || aVolume < 0.0f) { - return false; - } - LOG("Volume set to %f", aVolume); - return true; -} -int64_t MPRISServiceHandler::GetPosition() const { return 0; } - -constexpr double MPRISServiceHandler::GetMinimumRate() { return 1.0f; } - -constexpr double MPRISServiceHandler::GetMaximumRate() { return 1.0f; } - -// Getting and Setting the Rate doesn't work yet, so it will be locked to 1.0 -double MPRISServiceHandler::GetRate() const { return 1.0f; } - -bool MPRISServiceHandler::SetRate(double aRate) { - if (aRate > GetMaximumRate() || aRate < GetMinimumRate()) { - return false; - } - - LOG("Set Playback Rate to %f", aRate); - return true; -} - -void MPRISServiceHandler::SetPlaybackState(dom::PlaybackState aState) { - LOG("SetPlaybackState"); - if (mPlaybackState == aState) { - return; - } - - MediaControlKeysEventSource::SetPlaybackState(aState); - - if (!mConnection) { - return; // No D-Bus Connection, no event - } - - GVariant* state = GetPlaybackStatus(); - if (!state) { - return; // Invalid state - } - - GVariantBuilder builder; - g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); - g_variant_builder_add(&builder, "{sv}", "PlaybackStatus", state); - g_dbus_connection_emit_signal( - mConnection, nullptr, DBUS_MPRIS_OBJECT_PATH, - "org.freedesktop.DBus.Properties", "PropertiesChanged", - g_variant_new("(sa{sv}as)", "org.mpris.MediaPlayer2", &builder, nullptr), - nullptr); -} - -GVariant* MPRISServiceHandler::GetPlaybackStatus() const { - switch (GetPlaybackState()) { - case dom::PlaybackState::ePlaying: - return g_variant_new_string("Playing"); - case dom::PlaybackState::ePaused: - return g_variant_new_string("Paused"); - case dom::PlaybackState::eStopped: - return g_variant_new_string("Stopped"); - default: - MOZ_ASSERT_UNREACHABLE("Invalid Playback State"); - return nullptr; - } -} - -void MPRISServiceHandler::EmitEvent(mozilla::dom::MediaControlKeysEvent event) { - for (auto& listener : mListeners) { - listener->OnKeyPressed(event); - } -} - -void MPRISServiceHandler::Next() { - LOG("Next"); - EmitEvent(mozilla::dom::MediaControlKeysEvent::eNextTrack); -} - -void MPRISServiceHandler::Previous() { - LOG("Previous"); - EmitEvent(mozilla::dom::MediaControlKeysEvent::ePrevTrack); -} - -void MPRISServiceHandler::Pause() { - LOG("Pause"); - EmitEvent(mozilla::dom::MediaControlKeysEvent::ePause); -} - -void MPRISServiceHandler::PlayPause() { - LOG("PlayPause"); - EmitEvent(mozilla::dom::MediaControlKeysEvent::ePlayPause); -} - -void MPRISServiceHandler::Stop() { - LOG("Stop"); - EmitEvent(mozilla::dom::MediaControlKeysEvent::eStop); -} - -void MPRISServiceHandler::Play() { - LOG("Play"); - EmitEvent(mozilla::dom::MediaControlKeysEvent::ePlay); -} - -// Caution, Seek can really be negative, like -1000000 during testing -void MPRISServiceHandler::Seek(int64_t aOffset) { LOG("Seek(%ld)", aOffset); } - -// The following two methods are untested as my Desktop Widget didn't issue -// these calls. -void MPRISServiceHandler::SetPosition(char* aTrackId, int64_t aPosition) { - LOG("SetPosition(%s, %ld)", aTrackId, aPosition); -} - -bool MPRISServiceHandler::OpenUri(char* aUri) { - LOG("OpenUri(%s)", aUri); - return false; -} - -std::vector<struct MPRISMetadata> MPRISServiceHandler::GetDefaultMetadata() { - std::vector<struct MPRISMetadata> list; - - list.push_back({"mpris:trackid", g_variant_new("o", "/valid/path")}); - list.push_back({"xesam:title", g_variant_new_string("Firefox")}); - - GVariantBuilder artistBuilder; // Artists is a list. - g_variant_builder_init(&artistBuilder, G_VARIANT_TYPE("as")); - g_variant_builder_add(&artistBuilder, "s", "Mozilla"); - GVariant* artists = g_variant_builder_end(&artistBuilder); - - list.push_back({"xesam:artist", artists}); - return list; -} - -} // namespace widget -} // namespace mozilla diff --git a/widget/gtk/MPRISServiceHandler.h b/widget/gtk/MPRISServiceHandler.h deleted file mode 100644 index fc6b3f8c62cd2..0000000000000 --- a/widget/gtk/MPRISServiceHandler.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef WIDGET_GTK_MPRIS_SERVICE_HANDLER_H_ -#define WIDGET_GTK_MPRIS_SERVICE_HANDLER_H_ - -#include <gio/gio.h> -#include "mozilla/dom/MediaControlKeysEvent.h" -#include "mozilla/Attributes.h" - -#define DBUS_MRPIS_SERVICE_NAME "org.mpris.MediaPlayer2.firefox" -#define DBUS_MPRIS_OBJECT_PATH "/org/mpris/MediaPlayer2" - -namespace mozilla { -namespace widget { - -struct MPRISMetadata { - const char* mKey; - GVariant* mValue; -}; - -/** - * This class implements the "MPRIS" D-Bus Service - * (https://specifications.freedesktop.org/mpris-spec/2.2), - * which is used to communicate with the Desktop Environment about the - * Multimedia playing in Gecko. - * Note that this interface requires many methods which may not be supported by - * Gecko, the interface - * however provides CanXYZ properties for these methods, so the method is - * defined but won't be executed. - * - * Also note that the following defines are for parts that the MPRIS Spec - * defines optional. The code won't - * compile with any of the defines set, yet, as those aren't implemented yet and - * probably never will be of - * use for gecko. For sake of completeness, they have been added until the - * decision about their implementation - * is finally made. - * - * The constexpr'ed methods are capabilities of the user agent known at compile - * time, e.g. we decided at - * compile time whether we ever want to support closing the user agent via MPRIS - * (Quit() and CanQuit()). - * - * Other properties like CanPlay() might depend on the runtime state (is there - * media available for playback?) - * and thus aren't a constexpr but merely a const method. - */ -class MPRISServiceHandler final : public dom::MediaControlKeysEventSource { - NS_INLINE_DECL_REFCOUNTING(MPRISServiceHandler, override) - public: - // Note that this constructor does NOT initialize the MPRIS Service but only - // this class. The method Open() is responsible for registering and MAY FAIL. - MPRISServiceHandler() = default; - bool Open() override; - void Close() override; - bool IsOpened() const override; - - // From the EventSource. - void SetPlaybackState(dom::PlaybackState aState) override; - - // GetPlaybackState returns dom::PlaybackState. GetPlaybackStatus returns this - // state converted into d-bus variants. - GVariant* GetPlaybackStatus() const; - -// Implementations of the MPRIS API Methods/Properties. constexpr'ed properties -// will be what the user agent doesn't support and thus they are known at -// compile time. -#ifdef MPRIS_FULLSCREEN - bool GetFullscreen(); - void SetFullscreen(bool aFullscreen); - bool CanSetFullscreen(); -#endif - bool HasTrackList(); - const char* Identity(); -#ifdef MPRIS_DESKTOP_ENTRY - const char* DesktopEntry(); -#endif - GVariant* SupportedUriSchemes(); - GVariant* SupportedMimeTypes(); - constexpr bool CanRaise(); - void Raise(); - constexpr bool CanQuit(); - void Quit(); - - // :Player::Methods - void Next(); - void Previous(); - void Pause(); - void PlayPause(); - void Stop(); - void Play(); - void Seek(int64_t aOffset); - void SetPosition(char* aTrackId, int64_t aPosition); - // bool is our custom addition: return false whether opening fails/is not - // supported for that URI it will raise a DBUS Error - bool OpenUri(char* aUri); - -#ifdef MPRIS_LOOP_STATUS - MPRISLoopStatus GetLoopStatus(); -#endif - - double GetRate() const; - bool SetRate(double aRate); - constexpr double GetMinimumRate(); - constexpr double GetMaximumRate(); - -#ifdef MPRIS_SHUFFLE - bool GetShuffle() const; - void SetShuffle(bool aShuffle); -#endif - - std::vector<struct MPRISMetadata> GetDefaultMetadata(); - double GetVolume() const; - bool SetVolume(double aVolume); - int64_t GetPosition() const; - - bool CanGoNext() const; - bool CanGoPrevious() const; - bool CanPlay() const; - bool CanPause() const; - bool CanSeek() const; - bool CanControl() const; - - private: - ~MPRISServiceHandler(); - - // Note: Registration Ids for the D-Bus start with 1, so a value of 0 - // indicates an error (or an object which wasn't initialized yet) - - // a handle to our bus registration/ownership - guint mOwnerId = 0; - // This is for the interface org.mpris.MediaPlayer2 - guint mRootRegistrationId = 0; - // This is for the interface org.mpris.MediaPlayer2.Player - guint mPlayerRegistrationId = 0; - GDBusNodeInfo* mIntrospectionData = nullptr; - GDBusConnection* mConnection = nullptr; - bool mInitialized = false; - - // non-public API, called from events - void OnNameAcquired(GDBusConnection* aConnection, const gchar* aName); - void OnNameLost(GDBusConnection* aConnection, const gchar* aName); - void OnBusAcquired(GDBusConnection* aConnection, const gchar* aName); - - static void OnNameAcquiredStatic(GDBusConnection* aConnection, - const gchar* aName, gpointer aUserData); - static void OnNameLostStatic(GDBusConnection* aConnection, const gchar* aName, - gpointer aUserData); - static void OnBusAcquiredStatic(GDBusConnection* aConnection, - const gchar* aName, gpointer aUserData); - - void EmitEvent(mozilla::dom::MediaControlKeysEvent event); -}; - -} // namespace widget -} // namespace mozilla - -#endif // WIDGET_GTK_MPRIS_SERVICE_HANDLER_H_ diff --git a/widget/gtk/MediaKeysEventSourceFactory.cpp b/widget/gtk/MediaKeysEventSourceFactory.cpp index 997cd06360504..8784d1a1cf637 100644 --- a/widget/gtk/MediaKeysEventSourceFactory.cpp +++ b/widget/gtk/MediaKeysEventSourceFactory.cpp @@ -3,12 +3,12 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "MediaKeysEventSourceFactory.h" -#include "MPRISServiceHandler.h" namespace mozilla::widget { mozilla::dom::MediaControlKeysEventSource* CreateMediaControlKeysEventSource() { - return new MPRISServiceHandler(); + // TODO : will implement this in bug 1353652. + return nullptr; } } // namespace mozilla::widget diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build index d62391bd66e04..1c8ee424aeb11 100644 --- a/widget/gtk/moz.build +++ b/widget/gtk/moz.build @@ -32,7 +32,6 @@ EXPORTS.mozilla += [ UNIFIED_SOURCES += [ 'IMContextWrapper.cpp', 'mozcontainer.cpp', - 'MPRISServiceHandler.cpp', 'NativeKeyBindings.cpp', 'nsAppShell.cpp', 'nsBidiKeyboard.cpp', -- GitLab