Title: [231866] trunk
Revision
231866
Author
eric.carl...@apple.com
Date
2018-05-16 13:36:26 -0700 (Wed, 16 May 2018)

Log Message

Improve NowPlaying "title"
https://bugs.webkit.org/show_bug.cgi?id=185680
<rdar://problem/40296700>

Reviewed by Jer Noble.
Source/WebCore:

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:

LayoutTests:

* 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:

Modified Paths

Added Paths

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;
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to