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, ¶meter);
}
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);