Title: [273967] trunk/Source
Revision
273967
Author
[email protected]
Date
2021-03-05 07:50:23 -0800 (Fri, 05 Mar 2021)

Log Message

[GPU Process] Remote control command should only go to the current NowPlaying session
https://bugs.webkit.org/show_bug.cgi?id=222759
<rdar://problem/75053393>

Reviewed by Jer Noble.

Source/WebCore:

Don't register a remote command listener for every web process, or every remote control
commands will go to every web process. Instead, register a single listener for the
GPU process and route commands to only the current NowPlaying process.

Tested manually.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::didReceiveRemoteControlCommand): Drive-by: SkipForward
and SkipBackwards should seek relative to current time.

* platform/NowPlayingManager.cpp:
(WebCore::NowPlayingManager::setSupportedRemoteCommands): New, pass through to the
command listener.
* platform/NowPlayingManager.h:

* platform/RemoteCommandListener.cpp:
(WebCore::RemoteCommandListener::addSupportedCommand): m_registeredCommands -> m_supportedCommands.
(WebCore::RemoteCommandListener::removeSupportedCommand): Ditto.
(WebCore::RemoteCommandListener::setSupportedCommands): Ditto. Schedule update.
(WebCore::RemoteCommandListener::updateSupportedCommands):
* platform/RemoteCommandListener.h:

* platform/audio/NowPlayingInfo.h:
(WebCore::NowPlayingInfo::operator== const): Add operator so we can avoid updating
when nothing has changed.
(WebCore::NowPlayingInfo::operator!= const):

* platform/audio/cocoa/MediaSessionManagerCocoa.h:
* platform/audio/cocoa/MediaSessionManagerCocoa.mm:
(WebCore::MediaSessionManagerCocoa::setNowPlayingInfo): Always set string properties
so we don't show stale information after switching to a session that doesn't provide
all of the same properties.
(WebCore::MediaSessionManagerCocoa::updateNowPlayingInfo): Only update when we have
new state.

* platform/mac/MediaRemoteSoftLink.h:
* platform/mac/MediaRemoteSoftLink.mm: Soft link kMRMediaRemoteCommandInfoPreferredIntervalsKey.

Source/WebKit:

* GPUProcess/GPUConnectionToWebProcess.cpp:
(WebKit::GPUConnectionToWebProcess::clearNowPlayingInfo): Track being the active
NowPlaying process.
(WebKit::GPUConnectionToWebProcess::setNowPlayingInfo): Ditto.
(WebKit::GPUConnectionToWebProcess::updateSupportedRemoteCommands): Pass supported
commands and seeking to NowPlayingManager so it can pass them to the remote command
listener.
(WebKit::GPUConnectionToWebProcess::createRemoteCommandListener): We only ever need
one listener.
(WebKit::GPUConnectionToWebProcess::releaseRemoteCommandListener): Ditto.
(WebKit::GPUConnectionToWebProcess::dispatchMessage): Dispatch RemoteRemoteCommandListenerProxy
messages.
* GPUProcess/GPUConnectionToWebProcess.h:

* GPUProcess/media/RemoteRemoteCommandListenerProxy.cpp:
(WebKit::RemoteRemoteCommandListenerProxy::RemoteRemoteCommandListenerProxy): Don't
create a remote command listener, we only need one for the GPU process.
(WebKit::RemoteRemoteCommandListenerProxy::updateSupportedCommands): New.
(WebKit::RemoteRemoteCommandListenerProxy::didReceiveRemoteControlCommand): Deleted.
* GPUProcess/media/RemoteRemoteCommandListenerProxy.h:
(WebKit::RemoteRemoteCommandListenerProxy::create):
(WebKit::RemoteRemoteCommandListenerProxy::supportsSeeking const):
(WebKit::RemoteRemoteCommandListenerProxy::supportedCommands const):
(WebKit::RemoteRemoteCommandListenerProxy::identifier const):
* GPUProcess/media/RemoteRemoteCommandListenerProxy.messages.in:

* WebProcess/GPU/media/RemoteRemoteCommandListener.cpp:
(WebKit::RemoteRemoteCommandListener::RemoteRemoteCommandListener): Use m_process
instead of calling WebProcess::singleton().
(WebKit::RemoteRemoteCommandListener::~RemoteRemoteCommandListener): Ditto.
(WebKit::RemoteRemoteCommandListener::didReceiveRemoteControlCommand): Use client(),
m_client is now private.
(WebKit::RemoteRemoteCommandListener::updateSupportedCommands):
* WebProcess/GPU/media/RemoteRemoteCommandListener.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (273966 => 273967)


--- trunk/Source/WebCore/ChangeLog	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/ChangeLog	2021-03-05 15:50:23 UTC (rev 273967)
@@ -1,3 +1,49 @@
+2021-03-05  Eric Carlson  <[email protected]>
+
+        [GPU Process] Remote control command should only go to the current NowPlaying session
+        https://bugs.webkit.org/show_bug.cgi?id=222759
+        <rdar://problem/75053393>
+
+        Reviewed by Jer Noble.
+
+        Don't register a remote command listener for every web process, or every remote control
+        commands will go to every web process. Instead, register a single listener for the
+        GPU process and route commands to only the current NowPlaying process.
+
+        Tested manually.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::didReceiveRemoteControlCommand): Drive-by: SkipForward
+        and SkipBackwards should seek relative to current time.
+
+        * platform/NowPlayingManager.cpp:
+        (WebCore::NowPlayingManager::setSupportedRemoteCommands): New, pass through to the
+        command listener.
+        * platform/NowPlayingManager.h:
+
+        * platform/RemoteCommandListener.cpp:
+        (WebCore::RemoteCommandListener::addSupportedCommand): m_registeredCommands -> m_supportedCommands.
+        (WebCore::RemoteCommandListener::removeSupportedCommand): Ditto.
+        (WebCore::RemoteCommandListener::setSupportedCommands): Ditto. Schedule update.
+        (WebCore::RemoteCommandListener::updateSupportedCommands):
+        * platform/RemoteCommandListener.h:
+
+        * platform/audio/NowPlayingInfo.h:
+        (WebCore::NowPlayingInfo::operator== const): Add operator so we can avoid updating
+        when nothing has changed.
+        (WebCore::NowPlayingInfo::operator!= const):
+
+        * platform/audio/cocoa/MediaSessionManagerCocoa.h:
+        * platform/audio/cocoa/MediaSessionManagerCocoa.mm:
+        (WebCore::MediaSessionManagerCocoa::setNowPlayingInfo): Always set string properties
+        so we don't show stale information after switching to a session that doesn't provide
+        all of the same properties.
+        (WebCore::MediaSessionManagerCocoa::updateNowPlayingInfo): Only update when we have
+        new state.
+
+        * platform/mac/MediaRemoteSoftLink.h:
+        * platform/mac/MediaRemoteSoftLink.mm: Soft link kMRMediaRemoteCommandInfoPreferredIntervalsKey.
+
 2021-03-05  Chris Dumez  <[email protected]>
 
         Reduce use of CFRetain() / CFRelease() / CFAutoRelease() in WebKit

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (273966 => 273967)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2021-03-05 15:50:23 UTC (rev 273967)
@@ -7539,12 +7539,16 @@
     case PlatformMediaSession::EndSeekingForwardCommand:
         endScanning();
         break;
-    case PlatformMediaSession::SkipForwardCommand:
-        handleSeekToPlaybackPosition(argument.time ? argument.time.value() : defaultSkipAmount);
+    case PlatformMediaSession::SkipForwardCommand: {
+        auto delta = argument.time ? argument.time.value() : defaultSkipAmount;
+        handleSeekToPlaybackPosition(std::min(currentTime() + delta, duration()));
         break;
-    case PlatformMediaSession::SkipBackwardCommand:
-        handleSeekToPlaybackPosition(0 - (argument.time ? argument.time.value() : defaultSkipAmount));
+    }
+    case PlatformMediaSession::SkipBackwardCommand: {
+        auto delta = argument.time ? argument.time.value() : defaultSkipAmount;
+        handleSeekToPlaybackPosition(std::max(currentTime() - delta, 0.));
         break;
+    }
     case PlatformMediaSession::SeekToPlaybackPositionCommand:
         ASSERT(argument.time);
         if (argument.time)

Modified: trunk/Source/WebCore/platform/NowPlayingManager.cpp (273966 => 273967)


--- trunk/Source/WebCore/platform/NowPlayingManager.cpp	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/NowPlayingManager.cpp	2021-03-05 15:50:23 UTC (rev 273967)
@@ -74,4 +74,13 @@
 #endif
 }
 
+void NowPlayingManager::setSupportedRemoteCommands(const RemoteCommandListener::RemoteCommandsSet& commands, bool supportsSeeking)
+{
+    if (!m_remoteCommandListener)
+        return;
+
+    m_remoteCommandListener->setSupportsSeeking(supportsSeeking);
+    m_remoteCommandListener->setSupportedCommands(commands);
 }
+
+}

Modified: trunk/Source/WebCore/platform/NowPlayingManager.h (273966 => 273967)


--- trunk/Source/WebCore/platform/NowPlayingManager.h	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/NowPlayingManager.h	2021-03-05 15:50:23 UTC (rev 273967)
@@ -50,6 +50,7 @@
 
     void clearNowPlayingInfoClient(Client&);
     void setNowPlayingInfo(Client&, NowPlayingInfo&&);
+    void setSupportedRemoteCommands(const RemoteCommandListener::RemoteCommandsSet&, bool);
 
 private:
     std::unique_ptr<RemoteCommandListener> m_remoteCommandListener;

Modified: trunk/Source/WebCore/platform/RemoteCommandListener.cpp (273966 => 273967)


--- trunk/Source/WebCore/platform/RemoteCommandListener.cpp	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/RemoteCommandListener.cpp	2021-03-05 15:50:23 UTC (rev 273967)
@@ -89,14 +89,35 @@
 
 void RemoteCommandListener::addSupportedCommand(PlatformMediaSession::RemoteControlCommandType command)
 {
-    m_registeredCommands.add(command);
+    m_supportedCommands.add(command);
     scheduleSupportedCommandsUpdate();
 }
 
 void RemoteCommandListener::removeSupportedCommand(PlatformMediaSession::RemoteControlCommandType command)
 {
-    m_registeredCommands.remove(command);
+    m_supportedCommands.remove(command);
     scheduleSupportedCommandsUpdate();
 }
 
+void RemoteCommandListener::setSupportedCommands(const RemoteCommandsSet& commands)
+{
+    m_supportedCommands = commands;
+    scheduleSupportedCommandsUpdate();
 }
+
+void RemoteCommandListener::updateSupportedCommands()
+{
+    ASSERT_NOT_REACHED();
+}
+
+const RemoteCommandListener::RemoteCommandsSet& RemoteCommandListener::supportedCommands() const
+{
+    return m_supportedCommands;
+}
+
+bool RemoteCommandListener::supportsSeeking() const
+{
+    return m_supportsSeeking;
+}
+
+}

Modified: trunk/Source/WebCore/platform/RemoteCommandListener.h (273966 => 273967)


--- trunk/Source/WebCore/platform/RemoteCommandListener.h	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/RemoteCommandListener.h	2021-03-05 15:50:23 UTC (rev 273967)
@@ -51,20 +51,24 @@
 
     void addSupportedCommand(PlatformMediaSession::RemoteControlCommandType);
     void removeSupportedCommand(PlatformMediaSession::RemoteControlCommandType);
-    virtual void updateSupportedCommands() { }
+
+    using RemoteCommandsSet = HashSet<PlatformMediaSession::RemoteControlCommandType, WTF::IntHash<PlatformMediaSession::RemoteControlCommandType>, WTF::StrongEnumHashTraits<PlatformMediaSession::RemoteControlCommandType>>;
+    void setSupportedCommands(const RemoteCommandsSet&);
+    const RemoteCommandsSet& supportedCommands() const;
+
+    virtual void updateSupportedCommands();
     void scheduleSupportedCommandsUpdate();
+
     void setSupportsSeeking(bool);
+    bool supportsSeeking() const;
 
     RemoteCommandListenerClient& client() const { return m_client; }
 
-protected:
+private:
     RemoteCommandListenerClient& m_client;
-
-    using RemoteCommandsSet = HashSet<PlatformMediaSession::RemoteControlCommandType, WTF::IntHash<PlatformMediaSession::RemoteControlCommandType>, WTF::StrongEnumHashTraits<PlatformMediaSession::RemoteControlCommandType>>;
-    RemoteCommandsSet m_registeredCommands;
+    RemoteCommandsSet m_supportedCommands;
+    DeferrableTask<Timer> m_updateCommandsTask;
     bool m_supportsSeeking { false };
-
-    DeferrableTask<Timer> m_updateCommandsTask;
 };
 
 }

Modified: trunk/Source/WebCore/platform/audio/NowPlayingInfo.h (273966 => 273967)


--- trunk/Source/WebCore/platform/audio/NowPlayingInfo.h	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/audio/NowPlayingInfo.h	2021-03-05 15:50:23 UTC (rev 273967)
@@ -42,6 +42,25 @@
     bool isPlaying { false };
     bool allowsNowPlayingControlsVisibility { false };
 
+    bool operator==(const NowPlayingInfo& other) const
+    {
+        return title == other.title
+            && artist == other.artist
+            && album == other.album
+            && sourceApplicationIdentifier == other.sourceApplicationIdentifier
+            && duration == other.duration
+            && currentTime == other.currentTime
+            && supportsSeeking == other.supportsSeeking
+            && uniqueIdentifier == other.uniqueIdentifier
+            && isPlaying == other.isPlaying
+            && allowsNowPlayingControlsVisibility == other.allowsNowPlayingControlsVisibility;
+    }
+
+    bool operator!=(const NowPlayingInfo other) const
+    {
+        return !(*this == other);
+    }
+
     template<class Encoder> void encode(Encoder&) const;
     template<class Decoder> static Optional<NowPlayingInfo> decode(Decoder&);
 };

Modified: trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h (273966 => 273967)


--- trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h	2021-03-05 15:50:23 UTC (rev 273967)
@@ -29,6 +29,7 @@
 
 #include "AudioHardwareListener.h"
 #include "GenericTaskQueue.h"
+#include "NowPlayingInfo.h"
 #include "PlatformMediaSessionManager.h"
 #include "RemoteCommandListener.h"
 
@@ -98,6 +99,7 @@
     void audioHardwareDidBecomeInactive() final { }
     void audioOutputDeviceChanged() final;
 
+    Optional<NowPlayingInfo> m_nowPlayingInfo;
     bool m_nowPlayingActive { false };
     bool m_registeredAsNowPlayingApplication { false };
     bool m_haveEverRegisteredAsNowPlayingApplication { false };

Modified: trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm (273966 => 273967)


--- trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm	2021-03-05 15:50:23 UTC (rev 273967)
@@ -286,15 +286,10 @@
 
     auto info = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
 
-    if (!nowPlayingInfo.artist.isEmpty())
-        CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoArtist, nowPlayingInfo.artist.createCFString().get());
+    CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoArtist, nowPlayingInfo.artist.createCFString().get());
+    CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoAlbum, nowPlayingInfo.album.createCFString().get());
+    CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoTitle, nowPlayingInfo.title.createCFString().get());
 
-    if (!nowPlayingInfo.album.isEmpty())
-        CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoAlbum, nowPlayingInfo.album.createCFString().get());
-
-    if (!nowPlayingInfo.title.isEmpty())
-        CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoTitle, nowPlayingInfo.title.createCFString().get());
-
     if (std::isfinite(nowPlayingInfo.duration) && nowPlayingInfo.duration != MediaPlayer::invalidTime()) {
         auto cfDuration = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &nowPlayingInfo.duration));
         CFDictionarySetValue(info.get(), kMRMediaRemoteNowPlayingInfoDuration, cfDuration.get());
@@ -366,20 +361,24 @@
         m_lastUpdatedNowPlayingDuration = NAN;
         m_lastUpdatedNowPlayingElapsedTime = NAN;
         m_lastUpdatedNowPlayingInfoUniqueIdentifier = { };
+        m_nowPlayingInfo = { };
 
         return;
     }
 
     m_haveEverRegisteredAsNowPlayingApplication = true;
-    platformStrategies()->mediaStrategy().setNowPlayingInfo(!m_registeredAsNowPlayingApplication, *nowPlayingInfo);
 
+    if (m_nowPlayingInfo != nowPlayingInfo) {
+        m_nowPlayingInfo = nowPlayingInfo;
+        platformStrategies()->mediaStrategy().setNowPlayingInfo(!m_registeredAsNowPlayingApplication, *nowPlayingInfo);
+        ALWAYS_LOG(LOGIDENTIFIER, "title = \"", nowPlayingInfo->title, "\", isPlaying = ", nowPlayingInfo->isPlaying, ", duration = ", nowPlayingInfo->duration, ", now = ", nowPlayingInfo->currentTime, ", id = ", nowPlayingInfo->uniqueIdentifier.toUInt64(), ", registered = ", m_registeredAsNowPlayingApplication);
+    }
+
     if (!m_registeredAsNowPlayingApplication) {
         m_registeredAsNowPlayingApplication = true;
         providePresentingApplicationPIDIfNecessary();
     }
 
-    ALWAYS_LOG(LOGIDENTIFIER, "title = \"", nowPlayingInfo->title, "\", isPlaying = ", nowPlayingInfo->isPlaying, ", duration = ", nowPlayingInfo->duration, ", now = ", nowPlayingInfo->currentTime, ", id = ", nowPlayingInfo->uniqueIdentifier.toUInt64(), ", registered = ", m_registeredAsNowPlayingApplication);
-
     if (!nowPlayingInfo->title.isEmpty())
         m_lastUpdatedNowPlayingTitle = nowPlayingInfo->title;
 

Modified: trunk/Source/WebCore/platform/cocoa/RemoteCommandListenerCocoa.h (273966 => 273967)


--- trunk/Source/WebCore/platform/cocoa/RemoteCommandListenerCocoa.h	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/cocoa/RemoteCommandListenerCocoa.h	2021-03-05 15:50:23 UTC (rev 273967)
@@ -46,7 +46,6 @@
 
     const RemoteCommandsSet& defaultCommands();
     RemoteCommandsSet m_currentCommands;
-    bool m_supportsSeeking { false };
 };
     
 }

Modified: trunk/Source/WebCore/platform/cocoa/RemoteCommandListenerCocoa.mm (273966 => 273967)


--- trunk/Source/WebCore/platform/cocoa/RemoteCommandListenerCocoa.mm	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/cocoa/RemoteCommandListenerCocoa.mm	2021-03-05 15:50:23 UTC (rev 273967)
@@ -101,13 +101,13 @@
     if (!isMediaRemoteFrameworkAvailable())
         return;
 
-    auto& supportedCommands = !m_registeredCommands.isEmpty() ? m_registeredCommands : defaultCommands();
-    if (m_currentCommands == supportedCommands)
+    auto& currentCommands = !supportedCommands().isEmpty() ? supportedCommands() : defaultCommands();
+    if (m_currentCommands == currentCommands)
         return;
 
-    auto commandInfoArray = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, supportedCommands.size(), &kCFTypeArrayCallBacks));
-    for (auto platformCommand : supportedCommands) {
-        if (isSeekCommand(platformCommand) && !m_supportsSeeking)
+    auto commandInfoArray = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, currentCommands.size(), &kCFTypeArrayCallBacks));
+    for (auto platformCommand : currentCommands) {
+        if (isSeekCommand(platformCommand) && !supportsSeeking())
             continue;
 
         auto command = mediaRemoteCommandForPlatformCommand(platformCommand);
@@ -118,11 +118,13 @@
         auto commandInfo = adoptCF(MRMediaRemoteCommandInfoCreate(kCFAllocatorDefault));
         MRMediaRemoteCommandInfoSetCommand(commandInfo.get(), command.value());
         MRMediaRemoteCommandInfoSetEnabled(commandInfo.get(), true);
+        if (platformCommand == PlatformMediaSession::SkipForwardCommand || platformCommand == PlatformMediaSession::SkipBackwardCommand)
+            MRMediaRemoteCommandInfoSetOptions(commandInfo.get(), (__bridge CFDictionaryRef)(@{(__bridge NSString *)kMRMediaRemoteCommandInfoPreferredIntervalsKey : @[@(15.0)]}));
         CFArrayAppendValue(commandInfoArray.get(), commandInfo.get());
     }
 
     MRMediaRemoteSetSupportedCommands(commandInfoArray.get(), MRMediaRemoteGetLocalOrigin(), nullptr, nullptr);
-    m_currentCommands = supportedCommands;
+    m_currentCommands = currentCommands;
 }
 
 RemoteCommandListenerCocoa::RemoteCommandListenerCocoa(RemoteCommandListenerClient& client)
@@ -168,7 +170,7 @@
             platformCommand = PlatformMediaSession::EndSeekingBackwardCommand;
             break;
         case MRMediaRemoteCommandSeekToPlaybackPosition: {
-            if (!m_supportsSeeking) {
+            if (!supportsSeeking()) {
                 status = MRMediaRemoteCommandHandlerStatusCommandFailed;
                 break;
             }
@@ -187,7 +189,7 @@
         }
         case MRMediaRemoteCommandSkipForward:
         case MRMediaRemoteCommandSkipBackward:
-            if (!m_supportsSeeking) {
+            if (!supportsSeeking()) {
                 status = MRMediaRemoteCommandHandlerStatusCommandFailed;
                 break;
             }
@@ -212,7 +214,7 @@
         };
 
         if (weakThis && status != MRMediaRemoteCommandHandlerStatusCommandFailed)
-            weakThis->m_client.didReceiveRemoteControlCommand(platformCommand, argument);
+            weakThis->client().didReceiveRemoteControlCommand(platformCommand, argument);
 
         completion((__bridge CFArrayRef)@[@(status)]);
     });

Modified: trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.h (273966 => 273967)


--- trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.h	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.h	2021-03-05 15:50:23 UTC (rev 273967)
@@ -78,6 +78,8 @@
 #define kMRMediaRemoteNowPlayingInfoUniqueIdentifier get_MediaRemote_kMRMediaRemoteNowPlayingInfoUniqueIdentifier()
 SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, MediaRemote, kMRMediaRemoteOptionSkipInterval, CFStringRef);
 #define kMRMediaRemoteOptionSkipInterval get_MediaRemote_kMRMediaRemoteOptionSkipInterval()
+SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, MediaRemote, kMRMediaRemoteCommandInfoPreferredIntervalsKey, CFStringRef);
+#define kMRMediaRemoteCommandInfoPreferredIntervalsKey get_MediaRemote_kMRMediaRemoteOptionSkipInterval()
 
 #if PLATFORM(IOS_FAMILY)
 SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, MediaRemote, MRMediaRemoteCopyPickableRoutes, CFArrayRef, (), ())

Modified: trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.mm (273966 => 273967)


--- trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.mm	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebCore/platform/mac/MediaRemoteSoftLink.mm	2021-03-05 15:50:23 UTC (rev 273967)
@@ -54,6 +54,7 @@
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteOptionPlaybackPosition, CFStringRef);
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteNowPlayingInfoUniqueIdentifier, CFStringRef);
 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteOptionSkipInterval, CFStringRef);
+SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, MediaRemote, kMRMediaRemoteCommandInfoPreferredIntervalsKey, CFStringRef);
 
 #if PLATFORM(IOS_FAMILY)
 SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, MediaRemote, MRMediaRemoteCopyPickableRoutes, CFArrayRef, (), ());

Modified: trunk/Source/WebKit/ChangeLog (273966 => 273967)


--- trunk/Source/WebKit/ChangeLog	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebKit/ChangeLog	2021-03-05 15:50:23 UTC (rev 273967)
@@ -1,3 +1,46 @@
+2021-03-05  Eric Carlson  <[email protected]>
+
+        [GPU Process] Remote control command should only go to the current NowPlaying session
+        https://bugs.webkit.org/show_bug.cgi?id=222759
+        <rdar://problem/75053393>
+
+        Reviewed by Jer Noble.
+
+        * GPUProcess/GPUConnectionToWebProcess.cpp:
+        (WebKit::GPUConnectionToWebProcess::clearNowPlayingInfo): Track being the active
+        NowPlaying process.
+        (WebKit::GPUConnectionToWebProcess::setNowPlayingInfo): Ditto.
+        (WebKit::GPUConnectionToWebProcess::updateSupportedRemoteCommands): Pass supported
+        commands and seeking to NowPlayingManager so it can pass them to the remote command
+        listener.
+        (WebKit::GPUConnectionToWebProcess::createRemoteCommandListener): We only ever need
+        one listener.
+        (WebKit::GPUConnectionToWebProcess::releaseRemoteCommandListener): Ditto.
+        (WebKit::GPUConnectionToWebProcess::dispatchMessage): Dispatch RemoteRemoteCommandListenerProxy
+        messages.
+        * GPUProcess/GPUConnectionToWebProcess.h:
+
+        * GPUProcess/media/RemoteRemoteCommandListenerProxy.cpp:
+        (WebKit::RemoteRemoteCommandListenerProxy::RemoteRemoteCommandListenerProxy): Don't
+        create a remote command listener, we only need one for the GPU process.
+        (WebKit::RemoteRemoteCommandListenerProxy::updateSupportedCommands): New.
+        (WebKit::RemoteRemoteCommandListenerProxy::didReceiveRemoteControlCommand): Deleted.
+        * GPUProcess/media/RemoteRemoteCommandListenerProxy.h:
+        (WebKit::RemoteRemoteCommandListenerProxy::create):
+        (WebKit::RemoteRemoteCommandListenerProxy::supportsSeeking const):
+        (WebKit::RemoteRemoteCommandListenerProxy::supportedCommands const):
+        (WebKit::RemoteRemoteCommandListenerProxy::identifier const):
+        * GPUProcess/media/RemoteRemoteCommandListenerProxy.messages.in:
+
+        * WebProcess/GPU/media/RemoteRemoteCommandListener.cpp:
+        (WebKit::RemoteRemoteCommandListener::RemoteRemoteCommandListener): Use m_process
+        instead of calling WebProcess::singleton().
+        (WebKit::RemoteRemoteCommandListener::~RemoteRemoteCommandListener): Ditto.
+        (WebKit::RemoteRemoteCommandListener::didReceiveRemoteControlCommand): Use client(),
+        m_client is now private.
+        (WebKit::RemoteRemoteCommandListener::updateSupportedCommands):
+        * WebProcess/GPU/media/RemoteRemoteCommandListener.h:
+
 2021-03-05  Chris Dumez  <[email protected]>
 
         Reduce use of CFRetain() / CFRelease() / CFAutoRelease() in WebKit

Modified: trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp (273966 => 273967)


--- trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp	2021-03-05 15:50:23 UTC (rev 273967)
@@ -51,6 +51,7 @@
 #include "RemoteMediaResourceManager.h"
 #include "RemoteMediaResourceManagerMessages.h"
 #include "RemoteRemoteCommandListenerProxy.h"
+#include "RemoteRemoteCommandListenerProxyMessages.h"
 #include "RemoteRenderingBackend.h"
 #include "RemoteSampleBufferDisplayLayerManager.h"
 #include "RemoteSampleBufferDisplayLayerManagerMessages.h"
@@ -366,14 +367,26 @@
 #endif
 void GPUConnectionToWebProcess::clearNowPlayingInfo()
 {
+    m_isActiveNowPlayingProcess = false;
     gpuProcess().nowPlayingManager().clearNowPlayingInfoClient(*this);
 }
 
 void GPUConnectionToWebProcess::setNowPlayingInfo(bool setAsNowPlayingApplication, NowPlayingInfo&& nowPlayingInfo)
 {
+    m_isActiveNowPlayingProcess = true;
     gpuProcess().nowPlayingManager().setNowPlayingInfo(*this, WTFMove(nowPlayingInfo));
+    updateSupportedRemoteCommands();
 }
 
+void GPUConnectionToWebProcess::updateSupportedRemoteCommands()
+{
+    if (!m_isActiveNowPlayingProcess || !m_remoteRemoteCommandListener)
+        return;
+
+    gpuProcess().nowPlayingManager().setSupportedRemoteCommands(m_remoteRemoteCommandListener->supportedCommands(), m_remoteRemoteCommandListener->supportsSeeking());
+
+}
+
 void GPUConnectionToWebProcess::didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType type, const PlatformMediaSession::RemoteCommandArgument& argument)
 {
     connection().send(Messages::GPUProcessConnection::DidReceiveRemoteCommand(type, argument), 0);
@@ -435,16 +448,13 @@
 
 void GPUConnectionToWebProcess::createRemoteCommandListener(RemoteRemoteCommandListenerIdentifier identifier)
 {
-    auto addResult = m_remoteRemoteCommandListenerMap.ensure(identifier, [&]() {
-        return makeUnique<RemoteRemoteCommandListenerProxy>(*this, WTFMove(identifier));
-    });
-    ASSERT_UNUSED(addResult, addResult.isNewEntry);
+    m_remoteRemoteCommandListener = RemoteRemoteCommandListenerProxy::create(*this, WTFMove(identifier));
 }
 
 void GPUConnectionToWebProcess::releaseRemoteCommandListener(RemoteRemoteCommandListenerIdentifier identifier)
 {
-    bool found = m_remoteRemoteCommandListenerMap.remove(identifier);
-    ASSERT_UNUSED(found, found);
+    if (m_remoteRemoteCommandListener && m_remoteRemoteCommandListener->identifier() == identifier)
+        m_remoteRemoteCommandListener = nullptr;
 }
 
 void GPUConnectionToWebProcess::setMediaOverridesForTesting(MediaOverridesForTesting overrides)
@@ -546,6 +556,11 @@
     }
 #endif
 
+    if (m_remoteRemoteCommandListener && decoder.messageReceiverName() == Messages::RemoteRemoteCommandListenerProxy::messageReceiverName()) {
+        m_remoteRemoteCommandListener->didReceiveMessage(connection, decoder);
+        return true;
+    }
+
     return messageReceiverMap().dispatchMessage(connection, decoder);
 }
 

Modified: trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h (273966 => 273967)


--- trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h	2021-03-05 15:50:23 UTC (rev 273967)
@@ -127,6 +127,8 @@
     RemoteImageDecoderAVFProxy& imageDecoderAVFProxy();
 #endif
 
+    void updateSupportedRemoteCommands();
+
     void terminateWebProcess();
 
 private:
@@ -244,8 +246,9 @@
 
     using RemoteAudioHardwareListenerMap = HashMap<RemoteAudioHardwareListenerIdentifier, std::unique_ptr<RemoteAudioHardwareListenerProxy>>;
     RemoteAudioHardwareListenerMap m_remoteAudioHardwareListenerMap;
-    using RemoteRemoteCommandListenerMap = HashMap<RemoteRemoteCommandListenerIdentifier, std::unique_ptr<RemoteRemoteCommandListenerProxy>>;
-    RemoteRemoteCommandListenerMap m_remoteRemoteCommandListenerMap;
+
+    RefPtr<RemoteRemoteCommandListenerProxy> m_remoteRemoteCommandListener;
+    bool m_isActiveNowPlayingProcess { false };
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/GPUProcess/media/RemoteRemoteCommandListenerProxy.cpp (273966 => 273967)


--- trunk/Source/WebKit/GPUProcess/media/RemoteRemoteCommandListenerProxy.cpp	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebKit/GPUProcess/media/RemoteRemoteCommandListenerProxy.cpp	2021-03-05 15:50:23 UTC (rev 273967)
@@ -29,6 +29,7 @@
 #if ENABLE(GPU_PROCESS)
 
 #include "GPUConnectionToWebProcess.h"
+#include "GPUProcess.h"
 #include "RemoteRemoteCommandListenerMessages.h"
 
 namespace WebKit {
@@ -38,26 +39,21 @@
 RemoteRemoteCommandListenerProxy::RemoteRemoteCommandListenerProxy(GPUConnectionToWebProcess& gpuConnection, RemoteRemoteCommandListenerIdentifier&& identifier)
     : m_gpuConnection(makeWeakPtr(gpuConnection))
     , m_identifier(WTFMove(identifier))
-    , m_listener(WebCore::RemoteCommandListener::create(*this))
 {
 }
 
 RemoteRemoteCommandListenerProxy::~RemoteRemoteCommandListenerProxy() = default;
 
-void RemoteRemoteCommandListenerProxy::didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType command, const PlatformMediaSession::RemoteCommandArgument& argument)
+void RemoteRemoteCommandListenerProxy::updateSupportedCommands(Vector<WebCore::PlatformMediaSession::RemoteControlCommandType>&& registeredCommands, bool supportsSeeking)
 {
-    if (!m_gpuConnection)
-        return;
+    m_supportedCommands.clear();
+    m_supportedCommands.add(registeredCommands.begin(), registeredCommands.end());
+    m_supportsSeeking = supportsSeeking;
 
-    m_gpuConnection->connection().send(Messages::RemoteRemoteCommandListener::DidReceiveRemoteControlCommand(command, argument), m_identifier);
+    if (m_gpuConnection)
+        m_gpuConnection->updateSupportedRemoteCommands();
 }
 
-void RemoteRemoteCommandListenerProxy::updateSupportedCommands(bool supportsSeeking)
-{
-    m_listener->setSupportsSeeking(supportsSeeking);
-    m_listener->updateSupportedCommands();
 }
 
-}
-
 #endif

Modified: trunk/Source/WebKit/GPUProcess/media/RemoteRemoteCommandListenerProxy.h (273966 => 273967)


--- trunk/Source/WebKit/GPUProcess/media/RemoteRemoteCommandListenerProxy.h	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebKit/GPUProcess/media/RemoteRemoteCommandListenerProxy.h	2021-03-05 15:50:23 UTC (rev 273967)
@@ -30,6 +30,7 @@
 #include "MessageReceiver.h"
 #include "RemoteRemoteCommandListenerIdentifier.h"
 #include <WebCore/RemoteCommandListener.h>
+#include <wtf/RetainPtr.h>
 #include <wtf/UniqueRef.h>
 #include <wtf/WeakPtr.h>
 
@@ -41,27 +42,34 @@
 
 class GPUConnectionToWebProcess;
 
-class RemoteRemoteCommandListenerProxy
-    : private WebCore::RemoteCommandListenerClient
-    , private IPC::MessageReceiver {
+class RemoteRemoteCommandListenerProxy : public RefCounted<RemoteRemoteCommandListenerProxy>, private IPC::MessageReceiver {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    RemoteRemoteCommandListenerProxy(GPUConnectionToWebProcess&, RemoteRemoteCommandListenerIdentifier&&);
+    static Ref<RemoteRemoteCommandListenerProxy> create(GPUConnectionToWebProcess& process, RemoteRemoteCommandListenerIdentifier&& identifier)
+    {
+        return adoptRef(*new RemoteRemoteCommandListenerProxy(process, WTFMove(identifier)));
+    }
+
     virtual ~RemoteRemoteCommandListenerProxy();
 
-private:
+    bool supportsSeeking() const { return m_supportsSeeking; }
+    const WebCore::RemoteCommandListener::RemoteCommandsSet& supportedCommands() const { return m_supportedCommands; }
+
+    RemoteRemoteCommandListenerIdentifier identifier() const { return m_identifier; }
+
     // IPC::MessageReceiver
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
 
-    // RemoteCommandListenerClient
-    void didReceiveRemoteControlCommand(WebCore::PlatformMediaSession::RemoteControlCommandType, const WebCore::PlatformMediaSession::RemoteCommandArgument&) final;
+private:
+    RemoteRemoteCommandListenerProxy(GPUConnectionToWebProcess&, RemoteRemoteCommandListenerIdentifier&&);
 
     // Messages
-    void updateSupportedCommands(bool supportsSeeking);
+    void updateSupportedCommands(Vector<WebCore::PlatformMediaSession::RemoteControlCommandType>&& commands, bool supportsSeeking);
 
     WeakPtr<GPUConnectionToWebProcess> m_gpuConnection;
     RemoteRemoteCommandListenerIdentifier m_identifier;
-    std::unique_ptr<WebCore::RemoteCommandListener> m_listener;
+    WebCore::RemoteCommandListener::RemoteCommandsSet m_supportedCommands;
+    bool m_supportsSeeking { false };
 };
 
 }

Modified: trunk/Source/WebKit/GPUProcess/media/RemoteRemoteCommandListenerProxy.messages.in (273966 => 273967)


--- trunk/Source/WebKit/GPUProcess/media/RemoteRemoteCommandListenerProxy.messages.in	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebKit/GPUProcess/media/RemoteRemoteCommandListenerProxy.messages.in	2021-03-05 15:50:23 UTC (rev 273967)
@@ -26,7 +26,7 @@
 #if ENABLE(GPU_PROCESS)
 
 messages -> RemoteRemoteCommandListenerProxy NotRefCounted {
-    UpdateSupportedCommands(bool supportsSeeking)
+    UpdateSupportedCommands(Vector<WebCore::PlatformMediaSession::RemoteControlCommandType> commands, bool supportsSeeking)
 }
 
 #endif

Modified: trunk/Source/WebKit/WebProcess/GPU/media/RemoteRemoteCommandListener.cpp (273966 => 273967)


--- trunk/Source/WebKit/WebProcess/GPU/media/RemoteRemoteCommandListener.cpp	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebKit/WebProcess/GPU/media/RemoteRemoteCommandListener.cpp	2021-03-05 15:50:23 UTC (rev 273967)
@@ -31,6 +31,7 @@
 #include "GPUConnectionToWebProcessMessages.h"
 #include "GPUProcessProxy.h"
 #include "RemoteRemoteCommandListenerMessages.h"
+#include "RemoteRemoteCommandListenerProxyMessages.h"
 #include "WebProcess.h"
 
 namespace WebKit {
@@ -47,7 +48,7 @@
     , m_process(webProcess)
     , m_identifier(RemoteRemoteCommandListenerIdentifier::generate())
 {
-    auto& connection = WebProcess::singleton().ensureGPUProcessConnection();
+    auto& connection = m_process.ensureGPUProcessConnection();
     connection.addClient(*this);
     connection.messageReceiverMap().addMessageReceiver(Messages::RemoteRemoteCommandListener::messageReceiverName(), m_identifier.toUInt64(), *this);
     connection.connection().send(Messages::GPUConnectionToWebProcess::CreateRemoteCommandListener(m_identifier), { });
@@ -55,7 +56,7 @@
 
 RemoteRemoteCommandListener::~RemoteRemoteCommandListener()
 {
-    auto& connection = WebProcess::singleton().ensureGPUProcessConnection();
+    auto& connection = m_process.ensureGPUProcessConnection();
     connection.messageReceiverMap().removeMessageReceiver(*this);
     connection.connection().send(Messages::GPUConnectionToWebProcess::ReleaseRemoteCommandListener(m_identifier), 0);
 }
@@ -66,9 +67,26 @@
 
 void RemoteRemoteCommandListener::didReceiveRemoteControlCommand(WebCore::PlatformMediaSession::RemoteControlCommandType type, const PlatformMediaSession::RemoteCommandArgument& argument)
 {
-    m_client.didReceiveRemoteControlCommand(type, argument);
+    client().didReceiveRemoteControlCommand(type, argument);
 }
 
+void RemoteRemoteCommandListener::updateSupportedCommands()
+{
+    auto& supportedCommands = this->supportedCommands();
+    if (m_currentCommands == supportedCommands && m_currentSupportSeeking == supportsSeeking())
+        return;
+
+    m_currentCommands = supportedCommands;
+    m_currentSupportSeeking = supportsSeeking();
+
+    Vector<PlatformMediaSession::RemoteControlCommandType> commands;
+    commands.reserveInitialCapacity(supportedCommands.size());
+    for (auto command : supportedCommands)
+        commands.uncheckedAppend(command);
+
+    m_process.ensureGPUProcessConnection().connection().send(Messages::RemoteRemoteCommandListenerProxy::UpdateSupportedCommands { WTFMove(commands), m_currentSupportSeeking }, m_identifier);
 }
 
+}
+
 #endif

Modified: trunk/Source/WebKit/WebProcess/GPU/media/RemoteRemoteCommandListener.h (273966 => 273967)


--- trunk/Source/WebKit/WebProcess/GPU/media/RemoteRemoteCommandListener.h	2021-03-05 15:44:47 UTC (rev 273966)
+++ trunk/Source/WebKit/WebProcess/GPU/media/RemoteRemoteCommandListener.h	2021-03-05 15:50:23 UTC (rev 273967)
@@ -61,8 +61,12 @@
     // Messages
     void didReceiveRemoteControlCommand(WebCore::PlatformMediaSession::RemoteControlCommandType, const WebCore::PlatformMediaSession::RemoteCommandArgument&);
 
+    void updateSupportedCommands() final;
+
     WebProcess& m_process;
     RemoteRemoteCommandListenerIdentifier m_identifier;
+    WebCore::RemoteCommandListener::RemoteCommandsSet m_currentCommands;
+    bool m_currentSupportSeeking { false };
 };
 
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to