From 8f0d0a884ec6e52b9b62e56f6bc977db2948dd03 Mon Sep 17 00:00:00 2001 From: Chun-Min Chang Date: Wed, 9 Oct 2019 21:14:49 +0000 Subject: [PATCH] Bug 1580602 - P1: Implement a blank MediaSession interface. r=bzbarsky Create dummy implementations for the MediaSession interfaces. The files are generated by running `./mach webidl-example` with necessary changes to make it buildable. The internal implementations are blank in this patch. They will be done in the following patches. Due to some spec issues, the final implementations only support some basic operations like "play" and "pause". Differential Revision: https://phabricator.services.mozilla.com/D45456 --HG-- extra : moz-landing-system : lando --- dom/base/Navigator.cpp | 10 ++++ dom/base/Navigator.h | 3 ++ dom/media/mediasession/MediaMetadata.cpp | 54 +++++++++++++++++++ dom/media/mediasession/MediaMetadata.h | 67 ++++++++++++++++++++++++ dom/media/mediasession/MediaSession.cpp | 37 +++++++++++++ dom/media/mediasession/MediaSession.h | 51 ++++++++++++++++++ dom/media/mediasession/moz.build | 17 ++++++ dom/media/moz.build | 1 + dom/webidl/MediaSession.webidl | 65 +++++++++++++++++++++++ dom/webidl/Navigator.webidl | 8 +++ dom/webidl/moz.build | 1 + modules/libpref/init/StaticPrefList.yaml | 6 +++ 12 files changed, 320 insertions(+) create mode 100644 dom/media/mediasession/MediaMetadata.cpp create mode 100644 dom/media/mediasession/MediaMetadata.h create mode 100644 dom/media/mediasession/MediaSession.cpp create mode 100644 dom/media/mediasession/MediaSession.h create mode 100644 dom/media/mediasession/moz.build create mode 100644 dom/webidl/MediaSession.webidl diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index 326086491fd9..00248793fc19 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -41,6 +41,7 @@ #include "mozilla/dom/FeaturePolicyUtils.h" #include "mozilla/dom/GamepadServiceTest.h" #include "mozilla/dom/MediaCapabilities.h" +#include "mozilla/dom/MediaSession.h" #include "mozilla/dom/WakeLock.h" #include "mozilla/dom/power/PowerManagerService.h" #include "mozilla/dom/MIDIAccessManager.h" @@ -160,6 +161,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaDevices) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServiceWorkerContainer) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaCapabilities) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaSession) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAddonManager) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebGpu) @@ -233,6 +235,7 @@ void Navigator::Invalidate() { } mMediaCapabilities = nullptr; + mMediaSession = nullptr; mAddonManager = nullptr; @@ -1937,6 +1940,13 @@ dom::MediaCapabilities* Navigator::MediaCapabilities() { return mMediaCapabilities; } +dom::MediaSession* Navigator::MediaSession() { + if (!mMediaSession) { + mMediaSession = new dom::MediaSession(); + } + return mMediaSession; +} + Clipboard* Navigator::Clipboard() { if (!mClipboard) { mClipboard = new dom::Clipboard(GetWindow()); diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index dca0d0364d20..8c7e756c7ed0 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -80,6 +80,7 @@ class VRDisplay; class VRServiceTest; class StorageManager; class MediaCapabilities; +class MediaSession; struct ShareData; class WindowGlobalChild; @@ -217,6 +218,7 @@ class Navigator final : public nsISupports, public nsWrapperCache { static void GetAcceptLanguages(nsTArray& aLanguages); dom::MediaCapabilities* MediaCapabilities(); + dom::MediaSession* MediaSession(); AddonManager* GetMozAddonManager(ErrorResult& aRv); @@ -278,6 +280,7 @@ class Navigator final : public nsISupports, public nsWrapperCache { nsTArray mRequestedVibrationPattern; RefPtr mStorageManager; RefPtr mMediaCapabilities; + RefPtr mMediaSession; RefPtr mAddonManager; RefPtr mWebGpu; RefPtr mSharePromise; // Web Share API related diff --git a/dom/media/mediasession/MediaMetadata.cpp b/dom/media/mediasession/MediaMetadata.cpp new file mode 100644 index 000000000000..b73fa7902550 --- /dev/null +++ b/dom/media/mediasession/MediaMetadata.cpp @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 "mozilla/dom/MediaMetadata.h" +#include "mozilla/dom/MediaSessionBinding.h" + +namespace mozilla { +namespace dom { + +// Only needed for refcounted objects. +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MediaMetadata) +NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaMetadata) +NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaMetadata) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaMetadata) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +nsIGlobalObject* MediaMetadata::GetParentObject() const { return nullptr; } + +JSObject* MediaMetadata::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) { + return MediaMetadata_Binding::Wrap(aCx, this, aGivenProto); +} + +already_AddRefed MediaMetadata::Constructor( + const GlobalObject& aGlobal, const MediaMetadataInit& aInit, + ErrorResult& aRv) { + return nullptr; +} + +void MediaMetadata::GetTitle(nsString& aRetVal) const {} + +void MediaMetadata::SetTitle(const nsAString& aTitle) {} + +void MediaMetadata::GetArtist(nsString& aRetVal) const {} + +void MediaMetadata::SetArtist(const nsAString& aArtist) {} + +void MediaMetadata::GetAlbum(nsString& aRetVal) const {} + +void MediaMetadata::SetAlbum(const nsAString& aAlbum) {} + +void MediaMetadata::GetArtwork(JSContext* aCx, nsTArray& aRetVal, + ErrorResult& aRv) const {} + +void MediaMetadata::SetArtwork(JSContext* aCx, + const Sequence& aArtwork, + ErrorResult& aRv){}; +} // namespace dom +} // namespace mozilla diff --git a/dom/media/mediasession/MediaMetadata.h b/dom/media/mediasession/MediaMetadata.h new file mode 100644 index 000000000000..f5f55831e456 --- /dev/null +++ b/dom/media/mediasession/MediaMetadata.h @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 mozilla_dom_MediaMetadata_h +#define mozilla_dom_MediaMetadata_h + +#include "js/TypeDecls.h" +#include "mozilla/Attributes.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/ErrorResult.h" +#include "nsCycleCollectionParticipant.h" +#include "nsWrapperCache.h" + +class nsIGlobalObject; + +namespace mozilla { +namespace dom { + +struct MediaImage; +struct MediaMetadataInit; + +class MediaMetadata final : public nsISupports, public nsWrapperCache { + public: + // Ref counting and cycle collection + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaMetadata) + + // WebIDL methods + nsIGlobalObject* GetParentObject() const; + + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + static already_AddRefed Constructor( + const GlobalObject& aGlobal, const MediaMetadataInit& aInit, + ErrorResult& aRv); + + void GetTitle(nsString& aRetVal) const; + + void SetTitle(const nsAString& aTitle); + + void GetArtist(nsString& aRetVal) const; + + void SetArtist(const nsAString& aArtist); + + void GetAlbum(nsString& aRetVal) const; + + void SetAlbum(const nsAString& aAlbum); + + void GetArtwork(JSContext* aCx, nsTArray& aRetVal, + ErrorResult& aRv) const; + + void SetArtwork(JSContext* aCx, const Sequence& aArtwork, + ErrorResult& aRv); + + private: + MediaMetadata() = default; + ~MediaMetadata() = default; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_MediaMetadata_h diff --git a/dom/media/mediasession/MediaSession.cpp b/dom/media/mediasession/MediaSession.cpp new file mode 100644 index 000000000000..699332ac0598 --- /dev/null +++ b/dom/media/mediasession/MediaSession.cpp @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 "mozilla/dom/MediaMetadata.h" +#include "mozilla/dom/MediaSession.h" + +namespace mozilla { +namespace dom { + +// Only needed for refcounted objects. +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MediaSession) +NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaSession) +NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaSession) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaSession) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +nsIGlobalObject* MediaSession::GetParentObject() const { return nullptr; } + +JSObject* MediaSession::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) { + return MediaSession_Binding::Wrap(aCx, this, aGivenProto); +} + +MediaMetadata* MediaSession::GetMetadata() const { return nullptr; } + +void MediaSession::SetMetadata(MediaMetadata* aMetadata) {} + +void MediaSession::SetActionHandler(MediaSessionAction aAction, + MediaSessionActionHandler* aHandler) {} + +} // namespace dom +} // namespace mozilla diff --git a/dom/media/mediasession/MediaSession.h b/dom/media/mediasession/MediaSession.h new file mode 100644 index 000000000000..5cdb63d143d4 --- /dev/null +++ b/dom/media/mediasession/MediaSession.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 mozilla_dom_MediaSession_h +#define mozilla_dom_MediaSession_h + +#include "js/TypeDecls.h" +#include "mozilla/Attributes.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/dom/MediaSessionBinding.h" +#include "mozilla/ErrorResult.h" +#include "nsCycleCollectionParticipant.h" +#include "nsWrapperCache.h" + +class nsIGlobalObject; + +namespace mozilla { +namespace dom { + +class MediaSession final : public nsISupports, public nsWrapperCache { + public: + // Ref counting and cycle collection + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaSession) + + MediaSession() = default; + + // WebIDL methods + nsIGlobalObject* GetParentObject() const; + + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + MediaMetadata* GetMetadata() const; + + void SetMetadata(MediaMetadata* aMetadata); + + void SetActionHandler(MediaSessionAction aAction, + MediaSessionActionHandler* aHandler); + + private: + ~MediaSession() = default; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_MediaSession_h diff --git a/dom/media/mediasession/moz.build b/dom/media/mediasession/moz.build new file mode 100644 index 000000000000..47925760de31 --- /dev/null +++ b/dom/media/mediasession/moz.build @@ -0,0 +1,17 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +EXPORTS.mozilla.dom += [ + 'MediaMetadata.h', + 'MediaSession.h', +] + +UNIFIED_SOURCES += [ + 'MediaMetadata.cpp', + 'MediaSession.cpp', +] + +FINAL_LIBRARY = 'xul' diff --git a/dom/media/moz.build b/dom/media/moz.build index 81cfe3b5e816..96a374ff91ce 100644 --- a/dom/media/moz.build +++ b/dom/media/moz.build @@ -45,6 +45,7 @@ DIRS += [ 'mediacontrol', 'mediasink', 'mediasource', + 'mediasession', 'mp3', 'ogg', 'platforms', diff --git a/dom/webidl/MediaSession.webidl b/dom/webidl/MediaSession.webidl new file mode 100644 index 000000000000..95bb7d38aa73 --- /dev/null +++ b/dom/webidl/MediaSession.webidl @@ -0,0 +1,65 @@ +/* -*- Mode: IDL; tab-width: 2; 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/. + * + * The origin of this IDL file is + * https://w3c.github.io/mediasession/#idl-index + */ + +// TODO: Implement MediaSessionPlaybackState (bug 1582508) + +// TODO: Implement the missing seek* (bug 1580623) and skipad (bug 1582569) actions +enum MediaSessionAction { + "play", + "pause", + "previoustrack", + "nexttrack", + "stop", +}; + +callback MediaSessionActionHandler = void(MediaSessionActionDetails details); + +[Exposed=Window, Pref="dom.media.mediasession.enabled"] +interface MediaSession { + attribute MediaMetadata? metadata; + + // TODO: attribute MediaSessionPlaybackState playbackState; (bug 1582508) + + void setActionHandler(MediaSessionAction action, MediaSessionActionHandler? handler); + + // TODO: void setPositionState(optional MediaPositionState? state); (bug 1582509) +}; + +[Exposed=Window, Pref="dom.media.mediasession.enabled"] +interface MediaMetadata { + [Throws] + constructor(optional MediaMetadataInit init = {}); + + attribute DOMString title; + attribute DOMString artist; + attribute DOMString album; + // https://github.com/w3c/mediasession/issues/237 + // Take and return `MediaImage` on setter and getter. + [Frozen, Cached, Pure, Throws] + attribute sequence artwork; +}; + +dictionary MediaMetadataInit { + DOMString title = ""; + DOMString artist = ""; + DOMString album = ""; + sequence artwork = []; +}; + +dictionary MediaImage { + required USVString src; + DOMString sizes = ""; + DOMString type = ""; +}; + +dictionary MediaSessionActionDetails { + required MediaSessionAction action; +}; + +// TODO: Implement MediaPositionState (bug 1582509) diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl index b442c0672ae6..a6df66039e63 100644 --- a/dom/webidl/Navigator.webidl +++ b/dom/webidl/Navigator.webidl @@ -17,6 +17,7 @@ * https://w3c.github.io/webappsec-credential-management/#framework-credential-management * https://w3c.github.io/webdriver/webdriver-spec.html#interface * https://wicg.github.io/media-capabilities/#idl-index + * https://w3c.github.io/mediasession/#idl-index * * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and * Opera Software ASA. You are granted a license to use, reproduce @@ -334,3 +335,10 @@ dictionary ShareData { USVString text; USVString url; }; + +// https://w3c.github.io/mediasession/#idl-index +[Exposed=Window] +partial interface Navigator { + [Pref="dom.media.mediasession.enabled", SameObject] + readonly attribute MediaSession mediaSession; +}; \ No newline at end of file diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 92503627aa28..5e38f18de8c9 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -657,6 +657,7 @@ WEBIDL_FILES = [ 'MediaList.webidl', 'MediaQueryList.webidl', 'MediaRecorder.webidl', + 'MediaSession.webidl', 'MediaSource.webidl', 'MediaStream.webidl', 'MediaStreamAudioDestinationNode.webidl', diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 282e80587cef..e824b95fa542 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -1742,6 +1742,12 @@ value: false mirror: always +# Media Session API +- name: dom.media.mediasession.enabled + type: bool + value: false + mirror: always + # Enable meta-viewport support in remote APZ-enabled frames. - name: dom.meta-viewport.enabled type: RelaxedAtomicBool