Skip to content
Snippets Groups Projects
Commit 1eb3d684 authored by Marc Streckfuss's avatar Marc Streckfuss
Browse files

Bug 1353652 - Initial Draft of MPRIS API Provider (Media API on Linux) r=alwu

Differential Revision: https://phabricator.services.mozilla.com/D47999

--HG--
extra : moz-landing-system : lando
parent 2731ff13
No related branches found
No related tags found
No related merge requests found
...@@ -59,6 +59,9 @@ tools/clang-tidy/test/.* ...@@ -59,6 +59,9 @@ tools/clang-tidy/test/.*
# We are testing the incorrect formatting. # We are testing the incorrect formatting.
tools/lint/test/files/file-whitespace/ 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 # The XPTCall stubs files have some inline assembly macros
# that get reformatted badly. See bug 1510781. # that get reformatted badly. See bug 1510781.
xpcom/reflect/xptcall/md/win32/.* xpcom/reflect/xptcall/md/win32/.*
......
/* -*- 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_
This diff is collapsed.
/* -*- 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_
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MediaKeysEventSourceFactory.h" #include "MediaKeysEventSourceFactory.h"
#include "MPRISServiceHandler.h"
namespace mozilla::widget { namespace mozilla::widget {
mozilla::dom::MediaControlKeysEventSource* CreateMediaControlKeysEventSource() { mozilla::dom::MediaControlKeysEventSource* CreateMediaControlKeysEventSource() {
// TODO : will implement this in bug 1353652. return new MPRISServiceHandler();
return nullptr;
} }
} // namespace mozilla::widget } // namespace mozilla::widget
...@@ -32,6 +32,7 @@ EXPORTS.mozilla += [ ...@@ -32,6 +32,7 @@ EXPORTS.mozilla += [
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'IMContextWrapper.cpp', 'IMContextWrapper.cpp',
'mozcontainer.cpp', 'mozcontainer.cpp',
'MPRISServiceHandler.cpp',
'NativeKeyBindings.cpp', 'NativeKeyBindings.cpp',
'nsAppShell.cpp', 'nsAppShell.cpp',
'nsBidiKeyboard.cpp', 'nsBidiKeyboard.cpp',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment