Diff
Modified: trunk/LayoutTests/ChangeLog (231865 => 231866)
--- trunk/LayoutTests/ChangeLog 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/LayoutTests/ChangeLog 2018-05-16 20:36:26 UTC (rev 231866)
@@ -1,3 +1,17 @@
+2018-05-16 Eric Carlson <eric.carl...@apple.com>
+
+ Improve NowPlaying "title"
+ https://bugs.webkit.org/show_bug.cgi?id=185680
+ <rdar://problem/40296700>
+
+ Reviewed by Jer Noble.
+
+ * http/tests/media/now-playing-info-expected.txt: Added.
+ * http/tests/media/now-playing-info-private-browsing-expected.txt: Added.
+ * http/tests/media/now-playing-info-private-browsing.html: Added.
+ * http/tests/media/now-playing-info.html: Added.
+ * platform/gtk/TestExpectations:
+
2018-05-16 Youenn Fablet <you...@apple.com>
Layout Test webrtc/addICECandidate-closed.html is a flaky failure
Added: trunk/LayoutTests/http/tests/media/now-playing-info-expected.txt (0 => 231866)
--- trunk/LayoutTests/http/tests/media/now-playing-info-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/media/now-playing-info-expected.txt 2018-05-16 20:36:26 UTC (rev 231866)
@@ -0,0 +1,45 @@
+
+Tests that the NowPlaying information is updated correctly as attributes change.
+
+* NowPlaying should not be active before playback has started.
+RUN(video.src = "" "resources/test"))
+EVENT(canplaythrough)
+RUN(nowPlayingState = internals.nowPlayingState)
+EXPECTED (nowPlayingState.registeredAsNowPlayingApplication == 'false') OK
+
+* Start to play, NowPlaying should become active.
+RUN(video.play())
+EVENT(playing)
+RUN(video.pause())
+
+* Title should be page title because video has no title.
+RUN(nowPlayingState = internals.nowPlayingState)
+EXPECTED (nowPlayingState.registeredAsNowPlayingApplication == 'true') OK
+EXPECTED (nowPlayingState.title == 'Page Title') OK
+EXPECTED (nowPlayingState.duration > '0') OK
+EXPECTED (nowPlayingState.elapsedTime >= '0') OK
+
+* Set video title, it should be used.
+RUN(video.title = "Video Title")
+RUN(nowPlayingState = internals.nowPlayingState)
+EXPECTED (nowPlayingState.registeredAsNowPlayingApplication == 'true') OK
+EXPECTED (nowPlayingState.title == 'Video Title') OK
+EXPECTED (nowPlayingState.duration > '0') OK
+
+* Clear video and page titles, page domain should be used.
+RUN(video.title = "")
+RUN(document.title = "")
+RUN(nowPlayingState = internals.nowPlayingState)
+EXPECTED (nowPlayingState.registeredAsNowPlayingApplication == 'true') OK
+EXPECTED (nowPlayingState.title == '127.0.0.1') OK
+EXPECTED (nowPlayingState.duration > '0') OK
+
+* Change currentTime, state should be updated.
+RUN(video.currentTime = video.currentTime + 0.5)
+RUN(nowPlayingState = internals.nowPlayingState)
+EXPECTED (nowPlayingState.registeredAsNowPlayingApplication == 'true') OK
+EXPECTED (nowPlayingState.title == '127.0.0.1') OK
+EXPECTED (nowPlayingState.duration > '0') OK
+
+END OF TEST
+
Added: trunk/LayoutTests/http/tests/media/now-playing-info-private-browsing-expected.txt (0 => 231866)
--- trunk/LayoutTests/http/tests/media/now-playing-info-private-browsing-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/media/now-playing-info-private-browsing-expected.txt 2018-05-16 20:36:26 UTC (rev 231866)
@@ -0,0 +1,23 @@
+
+Tests that the NowPlaying title is not set when in private browsing mode.
+
+* NowPlaying should not be active before playback has started.
+RUN(video.src = "" "resources/test"))
+EVENT(canplaythrough)
+RUN(nowPlayingState = internals.nowPlayingState)
+EXPECTED (nowPlayingState.registeredAsNowPlayingApplication == 'false') OK
+
+* Start to play, NowPlaying should become active.
+RUN(video.play())
+EVENT(playing)
+RUN(video.pause())
+
+* Title should be blank because video has no title.
+RUN(nowPlayingState = internals.nowPlayingState)
+EXPECTED (nowPlayingState.registeredAsNowPlayingApplication == 'true') OK
+EXPECTED (nowPlayingState.title == '') OK
+EXPECTED (nowPlayingState.duration > '0') OK
+EXPECTED (nowPlayingState.elapsedTime >= '0') OK
+
+END OF TEST
+
Added: trunk/LayoutTests/http/tests/media/now-playing-info-private-browsing.html (0 => 231866)
--- trunk/LayoutTests/http/tests/media/now-playing-info-private-browsing.html (rev 0)
+++ trunk/LayoutTests/http/tests/media/now-playing-info-private-browsing.html 2018-05-16 20:36:26 UTC (rev 231866)
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Page Title</title>
+ <script src=""
+ <script src=""
+ <script>
+
+ let nowPlayingState;
+ let previousNowPlayingState;
+
+ if (window.testRunner)
+ testRunner.setPrivateBrowsingEnabled(true);
+
+ async function waitForAttributeToChange(attribute, expected) {
+ let start = new Date().getTime();
+ do {
+
+ if (internals.nowPlayingState[attribute] != expected)
+ return;
+
+ await new Promise(resolve => setTimeout(resolve, 100));
+ } while (new Date().getTime() - start < 500);
+
+ failTest(`** Timed out waiting for "${attribute}" to change from "${expected}"`);
+ }
+
+ async function runTest()
+ {
+ findMediaElement();
+
+ consoleWrite('<br>* NowPlaying should not be active before playback has started.');
+ run('video.src = "" "resources/test")');
+ await waitFor(video, 'canplaythrough');
+
+ run('nowPlayingState = internals.nowPlayingState');
+ testExpected('nowPlayingState.registeredAsNowPlayingApplication', false);
+
+ consoleWrite('<br>* Start to play, NowPlaying should become active.');
+ runWithKeyDown(() => {
+ run('video.play()');
+ });
+
+ await waitFor(video, 'playing');
+ run('video.pause()');
+ await waitForAttributeToChange('registeredAsNowPlayingApplication', false);
+
+ consoleWrite('<br>* Title should be blank because video has no title.');
+ run('nowPlayingState = internals.nowPlayingState');
+ testExpected('nowPlayingState.registeredAsNowPlayingApplication', true);
+ testExpected('nowPlayingState.title', '');
+ testExpected('nowPlayingState.duration', '0', '>');
+ testExpected('nowPlayingState.elapsedTime', '0', '>=');
+ previousNowPlayingState = nowPlayingState;
+
+ consoleWrite('');
+ endTest();
+ }
+ </script>
+ </head>
+ <body _onload_="runTest()">
+ <video controls title="Video Title"></video>
+ <br>
+ Tests that the NowPlaying title is not set when in private browsing mode.
+ </body>
+</html>
Added: trunk/LayoutTests/http/tests/media/now-playing-info.html (0 => 231866)
--- trunk/LayoutTests/http/tests/media/now-playing-info.html (rev 0)
+++ trunk/LayoutTests/http/tests/media/now-playing-info.html 2018-05-16 20:36:26 UTC (rev 231866)
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Page Title</title>
+ <script src=""
+ <script src=""
+ <script>
+
+ let nowPlayingState;
+ let previousNowPlayingState;
+
+ async function waitForAttributeToChange(attribute, expected) {
+ let start = new Date().getTime();
+ do {
+
+ if (internals.nowPlayingState[attribute] != expected)
+ return;
+
+ await new Promise(resolve => setTimeout(resolve, 100));
+ } while (new Date().getTime() - start < 500);
+
+ failTest(`** Timed out waiting for "${attribute}" to change from "${expected}"`);
+ }
+
+ async function runTest()
+ {
+ findMediaElement();
+
+ consoleWrite('<br>* NowPlaying should not be active before playback has started.');
+ run('video.src = "" "resources/test")');
+ await waitFor(video, 'canplaythrough');
+
+ run('nowPlayingState = internals.nowPlayingState');
+ testExpected('nowPlayingState.registeredAsNowPlayingApplication', false);
+
+ consoleWrite('<br>* Start to play, NowPlaying should become active.');
+ runWithKeyDown(() => {
+ run('video.play()');
+ });
+
+ await waitFor(video, 'playing');
+ run('video.pause()');
+ await waitForAttributeToChange('registeredAsNowPlayingApplication', false);
+
+ consoleWrite('<br>* Title should be page title because video has no title.');
+ run('nowPlayingState = internals.nowPlayingState');
+ testExpected('nowPlayingState.registeredAsNowPlayingApplication', true);
+ testExpected('nowPlayingState.title', 'Page Title');
+ testExpected('nowPlayingState.duration', '0', '>');
+ testExpected('nowPlayingState.elapsedTime', '0', '>=');
+ previousNowPlayingState = nowPlayingState;
+
+
+ consoleWrite('<br>* Set video title, it should be used.');
+ run('video.title = "Video Title"');
+ await waitForAttributeToChange('title', 'Page Title');
+
+ run('nowPlayingState = internals.nowPlayingState');
+ testExpected('nowPlayingState.registeredAsNowPlayingApplication', true);
+ testExpected('nowPlayingState.title', 'Video Title');
+ testExpected('nowPlayingState.duration', '0', '>');
+
+ // Don't use "testExpected" for time and identifier unless we know the test failed
+ // because the values will be different from run to run.
+ if (nowPlayingState.uniqueIdentifier != previousNowPlayingState.uniqueIdentifier)
+ testExpected('nowPlayingState.uniqueIdentifier', previousNowPlayingState.uniqueIdentifier);
+ if (nowPlayingState.elapsedTime != previousNowPlayingState.elapsedTime)
+ testExpected('nowPlayingState.elapsedTime', previousNowPlayingState.elapsedTime);
+ previousNowPlayingState = nowPlayingState;
+
+ consoleWrite('<br>* Clear video and page titles, page domain should be used.');
+ run('video.title = ""');
+ run('document.title = ""');
+ await waitForAttributeToChange('title', 'Video Title');
+
+ run('nowPlayingState = internals.nowPlayingState');
+ testExpected('nowPlayingState.registeredAsNowPlayingApplication', true);
+ testExpected('nowPlayingState.title', '127.0.0.1');
+ testExpected('nowPlayingState.duration', '0', '>');
+ if (nowPlayingState.uniqueIdentifier != previousNowPlayingState.uniqueIdentifier)
+ testExpected('nowPlayingState.uniqueIdentifier', previousNowPlayingState.uniqueIdentifier);
+ if (nowPlayingState.elapsedTime != previousNowPlayingState.elapsedTime)
+ testExpected('nowPlayingState.elapsedTime', previousNowPlayingState.elapsedTime);
+ previousNowPlayingState = nowPlayingState;
+
+ consoleWrite('<br>* Change currentTime, state should be updated.');
+ run('video.currentTime = video.currentTime + 0.5');
+ await waitForAttributeToChange('elapsedTime', previousNowPlayingState.elapsedTime);
+
+ run('nowPlayingState = internals.nowPlayingState');
+ testExpected('nowPlayingState.registeredAsNowPlayingApplication', true);
+ testExpected('nowPlayingState.title', '127.0.0.1');
+ testExpected('nowPlayingState.duration', '0', '>');
+ if (nowPlayingState.uniqueIdentifier != previousNowPlayingState.uniqueIdentifier)
+ testExpected('nowPlayingState.uniqueIdentifier', previousNowPlayingState.uniqueIdentifier);
+ if (nowPlayingState.elapsedTime == previousNowPlayingState.elapsedTime)
+ testExpected('nowPlayingState.elapsedTime', previousNowPlayingState.elapsedTime, '>');
+
+ consoleWrite('');
+ endTest();
+ }
+ </script>
+ </head>
+ <body _onload_="runTest()">
+ <video controls ></video>
+ <br>
+ Tests that the NowPlaying information is updated correctly as attributes change.
+ </body>
+</html>
Modified: trunk/LayoutTests/media/video-test.js (231865 => 231866)
--- trunk/LayoutTests/media/video-test.js 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/LayoutTests/media/video-test.js 2018-05-16 20:36:26 UTC (rev 231866)
@@ -186,9 +186,9 @@
}
}
-function waitFor(element, event) {
+function waitFor(element, type) {
return new Promise(resolve => {
- element.addEventListener(event, event => {
+ element.addEventListener(type, event => {
consoleWrite(`EVENT(${event.type})`);
resolve(event);
}, { once: true });
Modified: trunk/LayoutTests/platform/gtk/TestExpectations (231865 => 231866)
--- trunk/LayoutTests/platform/gtk/TestExpectations 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/LayoutTests/platform/gtk/TestExpectations 2018-05-16 20:36:26 UTC (rev 231866)
@@ -1187,6 +1187,10 @@
webkit.org/b/184295 http/wpt/loading/redirect-headers.html [ Skip ]
+# NowPlaying is macOS and iOS only.
+http/tests/media/now-playing-info-private-browsing.html [ Skip ]
+http/tests/media/now-playing-info.html [ Skip ]
+
#////////////////////////////////////////////////////////////////////////////////////////
# End of Expected failures.
#
Modified: trunk/Source/WebCore/ChangeLog (231865 => 231866)
--- trunk/Source/WebCore/ChangeLog 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/Source/WebCore/ChangeLog 2018-05-16 20:36:26 UTC (rev 231866)
@@ -1,3 +1,45 @@
+2018-05-16 Eric Carlson <eric.carl...@apple.com>
+
+ Improve NowPlaying "title"
+ https://bugs.webkit.org/show_bug.cgi?id=185680
+ <rdar://problem/40296700>
+
+ Reviewed by Jer Noble.
+
+ We send NowPlaying the element's title attribute if not empty, else the element's current url.
+ Title should be preferred because it is the most specific, but we should use the document
+ title if non-empty next, and if falling back to the element's url use just the domain instead
+ of the full url because it isn't likely to be useful to the user given the small amount of
+ space control center uses to display the title. Further, don't use any title at all when
+ in private browsing mode.
+
+ Tests: http/tests/media/now-playing-info-private-browsing.html
+ http/tests/media/now-playing-info.html
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::parseAttribute): Update NowPlaying when the title attribute changes.
+ (WebCore::HTMLMediaElement::finishSeek): Update NowPlaying when a seek completes.
+ (WebCore::HTMLMediaElement::mediaSessionTitle const): Update logic.
+ (WebCore::HTMLMediaElement::mediaSessionUniqueIdentifier const): Use the hash of the current
+ url as the unique identifier.
+ * html/HTMLMediaElement.h:
+
+ * platform/audio/PlatformMediaSession.cpp:
+ (WebCore::PlatformMediaSession::uniqueIdentifier const): New.
+ (WebCore::PlatformMediaSessionClient::mediaSessionUniqueIdentifier const): Ditto.
+ * platform/audio/PlatformMediaSession.h:
+
+ * platform/audio/ios/MediaSessionManagerIOS.mm:
+ (WebCore::MediaSessionManageriOS::updateNowPlayingInfo): Update m_lastUpdatedNowPlayingInfoUniqueIdentifier.
+
+ * platform/audio/mac/MediaSessionManagerMac.mm:
+ (WebCore::MediaSessionManagerMac::updateNowPlayingInfo): Update.
+
+ * testing/Internals.cpp:
+ (WebCore::Internals::nowPlayingState const): Expose NowPlaying state.
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2018-05-16 Daniel Bates <daba...@apple.com>
Attempt to fix the WinCairo build following r231859
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (231865 => 231866)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2018-05-16 20:36:26 UTC (rev 231866)
@@ -878,6 +878,9 @@
else if (name == autoplayAttr) {
if (processingUserGestureForMedia())
removeBehaviorsRestrictionsAfterFirstUserGesture();
+ } else if (name == titleAttr) {
+ if (m_mediaSession)
+ m_mediaSession->clientCharacteristicsChanged();
}
else
HTMLElement::parseAttribute(name, value);
@@ -3081,6 +3084,9 @@
// 17 - Queue a task to fire a simple event named seeked at the element.
scheduleEvent(eventNames().seekedEvent);
+ if (m_mediaSession)
+ m_mediaSession->clientCharacteristicsChanged();
+
#if ENABLE(MEDIA_SOURCE)
if (m_mediaSource)
m_mediaSource->monitorSourceBuffers();
@@ -7443,12 +7449,28 @@
String HTMLMediaElement::mediaSessionTitle() const
{
- if (hasAttributeWithoutSynchronization(titleAttr))
- return attributeWithoutSynchronization(titleAttr);
+ if (!document().page() || document().page()->usesEphemeralSession())
+ return emptyString();
- return m_currentSrc;
+ if (hasAttributeWithoutSynchronization(titleAttr)) {
+ auto title = attributeWithoutSynchronization(titleAttr);
+ if (!title.isEmpty())
+ return title;
+ }
+
+ auto title = document().title();
+ if (!title.isEmpty())
+ return title;
+
+ return m_currentSrc.host();
}
+uint64_t HTMLMediaElement::mediaSessionUniqueIdentifier() const
+{
+ auto& url = ""
+ return url.impl() ? url.impl()->hash() : 0;
+}
+
void HTMLMediaElement::didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType command, const PlatformMediaSession::RemoteCommandArgument* argument)
{
INFO_LOG(LOGIDENTIFIER, static_cast<int>(command));
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (231865 => 231866)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2018-05-16 20:36:26 UTC (rev 231866)
@@ -860,6 +860,7 @@
void suspendPlayback() override;
void resumeAutoplaying() override;
void mayResumePlayback(bool shouldResume) override;
+ uint64_t mediaSessionUniqueIdentifier() const final;
String mediaSessionTitle() const override;
double mediaSessionDuration() const override { return duration(); }
double mediaSessionCurrentTime() const override { return currentTime(); }
Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp (231865 => 231866)
--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp 2018-05-16 20:36:26 UTC (rev 231866)
@@ -238,6 +238,11 @@
}
#if ENABLE(VIDEO)
+uint64_t PlatformMediaSession::uniqueIdentifier() const
+{
+ return m_client.mediaSessionUniqueIdentifier();
+}
+
String PlatformMediaSession::title() const
{
return m_client.mediaSessionTitle();
@@ -323,6 +328,11 @@
}
#if ENABLE(VIDEO)
+uint64_t PlatformMediaSessionClient::mediaSessionUniqueIdentifier() const
+{
+ return 0;
+}
+
String PlatformMediaSessionClient::mediaSessionTitle() const
{
return String();
Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.h (231865 => 231866)
--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.h 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.h 2018-05-16 20:36:26 UTC (rev 231866)
@@ -113,6 +113,7 @@
void stopSession();
#if ENABLE(VIDEO)
+ uint64_t uniqueIdentifier() const;
String title() const;
double duration() const;
double currentTime() const;
@@ -216,6 +217,7 @@
virtual void suspendPlayback() = 0;
#if ENABLE(VIDEO)
+ virtual uint64_t mediaSessionUniqueIdentifier() const;
virtual String mediaSessionTitle() const;
virtual double mediaSessionDuration() const;
virtual double mediaSessionCurrentTime() const;
Modified: trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm (231865 => 231866)
--- trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm 2018-05-16 20:36:26 UTC (rev 231866)
@@ -280,6 +280,7 @@
m_reportedDuration = duration;
m_reportedTitle = title;
m_reportedCurrentTime = currentTime;
+ m_lastUpdatedNowPlayingInfoUniqueIdentifier = currentSession->uniqueIdentifier();
auto info = adoptNS([[NSMutableDictionary alloc] init]);
if (!title.isEmpty())
Modified: trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm (231865 => 231866)
--- trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/Source/WebCore/platform/audio/mac/MediaSessionManagerMac.mm 2018-05-16 20:36:26 UTC (rev 231866)
@@ -176,7 +176,7 @@
auto cfRate = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &rate));
CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoPlaybackRate, cfRate.get());
- m_lastUpdatedNowPlayingInfoUniqueIdentifier = title.impl() ? title.impl()->hash() : 0;
+ m_lastUpdatedNowPlayingInfoUniqueIdentifier = currentSession->uniqueIdentifier();
auto cfIdentifier = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &m_lastUpdatedNowPlayingInfoUniqueIdentifier));
CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoUniqueIdentifier, cfIdentifier.get());
Modified: trunk/Source/WebCore/testing/Internals.cpp (231865 => 231866)
--- trunk/Source/WebCore/testing/Internals.cpp 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/Source/WebCore/testing/Internals.cpp 2018-05-16 20:36:26 UTC (rev 231866)
@@ -3692,6 +3692,21 @@
#endif
}
+ExceptionOr<Internals::NowPlayingState> Internals::nowPlayingState() const
+{
+#if ENABLE(VIDEO)
+ return { { PlatformMediaSessionManager::sharedManager().lastUpdatedNowPlayingTitle(),
+ PlatformMediaSessionManager::sharedManager().lastUpdatedNowPlayingDuration(),
+ PlatformMediaSessionManager::sharedManager().lastUpdatedNowPlayingElapsedTime(),
+ PlatformMediaSessionManager::sharedManager().lastUpdatedNowPlayingInfoUniqueIdentifier(),
+ PlatformMediaSessionManager::sharedManager().hasActiveNowPlayingSession(),
+ PlatformMediaSessionManager::sharedManager().registeredAsNowPlayingApplication()
+ } };
+#else
+ return Exception { InvalidAccessError };
+#endif
+}
+
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
void Internals::setMockMediaPlaybackTargetPickerEnabled(bool enabled)
Modified: trunk/Source/WebCore/testing/Internals.h (231865 => 231866)
--- trunk/Source/WebCore/testing/Internals.h 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/Source/WebCore/testing/Internals.h 2018-05-16 20:36:26 UTC (rev 231866)
@@ -670,6 +670,16 @@
bool usingAppleInternalSDK() const;
+ struct NowPlayingState {
+ String title;
+ double duration;
+ double elapsedTime;
+ uint64_t uniqueIdentifier;
+ bool hasActiveSession;
+ bool registeredAsNowPlayingApplication;
+ };
+ ExceptionOr<NowPlayingState> nowPlayingState() const;
+
private:
explicit Internals(Document&);
Document* contextDocument() const;
Modified: trunk/Source/WebCore/testing/Internals.idl (231865 => 231866)
--- trunk/Source/WebCore/testing/Internals.idl 2018-05-16 20:24:32 UTC (rev 231865)
+++ trunk/Source/WebCore/testing/Internals.idl 2018-05-16 20:36:26 UTC (rev 231866)
@@ -84,6 +84,19 @@
[
ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
+ Conditional=VIDEO,
+ JSGenerateToJSObject,
+] dictionary NowPlayingState {
+ boolean hasActiveSession;
+ boolean registeredAsNowPlayingApplication;
+ DOMString title;
+ unrestricted double duration;
+ unrestricted double elapsedTime;
+ unsigned long long uniqueIdentifier;
+};
+
+[
+ ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
NoInterfaceObject,
] interface Internals {
DOMString address(Node node);
@@ -601,4 +614,6 @@
DOMString extraZoomModeAdaptationName();
boolean usingAppleInternalSDK();
+
+ [Conditional=VIDEO, MayThrowException] readonly attribute NowPlayingState nowPlayingState;
};