Title: [203982] trunk
Revision
203982
Author
[email protected]
Date
2016-08-01 12:49:02 -0700 (Mon, 01 Aug 2016)

Log Message

[Mac][iOS] Adopt MediaRemote "seek to playback position"
https://bugs.webkit.org/show_bug.cgi?id=160405
<rdar://problem/27547583>

Reviewed by Dean Jackson.

Source/WebCore:

Test: media/remote-control-command-seek.html

* Modules/webaudio/AudioContext.h: Update for didReceiveRemoteControlCommand argument change.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::didReceiveRemoteControlCommand): Support SeekToPlaybackPositionCommand.
Drive by fix, support Stop command.
(WebCore::HTMLMediaElement::supportsSeeking): New.
* html/HTMLMediaElement.h:

* platform/RemoteCommandListener.h:
(WebCore::RemoteCommandListenerClient::didReceiveRemoteControlCommand): Add command argument.
(WebCore::RemoteCommandListenerClient::supportsSeeking): New.
(WebCore::RemoteCommandListener::updateSupportedCommands): Ditto.
(WebCore::RemoteCommandListener::client): Ditto.

* platform/audio/PlatformMediaSession.cpp:
(WebCore::PlatformMediaSession::didReceiveRemoteControlCommand): Add command argument.
(WebCore::PlatformMediaSession::supportsSeeking): New, pass through to client.
* platform/audio/PlatformMediaSession.h:

* platform/audio/PlatformMediaSessionManager.cpp:
(WebCore::PlatformMediaSessionManager::setCurrentSession): Tell remote command listener to
update supported commands.
(WebCore::PlatformMediaSessionManager::currentSession): Make const.
(WebCore::PlatformMediaSessionManager::didReceiveRemoteControlCommand): Add command argument.
(WebCore::PlatformMediaSessionManager::supportsSeeking): New, pass through to session.
* platform/audio/PlatformMediaSessionManager.h:

* platform/ios/RemoteCommandListenerIOS.h:
(WebCore::RemoteCommandListenerIOS::createWeakPtr):
* platform/ios/RemoteCommandListenerIOS.mm:
(WebCore::RemoteCommandListenerIOS::RemoteCommandListenerIOS): Support changePlaybackPositionCommand.
(WebCore::RemoteCommandListenerIOS::~RemoteCommandListenerIOS): Remove seekToTime target.
(WebCore::RemoteCommandListenerIOS::updateSupportedCommands): Update changePlaybackPositionCommand.

* platform/mac/MediaRemoteSoftLink.cpp:
* platform/mac/MediaRemoteSoftLink.h:

* platform/mac/RemoteCommandListenerMac.h:
* platform/mac/RemoteCommandListenerMac.mm:
(WebCore::RemoteCommandListenerMac::updateSupportedCommands): New, split out of constructor.
(WebCore::RemoteCommandListenerMac::RemoteCommandListenerMac): Split setup logic out into
updateSupportedCommands. Support MRMediaRemoteCommandSeekToPlaybackPosition. Don't assert when
receiving an unsupported command, it happens. Return error when a command isn't supported or
fails.

* testing/Internals.cpp:
(WebCore::Internals::postRemoteControlCommand): Add command argument parameter. Support
seektoplaybackposition.
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

* media/remote-control-command-seek-expected.txt: Added.
* media/remote-control-command-seek.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (203981 => 203982)


--- trunk/LayoutTests/ChangeLog	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/LayoutTests/ChangeLog	2016-08-01 19:49:02 UTC (rev 203982)
@@ -1,3 +1,14 @@
+2016-08-01  Eric Carlson  <[email protected]>
+
+        [Mac][iOS] Adopt MediaRemote "seek to playback position"
+        https://bugs.webkit.org/show_bug.cgi?id=160405
+        <rdar://problem/27547583>
+
+        Reviewed by Dean Jackson.
+
+        * media/remote-control-command-seek-expected.txt: Added.
+        * media/remote-control-command-seek.html: Added.
+
 2016-08-01  Adrian Perez de Castro  <[email protected]>
 
         Update Apache configuration for Arch Linux

Added: trunk/LayoutTests/media/remote-control-command-seek-expected.txt (0 => 203982)


--- trunk/LayoutTests/media/remote-control-command-seek-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/remote-control-command-seek-expected.txt	2016-08-01 19:49:02 UTC (rev 203982)
@@ -0,0 +1,14 @@
+Test that the "seekToPlaybackPosition" remote control command works.
+
+
+* set video.src
+EVENT(loadedmetadata)
+
+* Send a seek command.
+RUN(internals.postRemoteControlCommand('seekToPlaybackPosition', 1.6))
+
+EVENT(timeupdate)
+EXPECTED (video.currentTime.toFixed(1) == '1.6') OK
+
+END OF TEST
+

Added: trunk/LayoutTests/media/remote-control-command-seek.html (0 => 203982)


--- trunk/LayoutTests/media/remote-control-command-seek.html	                        (rev 0)
+++ trunk/LayoutTests/media/remote-control-command-seek.html	2016-08-01 19:49:02 UTC (rev 203982)
@@ -0,0 +1,44 @@
+<html>
+    <head>
+        <script src=""
+        <script src=""
+        <script>
+
+            function start()
+            {
+                if (!window.internals) {
+                    failTest('This test requires window.internals.');
+                    return;
+                }
+
+                findMediaElement();
+
+                waitForEvent('loadedmetadata', loadedmetadata, false, true, document)
+                waitForEvent('timeupdate', seeked)
+
+                consoleWrite('* set video.src');
+                video.src = "" 'content/test');
+            }
+
+            function loadedmetadata()
+            {
+                consoleWrite('<br>* Send a seek command.');
+                run("internals.postRemoteControlCommand('seekToPlaybackPosition', 1.6)");
+                consoleWrite('');
+            }
+
+            function seeked()
+            {
+                testExpected('video.currentTime.toFixed(1)', 1.6);
+                consoleWrite("");
+                endTest();
+            }
+
+        </script>
+    </head>
+
+    <body _onload_="start()">
+        <p>Test that the "seekToPlaybackPosition" remote control command works.</p>
+        <video controls></video>
+    </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (203981 => 203982)


--- trunk/Source/WebCore/ChangeLog	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/ChangeLog	2016-08-01 19:49:02 UTC (rev 203982)
@@ -1,3 +1,64 @@
+2016-08-01  Eric Carlson  <[email protected]>
+
+        [Mac][iOS] Adopt MediaRemote "seek to playback position"
+        https://bugs.webkit.org/show_bug.cgi?id=160405
+        <rdar://problem/27547583>
+
+        Reviewed by Dean Jackson.
+
+        Test: media/remote-control-command-seek.html
+
+        * Modules/webaudio/AudioContext.h: Update for didReceiveRemoteControlCommand argument change.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::didReceiveRemoteControlCommand): Support SeekToPlaybackPositionCommand.
+        Drive by fix, support Stop command.
+        (WebCore::HTMLMediaElement::supportsSeeking): New.
+        * html/HTMLMediaElement.h:
+
+        * platform/RemoteCommandListener.h:
+        (WebCore::RemoteCommandListenerClient::didReceiveRemoteControlCommand): Add command argument.
+        (WebCore::RemoteCommandListenerClient::supportsSeeking): New.
+        (WebCore::RemoteCommandListener::updateSupportedCommands): Ditto.
+        (WebCore::RemoteCommandListener::client): Ditto.
+
+        * platform/audio/PlatformMediaSession.cpp:
+        (WebCore::PlatformMediaSession::didReceiveRemoteControlCommand): Add command argument.
+        (WebCore::PlatformMediaSession::supportsSeeking): New, pass through to client.
+        * platform/audio/PlatformMediaSession.h:
+
+        * platform/audio/PlatformMediaSessionManager.cpp:
+        (WebCore::PlatformMediaSessionManager::setCurrentSession): Tell remote command listener to
+        update supported commands.
+        (WebCore::PlatformMediaSessionManager::currentSession): Make const.
+        (WebCore::PlatformMediaSessionManager::didReceiveRemoteControlCommand): Add command argument.
+        (WebCore::PlatformMediaSessionManager::supportsSeeking): New, pass through to session.
+        * platform/audio/PlatformMediaSessionManager.h:
+
+        * platform/ios/RemoteCommandListenerIOS.h:
+        (WebCore::RemoteCommandListenerIOS::createWeakPtr):
+        * platform/ios/RemoteCommandListenerIOS.mm:
+        (WebCore::RemoteCommandListenerIOS::RemoteCommandListenerIOS): Support changePlaybackPositionCommand.
+        (WebCore::RemoteCommandListenerIOS::~RemoteCommandListenerIOS): Remove seekToTime target.
+        (WebCore::RemoteCommandListenerIOS::updateSupportedCommands): Update changePlaybackPositionCommand.
+
+        * platform/mac/MediaRemoteSoftLink.cpp:
+        * platform/mac/MediaRemoteSoftLink.h:
+
+        * platform/mac/RemoteCommandListenerMac.h:
+        * platform/mac/RemoteCommandListenerMac.mm:
+        (WebCore::RemoteCommandListenerMac::updateSupportedCommands): New, split out of constructor.
+        (WebCore::RemoteCommandListenerMac::RemoteCommandListenerMac): Split setup logic out into
+        updateSupportedCommands. Support MRMediaRemoteCommandSeekToPlaybackPosition. Don't assert when
+        receiving an unsupported command, it happens. Return error when a command isn't supported or
+        fails.
+
+        * testing/Internals.cpp:
+        (WebCore::Internals::postRemoteControlCommand): Add command argument parameter. Support
+        seektoplaybackposition.
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2016-08-01  Anders Carlsson  <[email protected]>
 
         Freeze DOMHTMLTitleElement and DOMHTMLUListElement bindings

Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.h (203981 => 203982)


--- trunk/Source/WebCore/Modules/webaudio/AudioContext.h	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.h	2016-08-01 19:49:02 UTC (rev 203982)
@@ -314,7 +314,8 @@
     void mayResumePlayback(bool shouldResume) override;
     void suspendPlayback() override;
     bool canReceiveRemoteControlCommands() const override { return false; }
-    void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType) override { }
+    void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) override { }
+    bool supportsSeeking() const override { return false; }
     bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override { return false; }
 
     // EventTarget

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (203981 => 203982)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2016-08-01 19:49:02 UTC (rev 203982)
@@ -6837,7 +6837,7 @@
     return m_currentSrc;
 }
 
-void HTMLMediaElement::didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType command)
+void HTMLMediaElement::didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType command, const PlatformMediaSession::RemoteCommandArgument* argument)
 {
     LOG(Media, "HTMLMediaElement::didReceiveRemoteControlCommand(%p) - %i", this, static_cast<int>(command));
 
@@ -6846,6 +6846,7 @@
     case PlatformMediaSession::PlayCommand:
         play();
         break;
+    case PlatformMediaSession::StopCommand:
     case PlatformMediaSession::PauseCommand:
         pause();
         break;
@@ -6862,11 +6863,21 @@
     case PlatformMediaSession::EndSeekingForwardCommand:
         endScanning();
         break;
+    case PlatformMediaSession::SeekToPlaybackPositionCommand:
+        ASSERT(argument);
+        if (argument)
+            fastSeek(argument->asDouble);
+        break;
     default:
         { } // Do nothing
     }
 }
 
+bool HTMLMediaElement::supportsSeeking() const 
+{
+    return !isLiveStream();
+}
+
 bool HTMLMediaElement::shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType type) const
 {
     if (type == PlatformMediaSession::EnteringBackground) {

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (203981 => 203982)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2016-08-01 19:49:02 UTC (rev 203982)
@@ -616,7 +616,7 @@
 #endif
 
     bool mediaPlayerShouldWaitForResponseToAuthenticationChallenge(const AuthenticationChallenge&) override;
-    void mediaPlayerHandlePlaybackCommand(PlatformMediaSession::RemoteControlCommandType command) override { didReceiveRemoteControlCommand(command); }
+    void mediaPlayerHandlePlaybackCommand(PlatformMediaSession::RemoteControlCommandType command) override { didReceiveRemoteControlCommand(command, nullptr); }
     String mediaPlayerSourceApplicationIdentifier() const override;
     Vector<String> mediaPlayerPreferredAudioCharacteristics() const override;
 
@@ -757,7 +757,8 @@
     double mediaSessionDuration() const override { return duration(); }
     double mediaSessionCurrentTime() const override { return currentTime(); }
     bool canReceiveRemoteControlCommands() const override { return true; }
-    void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType) override;
+    void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) override;
+    bool supportsSeeking() const override;
     bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override;
     bool shouldOverrideBackgroundLoadingRestriction() const override;
 

Modified: trunk/Source/WebCore/platform/RemoteCommandListener.h (203981 => 203982)


--- trunk/Source/WebCore/platform/RemoteCommandListener.h	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/RemoteCommandListener.h	2016-08-01 19:49:02 UTC (rev 203982)
@@ -34,7 +34,8 @@
     WTF_MAKE_FAST_ALLOCATED;
 public:
     virtual ~RemoteCommandListenerClient() { }
-    virtual void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType) = 0;
+    virtual void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) = 0;
+    virtual bool supportsSeeking() const = 0;
 };
 
 class RemoteCommandListener {
@@ -43,6 +44,10 @@
     RemoteCommandListener(RemoteCommandListenerClient& client) : m_client(client) { }
     virtual ~RemoteCommandListener() { }
 
+    virtual void updateSupportedCommands() { }
+
+    RemoteCommandListenerClient& client() const { return m_client; }
+
 protected:
     RemoteCommandListenerClient& m_client;
 };

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp (203981 => 203982)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp	2016-08-01 19:49:02 UTC (rev 203982)
@@ -242,11 +242,16 @@
     return m_client.canReceiveRemoteControlCommands();
 }
 
-void PlatformMediaSession::didReceiveRemoteControlCommand(RemoteControlCommandType command)
+void PlatformMediaSession::didReceiveRemoteControlCommand(RemoteControlCommandType command, const PlatformMediaSession::RemoteCommandArgument* argument)
 {
-    m_client.didReceiveRemoteControlCommand(command);
+    m_client.didReceiveRemoteControlCommand(command, argument);
 }
 
+bool PlatformMediaSession::supportsSeeking() const
+{
+    return m_client.supportsSeeking();
+}
+
 void PlatformMediaSession::visibilityChanged()
 {
     scheduleClientDataBufferingCheck();

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.h (203981 => 203982)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.h	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.h	2016-08-01 19:49:02 UTC (rev 203982)
@@ -114,6 +114,10 @@
     double currentTime() const;
 #endif
 
+    typedef union {
+        double asDouble;
+    } RemoteCommandArgument;
+
     enum RemoteControlCommandType {
         NoCommand,
         PlayCommand,
@@ -124,9 +128,11 @@
         EndSeekingBackwardCommand,
         BeginSeekingForwardCommand,
         EndSeekingForwardCommand,
+        SeekToPlaybackPositionCommand,
     };
     bool canReceiveRemoteControlCommands() const;
-    void didReceiveRemoteControlCommand(RemoteControlCommandType);
+    void didReceiveRemoteControlCommand(RemoteControlCommandType, const RemoteCommandArgument* argument = nullptr);
+    bool supportsSeeking() const;
 
     enum DisplayType {
         Normal,
@@ -202,7 +208,8 @@
 #endif
     
     virtual bool canReceiveRemoteControlCommands() const = 0;
-    virtual void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType) = 0;
+    virtual void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) = 0;
+    virtual bool supportsSeeking() const = 0;
 
     virtual void setShouldBufferData(bool) { }
     virtual bool elementIsHidden() const { return false; }

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (203981 => 203982)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2016-08-01 19:49:02 UTC (rev 203982)
@@ -266,11 +266,13 @@
 
     m_sessions.remove(index);
     m_sessions.insert(0, &session);
+    if (m_remoteCommandListener)
+        m_remoteCommandListener->updateSupportedCommands();
     
     LOG(Media, "PlatformMediaSessionManager::setCurrentSession - session moved from index %zu to 0", index);
 }
     
-PlatformMediaSession* PlatformMediaSessionManager::currentSession()
+PlatformMediaSession* PlatformMediaSessionManager::currentSession() const
 {
     if (!m_sessions.size())
         return nullptr;
@@ -344,14 +346,22 @@
 }
 #endif
 
-void PlatformMediaSessionManager::didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType command)
+void PlatformMediaSessionManager::didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType command, const PlatformMediaSession::RemoteCommandArgument* argument)
 {
     PlatformMediaSession* activeSession = currentSession();
     if (!activeSession || !activeSession->canReceiveRemoteControlCommands())
         return;
-    activeSession->didReceiveRemoteControlCommand(command);
+    activeSession->didReceiveRemoteControlCommand(command, argument);
 }
 
+bool PlatformMediaSessionManager::supportsSeeking() const
+{
+    PlatformMediaSession* activeSession = currentSession();
+    if (!activeSession)
+        return false;
+    return activeSession->supportsSeeking();
+}
+
 void PlatformMediaSessionManager::systemWillSleep()
 {
     if (m_interrupted)

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (203981 => 203982)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2016-08-01 19:49:02 UTC (rev 203982)
@@ -90,7 +90,7 @@
 #endif
 
     void setCurrentSession(PlatformMediaSession&);
-    PlatformMediaSession* currentSession();
+    PlatformMediaSession* currentSession() const;
 
     PlatformMediaSession* currentSessionMatching(std::function<bool(const PlatformMediaSession&)>);
 
@@ -112,7 +112,8 @@
     void updateSessionState();
 
     // RemoteCommandListenerClient
-    WEBCORE_EXPORT void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType) override;
+    WEBCORE_EXPORT void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) override;
+    WEBCORE_EXPORT bool supportsSeeking() const override;
 
     // AudioHardwareListenerClient
     void audioHardwareDidBecomeActive() override { }

Modified: trunk/Source/WebCore/platform/ios/RemoteCommandListenerIOS.h (203981 => 203982)


--- trunk/Source/WebCore/platform/ios/RemoteCommandListenerIOS.h	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/ios/RemoteCommandListenerIOS.h	2016-08-01 19:49:02 UTC (rev 203982)
@@ -46,7 +46,8 @@
 
 protected:
     WeakPtr<RemoteCommandListenerIOS> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
-    
+    void updateSupportedCommands() override;
+
     WeakPtrFactory<RemoteCommandListenerIOS> m_weakPtrFactory;
     RetainPtr<id> m_playTarget;
     RetainPtr<id> m_pauseTarget;
@@ -53,6 +54,7 @@
     RetainPtr<id> m_togglePlayPauseTarget;
     RetainPtr<id> m_seekForwardTarget;
     RetainPtr<id> m_seekBackwardTarget;
+    RetainPtr<id> m_seekToTimeTarget;
 };
 
 }

Modified: trunk/Source/WebCore/platform/ios/RemoteCommandListenerIOS.mm (203981 => 203982)


--- trunk/Source/WebCore/platform/ios/RemoteCommandListenerIOS.mm	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/ios/RemoteCommandListenerIOS.mm	2016-08-01 19:49:02 UTC (rev 203982)
@@ -36,6 +36,9 @@
 SOFT_LINK_FRAMEWORK(MediaPlayer)
 SOFT_LINK_CLASS(MediaPlayer, MPRemoteCommandCenter)
 SOFT_LINK_CLASS(MediaPlayer, MPSeekCommandEvent)
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100
+SOFT_LINK_CLASS(MediaPlayer, MPChangePlaybackPositionCommandEvent)
+#endif
 
 namespace WebCore {
 
@@ -55,7 +58,7 @@
         callOnMainThread([weakThis] {
             if (!weakThis)
                 return;
-            weakThis->m_client.didReceiveRemoteControlCommand(PlatformMediaSession::PauseCommand);
+            weakThis->m_client.didReceiveRemoteControlCommand(PlatformMediaSession::PauseCommand, nullptr);
         });
 
         return MPRemoteCommandHandlerStatusSuccess;
@@ -65,7 +68,7 @@
         callOnMainThread([weakThis] {
             if (!weakThis)
                 return;
-            weakThis->m_client.didReceiveRemoteControlCommand(PlatformMediaSession::PlayCommand);
+            weakThis->m_client.didReceiveRemoteControlCommand(PlatformMediaSession::PlayCommand, nullptr);
         });
 
         return MPRemoteCommandHandlerStatusSuccess;
@@ -75,7 +78,7 @@
         callOnMainThread([weakThis] {
             if (!weakThis)
                 return;
-            weakThis->m_client.didReceiveRemoteControlCommand(PlatformMediaSession::TogglePlayPauseCommand);
+            weakThis->m_client.didReceiveRemoteControlCommand(PlatformMediaSession::TogglePlayPauseCommand, nullptr);
         });
 
         return MPRemoteCommandHandlerStatusSuccess;
@@ -90,7 +93,7 @@
         callOnMainThread([weakThis, command] {
             if (!weakThis)
                 return;
-            weakThis->m_client.didReceiveRemoteControlCommand(command);
+            weakThis->m_client.didReceiveRemoteControlCommand(command, nullptr);
         });
 
         return MPRemoteCommandHandlerStatusSuccess;
@@ -105,11 +108,31 @@
         callOnMainThread([weakThis, command] {
             if (!weakThis)
                 return;
-            weakThis->m_client.didReceiveRemoteControlCommand(command);
+            weakThis->m_client.didReceiveRemoteControlCommand(command, nullptr);
         });
 
         return MPRemoteCommandHandlerStatusSuccess;
     }];
+
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100
+    m_seekToTimeTarget = [[center changePlaybackPositionCommand] addTargetWithHandler:^(MPRemoteCommandEvent *event) {
+        ASSERT([event isKindOfClass:getMPChangePlaybackPositionCommandEventClass()]);
+
+        if (!client.supportsSeeking())
+            return MPRemoteCommandHandlerStatusCommandFailed;
+
+        MPChangePlaybackPositionCommandEvent* seekEvent = static_cast<MPChangePlaybackPositionCommandEvent *>(event);
+        PlatformMediaSession::RemoteCommandArgument argument { [seekEvent positionTime] };
+
+        callOnMainThread([weakThis, argument] {
+            if (!weakThis)
+                return;
+            weakThis->m_client.didReceiveRemoteControlCommand(PlatformMediaSession::TogglePlayPauseCommand, &argument);
+        });
+
+        return MPRemoteCommandHandlerStatusSuccess;
+    }];
+#endif
 }
 
 RemoteCommandListenerIOS::~RemoteCommandListenerIOS()
@@ -120,8 +143,18 @@
     [[center togglePlayPauseCommand] removeTarget:m_togglePlayPauseTarget.get()];
     [[center seekForwardCommand] removeTarget:m_seekForwardTarget.get()];
     [[center seekBackwardCommand] removeTarget:m_seekBackwardTarget.get()];
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100
+    [[center changePlaybackPositionCommand] removeTarget:m_seekToTimeTarget.get()];
+#endif
 }
 
+void RemoteCommandListenerIOS::updateSupportedCommands()
+{
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100
+    [[[getMPRemoteCommandCenterClass() sharedCommandCenter] changePlaybackPositionCommand] setEnabled:!!client().supportsSeeking()];
+#endif
 }
 
+}
+
 #endif

Modified: trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.cpp (203981 => 203982)


--- trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.cpp	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.cpp	2016-08-01 19:49:02 UTC (rev 203982)
@@ -46,5 +46,6 @@
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfoDuration, CFStringRef);
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfoElapsedTime, CFStringRef);
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfoPlaybackRate, CFStringRef);
+SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteOptionPlaybackPosition, CFStringRef);
 
 #endif // USE(MEDIAREMOTE)

Modified: trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.h (203981 => 203982)


--- trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.h	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.h	2016-08-01 19:49:02 UTC (rev 203982)
@@ -61,5 +61,7 @@
 #define kMRMediaRemoteNowPlayingInfoElapsedTime get_MediaRemote_kMRMediaRemoteNowPlayingInfoElapsedTime()
 SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfoPlaybackRate, CFStringRef);
 #define kMRMediaRemoteNowPlayingInfoPlaybackRate get_MediaRemote_kMRMediaRemoteNowPlayingInfoPlaybackRate()
+SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, MediaRemote, kMRMediaRemoteOptionPlaybackPosition, CFStringRef);
+#define kMRMediaRemoteOptionPlaybackPosition get_MediaRemote_kMRMediaRemoteOptionPlaybackPosition()
 
 #endif // USE(MEDIAREMOTE)

Modified: trunk/Source/WebCore/platform/mac/RemoteCommandListenerMac.h (203981 => 203982)


--- trunk/Source/WebCore/platform/mac/RemoteCommandListenerMac.h	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/mac/RemoteCommandListenerMac.h	2016-08-01 19:49:02 UTC (rev 203982)
@@ -42,6 +42,8 @@
 protected:
     WeakPtr<RemoteCommandListenerMac> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
 
+    void updateSupportedCommands() override;
+
     WeakPtrFactory<RemoteCommandListenerMac> m_weakPtrFactory { this };
     void* m_commandHandler { nullptr };
 };

Modified: trunk/Source/WebCore/platform/mac/RemoteCommandListenerMac.mm (203981 => 203982)


--- trunk/Source/WebCore/platform/mac/RemoteCommandListenerMac.mm	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/platform/mac/RemoteCommandListenerMac.mm	2016-08-01 19:49:02 UTC (rev 203982)
@@ -40,8 +40,7 @@
     return std::make_unique<RemoteCommandListenerMac>(client);
 }
 
-RemoteCommandListenerMac::RemoteCommandListenerMac(RemoteCommandListenerClient& client)
-    : RemoteCommandListener(client)
+void RemoteCommandListenerMac::updateSupportedCommands()
 {
 #if USE(MEDIAREMOTE)
     if (!isMediaRemoteFrameworkAvailable())
@@ -66,13 +65,32 @@
         CFArrayAppendValue(commandInfoArray.get(), commandInfo.get());
     }
 
+    auto seekCommandInfo = adoptCF(MRMediaRemoteCommandInfoCreate(kCFAllocatorDefault));
+    MRMediaRemoteCommandInfoSetCommand(seekCommandInfo.get(), MRMediaRemoteCommandSeekToPlaybackPosition);
+    MRMediaRemoteCommandInfoSetEnabled(seekCommandInfo.get(), client().supportsSeeking());
+    CFArrayAppendValue(commandInfoArray.get(), seekCommandInfo.get());
+
     MRMediaRemoteSetSupportedCommands(commandInfoArray.get(), MRMediaRemoteGetLocalOrigin(), nullptr, nullptr);
+#endif // USE(MEDIAREMOTE)
+}
 
+RemoteCommandListenerMac::RemoteCommandListenerMac(RemoteCommandListenerClient& client)
+    : RemoteCommandListener(client)
+{
+#if USE(MEDIAREMOTE)
+    if (!isMediaRemoteFrameworkAvailable())
+        return;
+
+    updateSupportedCommands();
+
     auto weakThis = createWeakPtr();
     m_commandHandler = MRMediaRemoteAddAsyncCommandHandlerBlock(^(MRMediaRemoteCommand command, CFDictionaryRef options, void(^completion)(CFArrayRef)) {
-        UNUSED_PARAM(options);
 
+        LOG(Media, "RemoteCommandListenerMac::RemoteCommandListenerMac - received command %u", command);
+
         PlatformMediaSession::RemoteControlCommandType platformCommand { PlatformMediaSession::NoCommand };
+        PlatformMediaSession::RemoteCommandArgument argument { 0 };
+        MRMediaRemoteCommandHandlerStatus status = MRMediaRemoteCommandHandlerStatusSuccess;
 
         switch (command) {
         case MRMediaRemoteCommandPlay:
@@ -81,6 +99,9 @@
         case MRMediaRemoteCommandPause:
             platformCommand = PlatformMediaSession::PauseCommand;
             break;
+        case MRMediaRemoteCommandStop:
+            platformCommand = PlatformMediaSession::StopCommand;
+            break;
         case MRMediaRemoteCommandTogglePlayPause:
             platformCommand = PlatformMediaSession::TogglePlayPauseCommand;
             break;
@@ -96,14 +117,32 @@
         case MRMediaRemoteCommandEndRewind:
             platformCommand = PlatformMediaSession::EndSeekingBackwardCommand;
             break;
+        case MRMediaRemoteCommandSeekToPlaybackPosition: {
+            if (!client.supportsSeeking()) {
+                status = MRMediaRemoteCommandHandlerStatusCommandFailed;
+                break;
+            }
+
+            CFNumberRef positionRef = static_cast<CFNumberRef>(CFDictionaryGetValue(options, kMRMediaRemoteOptionPlaybackPosition));
+            if (!positionRef) {
+                status = MRMediaRemoteCommandHandlerStatusCommandFailed;
+                break;
+            }
+
+            CFNumberGetValue(positionRef, kCFNumberDoubleType, &argument.asDouble);
+            platformCommand = PlatformMediaSession::SeekToPlaybackPositionCommand;
+            break;
+        }
         default:
-            ASSERT_NOT_REACHED();
+            LOG(Media, "RemoteCommandListenerMac::RemoteCommandListenerMac - command %u not supported!", command);
+            status = MRMediaRemoteCommandHandlerStatusCommandFailed;
+            return;
         };
 
         if (!weakThis)
             return;
-        weakThis->m_client.didReceiveRemoteControlCommand(platformCommand);
-        completion(static_cast<CFArrayRef>(@[@0]));
+        weakThis->m_client.didReceiveRemoteControlCommand(platformCommand, &argument);
+        completion(static_cast<CFArrayRef>(@[@(status)]));
     });
 #endif // USE(MEDIAREMOTE)
 }

Modified: trunk/Source/WebCore/testing/Internals.cpp (203981 => 203982)


--- trunk/Source/WebCore/testing/Internals.cpp	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/testing/Internals.cpp	2016-08-01 19:49:02 UTC (rev 203982)
@@ -2880,10 +2880,11 @@
     element.mediaSession().addBehaviorRestriction(restrictions);
 }
 
-void Internals::postRemoteControlCommand(const String& commandString, ExceptionCode& ec)
+void Internals::postRemoteControlCommand(const String& commandString, float argument, ExceptionCode& ec)
 {
     PlatformMediaSession::RemoteControlCommandType command;
-    
+    PlatformMediaSession::RemoteCommandArgument parameter { argument };
+
     if (equalLettersIgnoringASCIICase(commandString, "play"))
         command = PlatformMediaSession::PlayCommand;
     else if (equalLettersIgnoringASCIICase(commandString, "pause"))
@@ -2900,12 +2901,14 @@
         command = PlatformMediaSession::BeginSeekingForwardCommand;
     else if (equalLettersIgnoringASCIICase(commandString, "endseekingforward"))
         command = PlatformMediaSession::EndSeekingForwardCommand;
+    else if (equalLettersIgnoringASCIICase(commandString, "seektoplaybackposition"))
+        command = PlatformMediaSession::SeekToPlaybackPositionCommand;
     else {
         ec = INVALID_ACCESS_ERR;
         return;
     }
     
-    PlatformMediaSessionManager::sharedManager().didReceiveRemoteControlCommand(command);
+    PlatformMediaSessionManager::sharedManager().didReceiveRemoteControlCommand(command, &parameter);
 }
 
 bool Internals::elementIsBlockingDisplaySleep(HTMLMediaElement& element) const

Modified: trunk/Source/WebCore/testing/Internals.h (203981 => 203982)


--- trunk/Source/WebCore/testing/Internals.h	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/testing/Internals.h	2016-08-01 19:49:02 UTC (rev 203982)
@@ -411,7 +411,7 @@
     void applicationWillEnterBackground() const;
     void setMediaSessionRestrictions(const String& mediaType, const String& restrictions, ExceptionCode&);
     void setMediaElementRestrictions(HTMLMediaElement&, const String& restrictions);
-    void postRemoteControlCommand(const String&, ExceptionCode&);
+    void postRemoteControlCommand(const String&, float argument, ExceptionCode&);
     bool elementIsBlockingDisplaySleep(HTMLMediaElement&) const;
 #endif
 

Modified: trunk/Source/WebCore/testing/Internals.idl (203981 => 203982)


--- trunk/Source/WebCore/testing/Internals.idl	2016-08-01 19:35:11 UTC (rev 203981)
+++ trunk/Source/WebCore/testing/Internals.idl	2016-08-01 19:49:02 UTC (rev 203982)
@@ -406,7 +406,7 @@
     [Conditional=VIDEO, RaisesException] void setMediaSessionRestrictions(DOMString mediaType, DOMString restrictions);
     [Conditional=VIDEO] void setMediaElementRestrictions(HTMLMediaElement element, DOMString restrictions);
     [Conditional=WEB_AUDIO] void setAudioContextRestrictions(AudioContext context, DOMString restrictions);
-    [Conditional=VIDEO, RaisesException] void postRemoteControlCommand(DOMString command);
+    [Conditional=VIDEO, RaisesException] void postRemoteControlCommand(DOMString command, optional unrestricted float argument = 0);
     [Conditional=WIRELESS_PLAYBACK_TARGET] void setMockMediaPlaybackTargetPickerEnabled(boolean enabled);
     [Conditional=WIRELESS_PLAYBACK_TARGET, RaisesException] void setMockMediaPlaybackTargetPickerState(DOMString deviceName, DOMString deviceState);
     [Conditional=MEDIA_STREAM] void setMockMediaCaptureDevicesEnabled(boolean enabled);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to