[Mac] Use one playback target for all web processes
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Apr 2015 04:06:57 +0000 (04:06 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Apr 2015 04:06:57 +0000 (04:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=144009

Reviewed by Tim Horton.

Source/WebCore:

* Modules/mediacontrols/mediaControlsApple.js:
(Controller.prototype.updateWirelessPlaybackStatus): Drive-by fix to show controls when
    we show the placeholder image.

Instead of having each Page/Document pair manage access to the playback target for the videos
in a web process, put all of the logic into a new class - WebMediaSessionManager. A singleton
instance talks to the target picker and manages video element access for all web processes.
All playback target logic was removed from Document, Page, and MediaSessionManager.

* Modules/mediasession: Added.
* Modules/mediasession/WebMediaSessionManager.cpp: Added.
(WebCore::ClientState::ClientState):
(WebCore::flagsAreSet):
(WebCore::WebMediaSessionManager::WebMediaSessionManager):
(WebCore::WebMediaSessionManager::~WebMediaSessionManager):
(WebCore::WebMediaSessionManager::addPlaybackTargetPickerClient):
(WebCore::WebMediaSessionManager::removePlaybackTargetPickerClient):
(WebCore::WebMediaSessionManager::removeAllPlaybackTargetPickerClients):
(WebCore::WebMediaSessionManager::showPlaybackTargetPicker):
(WebCore::WebMediaSessionManager::clientStateDidChange):
(WebCore::WebMediaSessionManager::setPlaybackTarget):
(WebCore::WebMediaSessionManager::externalOutputDeviceAvailableDidChange):
(WebCore::WebMediaSessionManager::configurePlaybackTargetMonitoring):
(WebCore::WebMediaSessionManager::taskTimerFired):
(WebCore::WebMediaSessionManager::find):
(WebCore::WebMediaSessionManager::forEachClient):
* Modules/mediasession/WebMediaSessionManager.h: Added.
* Modules/mediasession/WebMediaSessionManagerClient.h: Added.
(WebCore::WebMediaSessionManagerClient::~WebMediaSessionManagerClient):
* Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::mediaState): Replaces isPlayingAudio.
(WebCore::AudioContext::isPlayingAudio): Deleted.
* Modules/webaudio/AudioContext.h:
* WebCore.xcodeproj/project.pbxproj: Added new files.
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::addAudioProducer): Take a MediaProducer instead of an AudioProducer.
(WebCore::Document::removeAudioProducer):
(WebCore::Document::updateIsPlayingMedia):
(WebCore::nextPlaybackTargetClientContextId):
(WebCore::Document::addPlaybackTargetPickerClient):
(WebCore::Document::removePlaybackTargetPickerClient):
(WebCore::Document::showPlaybackTargetPicker):
(WebCore::Document::playbackTargetPickerClientStateDidChange):
(WebCore::Document::playbackTargetAvailabilityDidChange):
(WebCore::Document::setPlaybackTarget):
(WebCore::Document::setShouldPlayToPlaybackTarget):
(WebCore::Document::configurePlaybackTargetMonitoring): Deleted.
(WebCore::Document::requiresPlaybackTargetRouteMonitoring): Deleted.
(WebCore::Document::didChoosePlaybackTarget): Deleted.
* dom/Document.h:
(WebCore::Document::mediaState):
(WebCore::Document::isPlayingAudio): Deleted.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::~HTMLMediaElement):
(WebCore::HTMLMediaElement::registerWithDocument):
(WebCore::HTMLMediaElement::setMuted):
(WebCore::HTMLMediaElement::parseAttribute):
* html/HTMLMediaElement.h:
* html/HTMLMediaSession.cpp:
(WebCore::HTMLMediaSession::registerWithDocument):
(WebCore::HTMLMediaSession::unregisterWithDocument):
(WebCore::HTMLMediaSession::showPlaybackTargetPicker):
(WebCore::HTMLMediaSession::setHasPlaybackTargetAvailabilityListeners):
(WebCore::HTMLMediaSession::setPlaybackTarget):
(WebCore::HTMLMediaSession::externalOutputDeviceAvailableDidChange):
(WebCore::HTMLMediaSession::setShouldPlayToPlaybackTarget):
(WebCore::HTMLMediaSession::mediaStateDidChange):
(WebCore::HTMLMediaSession::didChoosePlaybackTarget): Deleted.
(WebCore::HTMLMediaSession::requiresPlaybackTargetRouteMonitoring): Deleted.
(WebCore::HTMLMediaSession::startPlayingToPlaybackTarget): Deleted.
(WebCore::HTMLMediaSession::stopPlayingToPlaybackTarget): Deleted.
* html/HTMLMediaSession.h:
* page/AudioProducer.h: Removed.
* page/ChromeClient.h:
* page/MediaProducer.h: Copied from Source/WebCore/page/AudioProducer.h.
(WebCore::MediaProducer::~MediaProducer):
(WebCore::AudioProducer::~AudioProducer): Deleted.
* page/Page.cpp:
(WebCore::Page::Page):
(WebCore::Page::updateIsPlayingMedia):
(WebCore::Page::addPlaybackTargetPickerClient):
(WebCore::Page::removePlaybackTargetPickerClient):
(WebCore::Page::showPlaybackTargetPicker):
(WebCore::Page::playbackTargetPickerClientStateDidChange):
(WebCore::Page::setPlaybackTarget):
(WebCore::Page::playbackTargetAvailabilityDidChange):
(WebCore::Page::setShouldPlayToPlaybackTarget):
(WebCore::Page::playbackTarget): Deleted.
(WebCore::Page::didChoosePlaybackTarget): Deleted.
(WebCore::Page::configurePlaybackTargetMonitoring): Deleted.
* page/Page.h:
(WebCore::Page::mediaState):
(WebCore::Page::isPlayingAudio): Deleted.
(WebCore::Page::hasWirelessPlaybackTarget): Deleted.
* platform/audio/MediaSession.h:
(WebCore::MediaSession::isPlayingToWirelessPlaybackTarget):
(WebCore::MediaSession::requiresPlaybackTargetRouteMonitoring):
(WebCore::MediaSessionClient::setShouldPlayToPlaybackTarget):
(WebCore::MediaSession::startPlayingToPlaybackTarget): Deleted.
(WebCore::MediaSession::stopPlayingToPlaybackTarget): Deleted.
(WebCore::MediaSessionClient::startPlayingToPlaybackTarget): Deleted.
(WebCore::MediaSessionClient::stopPlayingToPlaybackTarget): Deleted.
* platform/audio/MediaSessionManager.cpp:
(WebCore::MediaSessionManager::sessionWillBeginPlayback):
(WebCore::MediaSessionManager::sessionCanLoadMedia):
(WebCore::MediaSessionManager::sessionShouldBeginPlayingToWirelessPlaybackTarget): Deleted.
* platform/audio/MediaSessionManager.h:
* platform/graphics/MediaPlaybackTargetClient.h: Copied from Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h.
(WebCore::MediaPlaybackTargetClient::~MediaPlaybackTargetClient):
(WebCore::MediaPlaybackTargetPickerClient::~MediaPlaybackTargetPickerClient): Deleted.
* platform/graphics/MediaPlaybackTargetPicker.cpp:
(WebCore::MediaPlaybackTargetPicker::showPlaybackTargetPicker):
(WebCore::MediaPlaybackTargetPicker::startingMonitoringPlaybackTargets):
(WebCore::MediaPlaybackTargetPicker::stopMonitoringPlaybackTargets):
* platform/graphics/MediaPlaybackTargetPicker.h:
* platform/graphics/MediaPlaybackTargetPickerClient.h: Removed.
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::setShouldPlayToPlaybackTarget):
(WebCore::MediaPlayer::startPlayingToPlaybackTarget): Deleted.
(WebCore::MediaPlayer::stopPlayingToPlaybackTarget): Deleted.
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::setShouldPlayToPlaybackTarget):
(WebCore::MediaPlayerPrivateInterface::startPlayingToPlaybackTarget): Deleted.
(WebCore::MediaPlayerPrivateInterface::stopPlayingToPlaybackTarget): Deleted.
* platform/graphics/avfoundation/WebMediaSessionManagerMac.cpp: Added.
(WebCore::WebMediaSessionManagerMac::singleton):
(WebCore::WebMediaSessionManagerMac::WebMediaSessionManagerMac):
(WebCore::WebMediaSessionManagerMac::~WebMediaSessionManagerMac):
(WebCore::WebMediaSessionManagerMac::targetPicker):
* platform/graphics/avfoundation/WebMediaSessionManagerMac.h: Added.
* platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.h:
* platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm:
(WebCore::MediaPlaybackTargetPickerMac::currentDeviceDidChange):
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayer):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setShouldPlayToPlaybackTarget):
(WebCore::MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget): Deleted.
(WebCore::MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget): Deleted.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setShouldPlayToPlaybackTarget):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::togglePlayingToPlaybackTarget): Deleted.
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::startPlayingToPlaybackTarget): Deleted.
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::stopPlayingToPlaybackTarget): Deleted.
* platform/graphics/mac/MediaPlayerPrivateQTKit.h:
* platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
(WebCore::MediaPlayerPrivateQTKit::setShouldPlayToPlaybackTarget):
(WebCore::MediaPlayerPrivateQTKit::togglePlayingToPlaybackTarget): Deleted.
(WebCore::MediaPlayerPrivateQTKit::startPlayingToPlaybackTarget): Deleted.
(WebCore::MediaPlayerPrivateQTKit::stopPlayingToPlaybackTarget): Deleted.
* testing/Internals.cpp:
(WebCore::Internals::isPagePlayingAudio):

Source/WebKit/mac:

Update to use WebMediaSessionManager for playback target management.

* WebCoreSupport/WebChromeClient.h:
* WebCoreSupport/WebChromeClient.mm:
(WebChromeClient::addPlaybackTargetPickerClient):
(WebChromeClient::removePlaybackTargetPickerClient):
(WebChromeClient::showPlaybackTargetPicker):
(WebChromeClient::playbackTargetPickerClientStateDidChange):
(WebChromeClient::startingMonitoringPlaybackTargets): Deleted.
(WebChromeClient::stopMonitoringPlaybackTargets): Deleted.
* WebView/WebMediaPlaybackTargetPicker.h:
* WebView/WebMediaPlaybackTargetPicker.mm:
(WebMediaPlaybackTargetPicker::addPlaybackTargetPickerClient):
(WebMediaPlaybackTargetPicker::removePlaybackTargetPickerClient):
(WebMediaPlaybackTargetPicker::showPlaybackTargetPicker):
(WebMediaPlaybackTargetPicker::playbackTargetPickerClientStateDidChange):
(WebMediaPlaybackTargetPicker::setPlaybackTarget):
(WebMediaPlaybackTargetPicker::externalOutputDeviceAvailableDidChange):
(WebMediaPlaybackTargetPicker::setShouldPlayToPlaybackTarget):
(WebMediaPlaybackTargetPicker::invalidate):
(WebMediaPlaybackTargetPicker::startingMonitoringPlaybackTargets): Deleted.
(WebMediaPlaybackTargetPicker::stopMonitoringPlaybackTargets): Deleted.
(WebMediaPlaybackTargetPicker::didChoosePlaybackTarget): Deleted.
(WebMediaPlaybackTargetPicker::targetPicker): Deleted.
* WebView/WebView.mm:
(-[WebView _addPlaybackTargetPickerClient:]):
(-[WebView _removePlaybackTargetPickerClient:]):
(-[WebView _showPlaybackTargetPicker:location:hasVideo:]):
(-[WebView _playbackTargetPickerClientStateDidChange:state:]):
(-[WebView _showPlaybackTargetPicker:hasVideo:]): Deleted.
(-[WebView _startingMonitoringPlaybackTargets]): Deleted.
(-[WebView _stopMonitoringPlaybackTargets]): Deleted.
* WebView/WebViewInternal.h:

Source/WebKit2:

Every WebPageProxy uses the WebMediaSessionManager singleton to talk to the playback target
picker.

* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::WebPageProxy):
(WebKit::WebPageProxy::resetState):
(WebKit::WebPageProxy::isPlayingMediaDidChange):
(WebKit::WebPageProxy::addPlaybackTargetPickerClient):
(WebKit::WebPageProxy::removePlaybackTargetPickerClient):
(WebKit::WebPageProxy::showPlaybackTargetPicker):
(WebKit::WebPageProxy::playbackTargetPickerClientStateDidChange):
(WebKit::WebPageProxy::setPlaybackTarget):
(WebKit::WebPageProxy::externalOutputDeviceAvailableDidChange):
(WebKit::WebPageProxy::setShouldPlayToPlaybackTarget):
(WebKit::WebPageProxy::devicePickerProxy): Deleted.
(WebKit::WebPageProxy::startingMonitoringPlaybackTargets): Deleted.
(WebKit::WebPageProxy::stopMonitoringPlaybackTargets): Deleted.
(WebKit::WebPageProxy::didChoosePlaybackTarget): Deleted.
* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::isPlayingAudio):
* UIProcess/WebPageProxy.messages.in:
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::mediaSessionManager):
(WebKit::PageClientImpl::createPlaybackTargetPicker): Deleted.
* UIProcess/mac/WebMediaSessionManagerMac.cpp: Added.
(WebKit::WebMediaSessionManagerMac::singleton):
(WebKit::WebMediaSessionManagerMac::WebMediaSessionManagerMac):
(WebKit::WebMediaSessionManagerMac::~WebMediaSessionManagerMac):
(WebKit::WebMediaSessionManagerMac::targetPicker):
* UIProcess/mac/WebMediaSessionManagerMac.h: Added.
* WebProcess/Plugins/PluginView.h:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::isPlayingMediaDidChange):
(WebKit::WebChromeClient::addPlaybackTargetPickerClient):
(WebKit::WebChromeClient::removePlaybackTargetPickerClient):
(WebKit::WebChromeClient::showPlaybackTargetPicker):
(WebKit::WebChromeClient::playbackTargetPickerClientStateDidChange):
(WebKit::WebChromeClient::startingMonitoringPlaybackTargets): Deleted.
(WebKit::WebChromeClient::stopMonitoringPlaybackTargets): Deleted.
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
(WebKit::TiledCoreAnimationDrawingArea::dispatchAfterEnsuringUpdatedScrollPosition):
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::playbackTargetSelected):
(WebKit::WebPage::playbackTargetAvailabilityDidChange):
(WebKit::WebPage::setShouldPlayToPlaybackTarget):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183096 268f45cc-cd09-0410-ab3c-d52691b4dbfc

58 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediacontrols/mediaControlsApple.js
Source/WebCore/Modules/mediasession/WebMediaSessionManager.cpp [new file with mode: 0644]
Source/WebCore/Modules/mediasession/WebMediaSessionManager.h [new file with mode: 0644]
Source/WebCore/Modules/mediasession/WebMediaSessionManagerClient.h [new file with mode: 0644]
Source/WebCore/Modules/webaudio/AudioContext.cpp
Source/WebCore/Modules/webaudio/AudioContext.h
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLMediaSession.cpp
Source/WebCore/html/HTMLMediaSession.h
Source/WebCore/page/ChromeClient.h
Source/WebCore/page/MediaProducer.h [moved from Source/WebCore/page/AudioProducer.h with 77% similarity]
Source/WebCore/page/Page.cpp
Source/WebCore/page/Page.h
Source/WebCore/platform/audio/MediaSession.h
Source/WebCore/platform/audio/MediaSessionManager.cpp
Source/WebCore/platform/audio/MediaSessionManager.h
Source/WebCore/platform/graphics/MediaPlaybackTargetClient.h [moved from Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h with 78% similarity]
Source/WebCore/platform/graphics/MediaPlaybackTargetPicker.cpp
Source/WebCore/platform/graphics/MediaPlaybackTargetPicker.h
Source/WebCore/platform/graphics/MediaPlayer.cpp
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebCore/platform/graphics/MediaPlayerPrivate.h
Source/WebCore/platform/graphics/avfoundation/WebMediaSessionManagerMac.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/avfoundation/WebMediaSessionManagerMac.h [new file with mode: 0644]
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm
Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
Source/WebCore/testing/Internals.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebCoreSupport/WebChromeClient.h
Source/WebKit/mac/WebCoreSupport/WebChromeClient.mm
Source/WebKit/mac/WebView/WebMediaPlaybackTargetPicker.h
Source/WebKit/mac/WebView/WebMediaPlaybackTargetPicker.mm
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit/mac/WebView/WebViewInternal.h
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/PageClient.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/UIProcess/mac/PageClientImpl.h
Source/WebKit2/UIProcess/mac/PageClientImpl.mm
Source/WebKit2/WebProcess/Plugins/PluginView.h
Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm

index 2cdf85c..353ec1e 100644 (file)
@@ -1,3 +1,167 @@
+2015-04-21  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] Use one playback target for all web processes
+        https://bugs.webkit.org/show_bug.cgi?id=144009
+
+        Reviewed by Tim Horton.
+
+        * Modules/mediacontrols/mediaControlsApple.js:
+        (Controller.prototype.updateWirelessPlaybackStatus): Drive-by fix to show controls when
+            we show the placeholder image.
+
+        Instead of having each Page/Document pair manage access to the playback target for the videos
+        in a web process, put all of the logic into a new class - WebMediaSessionManager. A singleton
+        instance talks to the target picker and manages video element access for all web processes.
+        All playback target logic was removed from Document, Page, and MediaSessionManager.
+
+        * Modules/mediasession: Added.
+        * Modules/mediasession/WebMediaSessionManager.cpp: Added.
+        (WebCore::ClientState::ClientState):
+        (WebCore::flagsAreSet):
+        (WebCore::WebMediaSessionManager::WebMediaSessionManager):
+        (WebCore::WebMediaSessionManager::~WebMediaSessionManager):
+        (WebCore::WebMediaSessionManager::addPlaybackTargetPickerClient):
+        (WebCore::WebMediaSessionManager::removePlaybackTargetPickerClient):
+        (WebCore::WebMediaSessionManager::removeAllPlaybackTargetPickerClients):
+        (WebCore::WebMediaSessionManager::showPlaybackTargetPicker):
+        (WebCore::WebMediaSessionManager::clientStateDidChange):
+        (WebCore::WebMediaSessionManager::setPlaybackTarget):
+        (WebCore::WebMediaSessionManager::externalOutputDeviceAvailableDidChange):
+        (WebCore::WebMediaSessionManager::configurePlaybackTargetMonitoring):
+        (WebCore::WebMediaSessionManager::taskTimerFired):
+        (WebCore::WebMediaSessionManager::find):
+        (WebCore::WebMediaSessionManager::forEachClient):
+        * Modules/mediasession/WebMediaSessionManager.h: Added.
+        * Modules/mediasession/WebMediaSessionManagerClient.h: Added.
+        (WebCore::WebMediaSessionManagerClient::~WebMediaSessionManagerClient):
+        * Modules/webaudio/AudioContext.cpp:
+        (WebCore::AudioContext::mediaState): Replaces isPlayingAudio.
+        (WebCore::AudioContext::isPlayingAudio): Deleted.
+        * Modules/webaudio/AudioContext.h:
+        * WebCore.xcodeproj/project.pbxproj: Added new files.
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        (WebCore::Document::addAudioProducer): Take a MediaProducer instead of an AudioProducer.
+        (WebCore::Document::removeAudioProducer):
+        (WebCore::Document::updateIsPlayingMedia):
+        (WebCore::nextPlaybackTargetClientContextId):
+        (WebCore::Document::addPlaybackTargetPickerClient):
+        (WebCore::Document::removePlaybackTargetPickerClient):
+        (WebCore::Document::showPlaybackTargetPicker):
+        (WebCore::Document::playbackTargetPickerClientStateDidChange):
+        (WebCore::Document::playbackTargetAvailabilityDidChange):
+        (WebCore::Document::setPlaybackTarget):
+        (WebCore::Document::setShouldPlayToPlaybackTarget):
+        (WebCore::Document::configurePlaybackTargetMonitoring): Deleted.
+        (WebCore::Document::requiresPlaybackTargetRouteMonitoring): Deleted.
+        (WebCore::Document::didChoosePlaybackTarget): Deleted.
+        * dom/Document.h:
+        (WebCore::Document::mediaState):
+        (WebCore::Document::isPlayingAudio): Deleted.
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::~HTMLMediaElement):
+        (WebCore::HTMLMediaElement::registerWithDocument):
+        (WebCore::HTMLMediaElement::setMuted): 
+        (WebCore::HTMLMediaElement::parseAttribute):
+        * html/HTMLMediaElement.h:
+        * html/HTMLMediaSession.cpp:
+        (WebCore::HTMLMediaSession::registerWithDocument):
+        (WebCore::HTMLMediaSession::unregisterWithDocument):
+        (WebCore::HTMLMediaSession::showPlaybackTargetPicker):
+        (WebCore::HTMLMediaSession::setHasPlaybackTargetAvailabilityListeners):
+        (WebCore::HTMLMediaSession::setPlaybackTarget):
+        (WebCore::HTMLMediaSession::externalOutputDeviceAvailableDidChange):
+        (WebCore::HTMLMediaSession::setShouldPlayToPlaybackTarget):
+        (WebCore::HTMLMediaSession::mediaStateDidChange):
+        (WebCore::HTMLMediaSession::didChoosePlaybackTarget): Deleted.
+        (WebCore::HTMLMediaSession::requiresPlaybackTargetRouteMonitoring): Deleted.
+        (WebCore::HTMLMediaSession::startPlayingToPlaybackTarget): Deleted.
+        (WebCore::HTMLMediaSession::stopPlayingToPlaybackTarget): Deleted.
+        * html/HTMLMediaSession.h:
+        * page/AudioProducer.h: Removed.
+        * page/ChromeClient.h:
+        * page/MediaProducer.h: Copied from Source/WebCore/page/AudioProducer.h.
+        (WebCore::MediaProducer::~MediaProducer):
+        (WebCore::AudioProducer::~AudioProducer): Deleted.
+        * page/Page.cpp:
+        (WebCore::Page::Page):
+        (WebCore::Page::updateIsPlayingMedia):
+        (WebCore::Page::addPlaybackTargetPickerClient):
+        (WebCore::Page::removePlaybackTargetPickerClient):
+        (WebCore::Page::showPlaybackTargetPicker):
+        (WebCore::Page::playbackTargetPickerClientStateDidChange):
+        (WebCore::Page::setPlaybackTarget):
+        (WebCore::Page::playbackTargetAvailabilityDidChange):
+        (WebCore::Page::setShouldPlayToPlaybackTarget):
+        (WebCore::Page::playbackTarget): Deleted.
+        (WebCore::Page::didChoosePlaybackTarget): Deleted.
+        (WebCore::Page::configurePlaybackTargetMonitoring): Deleted.
+        * page/Page.h:
+        (WebCore::Page::mediaState):
+        (WebCore::Page::isPlayingAudio): Deleted.
+        (WebCore::Page::hasWirelessPlaybackTarget): Deleted.
+        * platform/audio/MediaSession.h:
+        (WebCore::MediaSession::isPlayingToWirelessPlaybackTarget):
+        (WebCore::MediaSession::requiresPlaybackTargetRouteMonitoring):
+        (WebCore::MediaSessionClient::setShouldPlayToPlaybackTarget):
+        (WebCore::MediaSession::startPlayingToPlaybackTarget): Deleted.
+        (WebCore::MediaSession::stopPlayingToPlaybackTarget): Deleted.
+        (WebCore::MediaSessionClient::startPlayingToPlaybackTarget): Deleted.
+        (WebCore::MediaSessionClient::stopPlayingToPlaybackTarget): Deleted.
+        * platform/audio/MediaSessionManager.cpp:
+        (WebCore::MediaSessionManager::sessionWillBeginPlayback):
+        (WebCore::MediaSessionManager::sessionCanLoadMedia):
+        (WebCore::MediaSessionManager::sessionShouldBeginPlayingToWirelessPlaybackTarget): Deleted.
+        * platform/audio/MediaSessionManager.h:
+        * platform/graphics/MediaPlaybackTargetClient.h: Copied from Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h.
+        (WebCore::MediaPlaybackTargetClient::~MediaPlaybackTargetClient):
+        (WebCore::MediaPlaybackTargetPickerClient::~MediaPlaybackTargetPickerClient): Deleted.
+        * platform/graphics/MediaPlaybackTargetPicker.cpp:
+        (WebCore::MediaPlaybackTargetPicker::showPlaybackTargetPicker):
+        (WebCore::MediaPlaybackTargetPicker::startingMonitoringPlaybackTargets):
+        (WebCore::MediaPlaybackTargetPicker::stopMonitoringPlaybackTargets):
+        * platform/graphics/MediaPlaybackTargetPicker.h:
+        * platform/graphics/MediaPlaybackTargetPickerClient.h: Removed.
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::setShouldPlayToPlaybackTarget):
+        (WebCore::MediaPlayer::startPlayingToPlaybackTarget): Deleted.
+        (WebCore::MediaPlayer::stopPlayingToPlaybackTarget): Deleted.
+        * platform/graphics/MediaPlayer.h:
+        * platform/graphics/MediaPlayerPrivate.h:
+        (WebCore::MediaPlayerPrivateInterface::setShouldPlayToPlaybackTarget):
+        (WebCore::MediaPlayerPrivateInterface::startPlayingToPlaybackTarget): Deleted.
+        (WebCore::MediaPlayerPrivateInterface::stopPlayingToPlaybackTarget): Deleted.
+        * platform/graphics/avfoundation/WebMediaSessionManagerMac.cpp: Added.
+        (WebCore::WebMediaSessionManagerMac::singleton):
+        (WebCore::WebMediaSessionManagerMac::WebMediaSessionManagerMac):
+        (WebCore::WebMediaSessionManagerMac::~WebMediaSessionManagerMac):
+        (WebCore::WebMediaSessionManagerMac::targetPicker):
+        * platform/graphics/avfoundation/WebMediaSessionManagerMac.h: Added.
+        * platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.h:
+        * platform/graphics/avfoundation/objc/MediaPlaybackTargetPickerMac.mm:
+        (WebCore::MediaPlaybackTargetPickerMac::currentDeviceDidChange):
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayer):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setShouldPlayToPlaybackTarget):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget): Deleted.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget): Deleted.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setShouldPlayToPlaybackTarget):
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::togglePlayingToPlaybackTarget): Deleted.
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::startPlayingToPlaybackTarget): Deleted.
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::stopPlayingToPlaybackTarget): Deleted.
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
+        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+        (WebCore::MediaPlayerPrivateQTKit::setShouldPlayToPlaybackTarget):
+        (WebCore::MediaPlayerPrivateQTKit::togglePlayingToPlaybackTarget): Deleted.
+        (WebCore::MediaPlayerPrivateQTKit::startPlayingToPlaybackTarget): Deleted.
+        (WebCore::MediaPlayerPrivateQTKit::stopPlayingToPlaybackTarget): Deleted.
+        * testing/Internals.cpp:
+        (WebCore::Internals::isPagePlayingAudio):
+
 2015-04-21  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [iOS] When computing visible rects for tiling, stop searching at UIWindows
index 7adade0..800eede 100644 (file)
@@ -1787,6 +1787,7 @@ Controller.prototype = {
                 this.controls.volumeBox.style.display = "none";
             else
                 this.controls.muteBox.style.display = "none";
+            this.showControls();
         } else {
             this.controls.inlinePlaybackPlaceholder.classList.add(this.ClassNames.hidden);
             this.controls.wirelessTargetPicker.classList.remove(this.ClassNames.playing);
diff --git a/Source/WebCore/Modules/mediasession/WebMediaSessionManager.cpp b/Source/WebCore/Modules/mediasession/WebMediaSessionManager.cpp
new file mode 100644 (file)
index 0000000..61c4fdd
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebMediaSessionManager.h"
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+
+#include "FloatRect.h"
+#include "MediaPlaybackTargetPickerMac.h"
+#include "WebMediaSessionManagerClient.h"
+
+namespace WebCore {
+
+struct ClientState {
+    explicit ClientState(WebMediaSessionManagerClient& client, uint64_t contextId)
+        : client(&client)
+        , contextId(contextId)
+    {
+    }
+
+    WebMediaSessionManagerClient* client { nullptr };
+    uint64_t contextId { 0 };
+    WebCore::MediaProducer::MediaStateFlags flags { WebCore::MediaProducer::IsNotPlaying };
+    bool requestedPicker { false };
+};
+
+static bool flagsAreSet(MediaProducer::MediaStateFlags value, unsigned flags)
+{
+    return value & flags;
+}
+
+WebMediaSessionManager::WebMediaSessionManager()
+    : m_taskTimer(RunLoop::current(), this, &WebMediaSessionManager::taskTimerFired)
+{
+}
+
+WebMediaSessionManager::~WebMediaSessionManager()
+{
+}
+
+uint64_t WebMediaSessionManager::addPlaybackTargetPickerClient(WebMediaSessionManagerClient& client, uint64_t contextId)
+{
+    size_t index = find(&client, contextId);
+    ASSERT(index == notFound);
+    if (index != notFound)
+        return 0;
+
+    m_clientState.append(std::make_unique<ClientState>(client, contextId));
+
+    if (m_externalOutputDeviceAvailable || m_playbackTarget) {
+
+        TaskCallback callback = std::make_tuple(&client, contextId, [this](ClientState& state) {
+
+            if (m_externalOutputDeviceAvailable)
+                state.client->externalOutputDeviceAvailableDidChange(state.contextId, true);
+
+            if (m_playbackTarget) {
+                state.client->setPlaybackTarget(state.contextId, *m_playbackTarget.copyRef());
+
+                if (m_clientState.size() == 1 && m_playbackTarget->hasActiveRoute())
+                    state.client->setShouldPlayToPlaybackTarget(state.contextId, true);
+            }
+        });
+
+        m_taskQueue.append(callback);
+        m_taskTimer.startOneShot(0);
+    }
+
+    return contextId;
+}
+
+void WebMediaSessionManager::removePlaybackTargetPickerClient(WebMediaSessionManagerClient& client, uint64_t contextId)
+{
+    size_t index = find(&client, contextId);
+    ASSERT(index != notFound);
+    if (index == notFound)
+        return;
+
+    m_clientState.remove(index);
+    configurePlaybackTargetMonitoring();
+
+    if (m_playbackTarget && m_clientState.size() == 1 && m_playbackTarget->hasActiveRoute())
+        m_clientState[0]->client->setShouldPlayToPlaybackTarget(m_clientState[0]->contextId, true);
+}
+
+void WebMediaSessionManager::removeAllPlaybackTargetPickerClients(WebMediaSessionManagerClient& client)
+{
+    for (size_t i = m_clientState.size(); i > 0; --i) {
+        if (m_clientState[i - 1]->client == &client)
+            m_clientState.remove(i - 1);
+    }
+}
+
+void WebMediaSessionManager::showPlaybackTargetPicker(WebMediaSessionManagerClient& client, uint64_t contextId, const IntRect& rect, bool isVideo)
+{
+    size_t index = find(&client, contextId);
+    ASSERT(index != notFound);
+    if (index == notFound)
+        return;
+
+    for (auto& state : m_clientState)
+        state->requestedPicker = (state->contextId == contextId && state->client == &client);
+
+    targetPicker().showPlaybackTargetPicker(FloatRect(rect), isVideo);
+}
+
+void WebMediaSessionManager::clientStateDidChange(WebMediaSessionManagerClient& client, uint64_t contextId, MediaProducer::MediaStateFlags newFlags)
+{
+    size_t index = find(&client, contextId);
+    ASSERT(index != notFound);
+    if (index == notFound)
+        return;
+
+    auto& changedClientState = m_clientState[index];
+    MediaProducer::MediaStateFlags oldFlags = changedClientState->flags;
+    if (newFlags == oldFlags)
+        return;
+
+    changedClientState->flags = newFlags;
+    if (!flagsAreSet(oldFlags, MediaProducer::RequiresPlaybackTargetMonitoring) && flagsAreSet(newFlags, MediaProducer::RequiresPlaybackTargetMonitoring))
+        configurePlaybackTargetMonitoring();
+
+    if (!flagsAreSet(newFlags, MediaProducer::IsPlayingVideo))
+        return;
+
+    // Do not interrupt another element already playing to a device.
+    for (auto& state : m_clientState) {
+        if (state->contextId == contextId && state->client == &client)
+            continue;
+
+        if (flagsAreSet(state->flags, MediaProducer::IsPlayingVideo) && flagsAreSet(state->flags, MediaProducer::IsPlayingToExternalDevice))
+            return;
+    }
+
+    if (m_playbackTarget && m_playbackTarget->hasActiveRoute()) {
+
+        for (auto& state : m_clientState) {
+            if (state->contextId == contextId && state->client == &client)
+                continue;
+            state->client->setShouldPlayToPlaybackTarget(state->contextId, false);
+        }
+
+        changedClientState->client->setShouldPlayToPlaybackTarget(changedClientState->contextId, true);
+    }
+
+    if (index && m_clientState.size() > 1)
+        std::swap(m_clientState.at(index), m_clientState.at(0));
+}
+
+void WebMediaSessionManager::setPlaybackTarget(Ref<MediaPlaybackTarget>&& target)
+{
+    m_playbackTarget = WTF::move(target);
+
+    size_t indexThatRequestedPicker = notFound;
+    for (size_t i = 0; i < m_clientState.size(); ++i) {
+        auto& state = m_clientState[i];
+        state->client->setPlaybackTarget(state->contextId, *m_playbackTarget.copyRef());
+        if (state->requestedPicker) {
+            indexThatRequestedPicker = i;
+            continue;
+        }
+        state->client->setShouldPlayToPlaybackTarget(state->contextId, false);
+        state->requestedPicker = false;
+    }
+
+    if (indexThatRequestedPicker == notFound)
+        return;
+
+    auto& state = m_clientState[indexThatRequestedPicker];
+    state->client->setShouldPlayToPlaybackTarget(state->contextId, true);
+    state->requestedPicker = false;
+}
+
+void WebMediaSessionManager::externalOutputDeviceAvailableDidChange(bool available)
+{
+    if (m_externalOutputDeviceAvailable == available)
+        return;
+
+    m_externalOutputDeviceAvailable = available;
+    for (auto& state : m_clientState)
+        state->client->externalOutputDeviceAvailableDidChange(state->contextId, available);
+}
+
+void WebMediaSessionManager::configurePlaybackTargetMonitoring()
+{
+    bool monitoringRequired = false;
+    for (auto& state : m_clientState) {
+        if (state->flags & MediaProducer::RequiresPlaybackTargetMonitoring) {
+            monitoringRequired = true;
+            break;
+        }
+    }
+
+    if (monitoringRequired)
+        targetPicker().startingMonitoringPlaybackTargets();
+    else
+        targetPicker().stopMonitoringPlaybackTargets();
+}
+
+void WebMediaSessionManager::taskTimerFired()
+{
+    auto taskQueue = WTF::move(m_taskQueue);
+    if (taskQueue.isEmpty())
+        return;
+
+    for (auto& task : taskQueue) {
+        size_t index = find(std::get<0>(task), std::get<1>(task));
+
+        if (index == notFound)
+            continue;
+
+        std::get<2>(task)(*m_clientState[index]);
+    }
+}
+
+size_t WebMediaSessionManager::find(WebMediaSessionManagerClient* client, uint64_t contextId)
+{
+    for (size_t i = 0; i < m_clientState.size(); ++i) {
+        if (m_clientState[i]->contextId == contextId && m_clientState[i]->client == client)
+            return i;
+    }
+
+    return notFound;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
diff --git a/Source/WebCore/Modules/mediasession/WebMediaSessionManager.h b/Source/WebCore/Modules/mediasession/WebMediaSessionManager.h
new file mode 100644 (file)
index 0000000..16b9aac
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebMediaSessionManager_h
+#define WebMediaSessionManager_h
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+
+#include "MediaPlaybackTargetPicker.h"
+#include "MediaProducer.h"
+#include "Timer.h"
+#include <wtf/Ref.h>
+#include <wtf/RefPtr.h>
+#include <wtf/RunLoop.h>
+
+namespace WebCore {
+
+struct ClientState;
+class IntRect;
+class WebMediaSessionManagerClient;
+
+class WebMediaSessionManager : public MediaPlaybackTargetPicker::Client {
+    WTF_MAKE_NONCOPYABLE(WebMediaSessionManager);
+public:
+
+    WEBCORE_EXPORT uint64_t addPlaybackTargetPickerClient(WebMediaSessionManagerClient&, uint64_t);
+    WEBCORE_EXPORT void removePlaybackTargetPickerClient(WebMediaSessionManagerClient&, uint64_t);
+    WEBCORE_EXPORT void removeAllPlaybackTargetPickerClients(WebMediaSessionManagerClient&);
+    WEBCORE_EXPORT void showPlaybackTargetPicker(WebMediaSessionManagerClient&, uint64_t, const IntRect&, bool);
+    WEBCORE_EXPORT void clientStateDidChange(WebMediaSessionManagerClient&, uint64_t, WebCore::MediaProducer::MediaStateFlags);
+
+protected:
+    WebMediaSessionManager();
+    virtual ~WebMediaSessionManager();
+
+    virtual WebCore::MediaPlaybackTargetPicker& targetPicker() = 0;
+
+private:
+
+    // MediaPlaybackTargetPicker::Client
+    virtual void setPlaybackTarget(Ref<WebCore::MediaPlaybackTarget>&&) override;
+    virtual void externalOutputDeviceAvailableDidChange(bool) override;
+
+    size_t find(WebMediaSessionManagerClient*, uint64_t);
+    void configurePlaybackTargetMonitoring();
+    void taskTimerFired();
+
+    typedef std::tuple<WebMediaSessionManagerClient*, uint64_t, std::function<void(ClientState&)>> TaskCallback;
+    Vector<TaskCallback> m_taskQueue;
+    RunLoop::Timer<WebMediaSessionManager> m_taskTimer;
+
+    Vector<std::unique_ptr<ClientState>> m_clientState;
+    RefPtr<MediaPlaybackTarget> m_playbackTarget;
+    bool m_externalOutputDeviceAvailable { false };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+#endif // WebMediaSessionManager_h
diff --git a/Source/WebCore/Modules/mediasession/WebMediaSessionManagerClient.h b/Source/WebCore/Modules/mediasession/WebMediaSessionManagerClient.h
new file mode 100644 (file)
index 0000000..4b7e8d6
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebMediaSessionManagerClient_h
+#define WebMediaSessionManagerClient_h
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+#include "MediaPlaybackTarget.h"
+#include "MediaProducer.h"
+
+namespace WebCore {
+
+class MediaPlaybackTarget;
+
+class WebMediaSessionManagerClient {
+public:
+    virtual ~WebMediaSessionManagerClient() { }
+
+    virtual void setPlaybackTarget(uint64_t, Ref<MediaPlaybackTarget>&&) = 0;
+    virtual void externalOutputDeviceAvailableDidChange(uint64_t, bool) = 0;
+    virtual void setShouldPlayToPlaybackTarget(uint64_t, bool) = 0;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+#endif // WebMediaSessionManagerClient_h
index 865a699..7b3d80a 100644 (file)
@@ -1006,9 +1006,12 @@ void AudioContext::mediaCanStart()
     removeBehaviorRestriction(AudioContext::RequirePageConsentForAudioStartRestriction);
 }
 
-bool AudioContext::isPlayingAudio()
+MediaProducer::MediaStateFlags AudioContext::mediaState() const
 {
-    return !m_isStopScheduled && m_destinationNode && m_destinationNode->isPlayingAudio();
+    if (!m_isStopScheduled && m_destinationNode && m_destinationNode->isPlayingAudio())
+        return MediaProducer::IsPlayingAudio;
+
+    return MediaProducer::IsNotPlaying;
 }
 
 void AudioContext::pageMutedStateDidChange()
index 4c4209b..8940520 100644 (file)
 #include "AsyncAudioDecoder.h"
 #include "AudioBus.h"
 #include "AudioDestinationNode.h"
-#include "AudioProducer.h"
 #include "EventListener.h"
 #include "EventTarget.h"
 #include "MediaCanStartListener.h"
+#include "MediaProducer.h"
 #include "MediaSession.h"
 #include <atomic>
 #include <wtf/HashSet.h>
@@ -76,7 +76,7 @@ class PeriodicWave;
 // AudioContext is the cornerstone of the web audio API and all AudioNodes are created from it.
 // For thread safety between the audio thread and the main thread, it has a rendering graph locking mechanism. 
 
-class AudioContext : public ActiveDOMObject, public ThreadSafeRefCounted<AudioContext>, public EventTargetWithInlineData, public MediaCanStartListener, public AudioProducer, private MediaSessionClient {
+class AudioContext : public ActiveDOMObject, public ThreadSafeRefCounted<AudioContext>, public EventTargetWithInlineData, public MediaCanStartListener, public MediaProducer, private MediaSessionClient {
 public:
     // Create an AudioContext for rendering to the audio hardware.
     static RefPtr<AudioContext> create(Document&, ExceptionCode&);
@@ -280,8 +280,8 @@ private:
 
     virtual void mediaCanStart() override;
 
-    // AudioProducer
-    virtual bool isPlayingAudio() override;
+    // MediaProducer
+    virtual MediaProducer::MediaStateFlags mediaState() const override;
     virtual void pageMutedStateDidChange() override;
 
     // The context itself keeps a reference to all source nodes.  The source nodes, then reference all nodes they're connected to.
index 87d2e77..7639d7f 100644 (file)
                070756DE14239B4E00414161 /* JSTextTrackCue.h in Headers */ = {isa = PBXBuildFile; fileRef = 070756D814239B4B00414161 /* JSTextTrackCue.h */; };
                070756DF14239B4E00414161 /* JSTextTrackCueList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 070756D914239B4C00414161 /* JSTextTrackCueList.cpp */; };
                070756E014239B4E00414161 /* JSTextTrackCueList.h in Headers */ = {isa = PBXBuildFile; fileRef = 070756DA14239B4E00414161 /* JSTextTrackCueList.h */; };
+               0709D78E1AE55554004E42F8 /* WebMediaSessionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0709D78C1AE55554004E42F8 /* WebMediaSessionManager.cpp */; };
+               0709D78F1AE55554004E42F8 /* WebMediaSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0709D78D1AE55554004E42F8 /* WebMediaSessionManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0709D7921AE5557E004E42F8 /* WebMediaSessionManagerMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0709D7901AE5557E004E42F8 /* WebMediaSessionManagerMac.cpp */; };
+               0709D7931AE5557E004E42F8 /* WebMediaSessionManagerMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 0709D7911AE5557E004E42F8 /* WebMediaSessionManagerMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0709D7951AE55A29004E42F8 /* WebMediaSessionManagerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 0709D7941AE55A29004E42F8 /* WebMediaSessionManagerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0709FC4E1025DEE30059CDBA /* AccessibilitySlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 0709FC4D1025DEE30059CDBA /* AccessibilitySlider.h */; };
                070E09191875EEFC003A1D3C /* MediaSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 070E09181875ED93003A1D3C /* MediaSession.h */; settings = {ATTRIBUTES = (Private, ); }; };
                070E091B1875EF71003A1D3C /* MediaSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 070E091A1875EF71003A1D3C /* MediaSession.cpp */; };
                078E43DA1ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 078E43D81ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.h */; settings = {ATTRIBUTES = (Private, ); }; };
                078E43DD1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 078E43DB1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
                078E43DE1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 078E43DC1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.mm */; };
-               079216551AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               079216551AA560AA00A3C049 /* MediaPlaybackTargetClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 079216531AA560AA00A3C049 /* MediaPlaybackTargetClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
                07941791166E855F009416C2 /* InbandTextTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0794178F166E855F009416C2 /* InbandTextTrack.cpp */; };
                07941792166E855F009416C2 /* InbandTextTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = 07941790166E855F009416C2 /* InbandTextTrack.h */; };
                07941794166EA04E009416C2 /* InbandTextTrackPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 07941793166EA04E009416C2 /* InbandTextTrackPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52CCA9E815E3F64C0053C77F /* DOMDOMNamedFlowCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 52CCA9E515E3F64C0053C77F /* DOMDOMNamedFlowCollection.h */; };
                52CCA9E915E3F64C0053C77F /* DOMDOMNamedFlowCollection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52CCA9E615E3F64C0053C77F /* DOMDOMNamedFlowCollection.mm */; };
                52CCA9EA15E3F64C0053C77F /* DOMDOMNamedFlowCollectionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 52CCA9E715E3F64C0053C77F /* DOMDOMNamedFlowCollectionInternal.h */; };
-               52E2CAFC19FF0207001EEB4F /* AudioProducer.h in Headers */ = {isa = PBXBuildFile; fileRef = 52E2CAFB19FF0207001EEB4F /* AudioProducer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               52E2CAFC19FF0207001EEB4F /* MediaProducer.h in Headers */ = {isa = PBXBuildFile; fileRef = 52E2CAFB19FF0207001EEB4F /* MediaProducer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52F10865162B6DA4009AC81E /* MixedContentChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52F10862162B6D82009AC81E /* MixedContentChecker.cpp */; };
                52F10866162B6DA8009AC81E /* MixedContentChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 52F10863162B6D82009AC81E /* MixedContentChecker.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52F52E1114A0134F00ACC397 /* NSScrollerImpDetails.mm in Sources */ = {isa = PBXBuildFile; fileRef = 52F52E1014A0134F00ACC397 /* NSScrollerImpDetails.mm */; };
                070756D814239B4B00414161 /* JSTextTrackCue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTextTrackCue.h; sourceTree = "<group>"; };
                070756D914239B4C00414161 /* JSTextTrackCueList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTextTrackCueList.cpp; sourceTree = "<group>"; };
                070756DA14239B4E00414161 /* JSTextTrackCueList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTextTrackCueList.h; sourceTree = "<group>"; };
+               0709D78C1AE55554004E42F8 /* WebMediaSessionManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebMediaSessionManager.cpp; path = mediasession/WebMediaSessionManager.cpp; sourceTree = "<group>"; };
+               0709D78D1AE55554004E42F8 /* WebMediaSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebMediaSessionManager.h; path = mediasession/WebMediaSessionManager.h; sourceTree = "<group>"; };
+               0709D7901AE5557E004E42F8 /* WebMediaSessionManagerMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebMediaSessionManagerMac.cpp; sourceTree = "<group>"; };
+               0709D7911AE5557E004E42F8 /* WebMediaSessionManagerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebMediaSessionManagerMac.h; sourceTree = "<group>"; };
+               0709D7941AE55A29004E42F8 /* WebMediaSessionManagerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebMediaSessionManagerClient.h; path = mediasession/WebMediaSessionManagerClient.h; sourceTree = "<group>"; };
                0709FC4D1025DEE30059CDBA /* AccessibilitySlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilitySlider.h; sourceTree = "<group>"; };
                070DD8F50F01868000727DEB /* mediaControls.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mediaControls.css; sourceTree = "<group>"; };
                070E09181875ED93003A1D3C /* MediaSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaSession.h; sourceTree = "<group>"; };
                078E43D81ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTargetPicker.h; sourceTree = "<group>"; };
                078E43DB1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediaPlaybackTargetPickerMac.h; path = objc/MediaPlaybackTargetPickerMac.h; sourceTree = "<group>"; };
                078E43DC1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MediaPlaybackTargetPickerMac.mm; path = objc/MediaPlaybackTargetPickerMac.mm; sourceTree = "<group>"; };
-               079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTargetPickerClient.h; sourceTree = "<group>"; };
+               079216531AA560AA00A3C049 /* MediaPlaybackTargetClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTargetClient.h; sourceTree = "<group>"; };
                0794178F166E855F009416C2 /* InbandTextTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InbandTextTrack.cpp; sourceTree = "<group>"; };
                07941790166E855F009416C2 /* InbandTextTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrack.h; sourceTree = "<group>"; };
                07941793166EA04E009416C2 /* InbandTextTrackPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrackPrivate.h; sourceTree = "<group>"; };
                52CCA9E515E3F64C0053C77F /* DOMDOMNamedFlowCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMDOMNamedFlowCollection.h; sourceTree = "<group>"; };
                52CCA9E615E3F64C0053C77F /* DOMDOMNamedFlowCollection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMDOMNamedFlowCollection.mm; sourceTree = "<group>"; };
                52CCA9E715E3F64C0053C77F /* DOMDOMNamedFlowCollectionInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMDOMNamedFlowCollectionInternal.h; sourceTree = "<group>"; };
-               52E2CAFB19FF0207001EEB4F /* AudioProducer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioProducer.h; sourceTree = "<group>"; };
+               52E2CAFB19FF0207001EEB4F /* MediaProducer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaProducer.h; sourceTree = "<group>"; };
                52F10862162B6D82009AC81E /* MixedContentChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MixedContentChecker.cpp; sourceTree = "<group>"; };
                52F10863162B6D82009AC81E /* MixedContentChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MixedContentChecker.h; sourceTree = "<group>"; };
                52F52E1014A0134F00ACC397 /* NSScrollerImpDetails.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NSScrollerImpDetails.mm; sourceTree = "<group>"; };
                        tabWidth = 4;
                        usesTabs = 0;
                };
+               0709D78B1AE5552E004E42F8 /* mediasession */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0709D7941AE55A29004E42F8 /* WebMediaSessionManagerClient.h */,
+                               0709D78C1AE55554004E42F8 /* WebMediaSessionManager.cpp */,
+                               0709D78D1AE55554004E42F8 /* WebMediaSessionManager.h */,
+                       );
+                       name = mediasession;
+                       sourceTree = "<group>";
+               };
                07221B4617CEC32700848E51 /* mediastream */ = {
                        isa = PBXGroup;
                        children = (
                076F0D0812B8192700C26AA4 /* avfoundation */ = {
                        isa = PBXGroup;
                        children = (
-                               071E496F1AD5AB5E008A50B4 /* MediaPlaybackTargetMac.h */,
-                               071E496D1AD5AA0D008A50B4 /* MediaPlaybackTargetMac.mm */,
+                               0709D7901AE5557E004E42F8 /* WebMediaSessionManagerMac.cpp */,
+                               0709D7911AE5557E004E42F8 /* WebMediaSessionManagerMac.h */,
                                DF9AFD6F13FC31B00015FEB7 /* objc */,
                                CDE3A85217F5FCE600C5BE20 /* AudioTrackPrivateAVF.h */,
                                07E9E12F18F62B370011A3A4 /* InbandMetadataTextTrackPrivateAVF.cpp */,
                                07E9E12D18F5E2760011A3A4 /* InbandMetadataTextTrackPrivateAVF.h */,
                                07B442D4166C70B000556CAD /* InbandTextTrackPrivateAVF.cpp */,
                                07B442D5166C70B000556CAD /* InbandTextTrackPrivateAVF.h */,
+                               071E496F1AD5AB5E008A50B4 /* MediaPlaybackTargetMac.h */,
+                               071E496D1AD5AA0D008A50B4 /* MediaPlaybackTargetMac.mm */,
                                078E43DB1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.h */,
                                078E43DC1ABB6F6F001C2FA6 /* MediaPlaybackTargetPickerMac.mm */,
                                076F0D0912B8192700C26AA4 /* MediaPlayerPrivateAVFoundation.cpp */,
                                8538F0000AD71770006A81D1 /* AbstractView.idl */,
                                BCF48CE61370D114004E87D6 /* AdjustViewSizeOrNot.h */,
                                CEDA12D6152CA1CB00D9E08D /* AlternativeTextClient.h */,
-                               52E2CAFB19FF0207001EEB4F /* AudioProducer.h */,
                                45830D4B1679B4F800ACF8C3 /* AutoscrollController.cpp */,
                                45830D4C1679B4F800ACF8C3 /* AutoscrollController.h */,
                                BC124EE40C2641CD009E2349 /* BarProp.cpp */,
                                932AD70417EFA2C30038F8FF /* MainFrame.h */,
                                BC59DEFA169DEDD80016AC34 /* make_settings.pl */,
                                931BCC601124DFCB00BE70DD /* MediaCanStartListener.h */,
+                               52E2CAFB19FF0207001EEB4F /* MediaProducer.h */,
                                93EB355E09E37FD600F43799 /* MouseEventWithHitTestResults.cpp */,
                                935C476209AC4CE600A6AAB4 /* MouseEventWithHitTestResults.h */,
                                A9C6E5A30D746458006442E9 /* Navigator.cpp */,
                                9712A55315004E3C0048AF10 /* indexeddb */,
                                AA7EA0A917557B1C00DF4643 /* indieui */,
                                CD9A37F517C7D93600C5FA7A /* mediacontrols */,
+                               0709D78B1AE5552E004E42F8 /* mediasession */,
                                B1A942DD15B5CE2200D525D1 /* mediasource */,
                                07221B4617CEC32700848E51 /* mediastream */,
                                333F703D0FB49C16008E12A6 /* notifications */,
                                07F876831AD4A94500905849 /* MediaPlaybackTargetContext.h */,
                                078E43D71ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.cpp */,
                                078E43D81ABB6C7E001C2FA6 /* MediaPlaybackTargetPicker.h */,
-                               079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */,
+                               079216531AA560AA00A3C049 /* MediaPlaybackTargetClient.h */,
                                E4B41E0C0CBF90BD00AF2ECE /* MediaPlayer.cpp */,
                                E4B41E0D0CBF90BD00AF2ECE /* MediaPlayer.h */,
                                079F5E4B0F3BEBEA005E0782 /* MediaPlayerPrivate.h */,
                                FD359190138DB22000E1EBEC /* AudioParamTimeline.h in Headers */,
                                FD31602012B0267600C1A359 /* AudioProcessingEvent.h in Headers */,
                                FD31608412B026F700C1A359 /* AudioProcessor.h in Headers */,
-                               52E2CAFC19FF0207001EEB4F /* AudioProducer.h in Headers */,
                                FD31608612B026F700C1A359 /* AudioResampler.h in Headers */,
                                FD31608812B026F700C1A359 /* AudioResamplerKernel.h in Headers */,
                                FD8C46EC154608E700A5910C /* AudioScheduledSourceNode.h in Headers */,
                                1A8F6BC30DB55CDC001DB794 /* DOMApplicationCache.h in Headers */,
                                85D389B20A991A7F00282145 /* DOMAttr.h in Headers */,
                                85E7118D0AC5D5350053270F /* DOMAttrInternal.h in Headers */,
+                               0709D7951AE55A29004E42F8 /* WebMediaSessionManagerClient.h in Headers */,
                                76FB9FEB19A7284B00420562 /* DOMAutocompleteErrorEvent.h in Headers */,
                                76FB9FED19A7284B00420562 /* DOMAutocompleteErrorEventInternal.h in Headers */,
                                BC946EEF107FDBAC00857193 /* DOMBeforeLoadEvent.h in Headers */,
                                DF9AFD7213FC31D80015FEB7 /* MediaPlayerPrivateAVFoundationObjC.h in Headers */,
                                CDC8B5A3180463470016E685 /* MediaPlayerPrivateMediaSourceAVFObjC.h in Headers */,
                                E44613E60CD681A900FADA75 /* MediaPlayerPrivateQTKit.h in Headers */,
+                               52E2CAFC19FF0207001EEB4F /* MediaProducer.h in Headers */,
                                4E19592A0A39DACC00220FE5 /* MediaQuery.h in Headers */,
                                071E49701AD5AB5E008A50B4 /* MediaPlaybackTargetMac.h in Headers */,
                                4E19592C0A39DACC00220FE5 /* MediaQueryEvaluator.h in Headers */,
                                E10B9B6C0B747599003ED890 /* NativeXPathNSResolver.h in Headers */,
                                93CCF0270AF6C52900018E89 /* NavigationAction.h in Headers */,
                                979F43D41075E44A0000F83B /* NavigationScheduler.h in Headers */,
+                               0709D7931AE5557E004E42F8 /* WebMediaSessionManagerMac.h in Headers */,
                                A9C6E5A60D746458006442E9 /* Navigator.h in Headers */,
                                ADDA94C219687AA500453029 /* JSDocumentCustom.h in Headers */,
                                E12719C70EEEC16800F61213 /* NavigatorBase.h in Headers */,
                                9391A991162746CB00297330 /* ScrollingCoordinatorMac.h in Headers */,
                                93C38BFF164473C700091EB2 /* ScrollingStateFixedNode.h in Headers */,
                                0FEA3E7B191B2FC5000F1B55 /* ScrollingStateFrameScrollingNode.h in Headers */,
-                               079216551AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h in Headers */,
+                               079216551AA560AA00A3C049 /* MediaPlaybackTargetClient.h in Headers */,
                                931CBD0D161A44E900E4C874 /* ScrollingStateNode.h in Headers */,
                                0FEA3E84191B31BF000F1B55 /* ScrollingStateOverflowScrollingNode.h in Headers */,
                                931CBD0F161A44E900E4C874 /* ScrollingStateScrollingNode.h in Headers */,
                                B2227A810D00BF220071B782 /* SVGPathSegList.h in Headers */,
                                8476C9E611DF6A0B00555B02 /* SVGPathSegListBuilder.h in Headers */,
                                084A0829128D7867002DB1F1 /* SVGPathSegListPropertyTearOff.h in Headers */,
+                               0709D78F1AE55554004E42F8 /* WebMediaSessionManager.h in Headers */,
                                84B6B978120F13E500B8EFAF /* SVGPathSegListSource.h in Headers */,
                                83C1D435178D5AB500141E68 /* SVGPathSegMovetoAbs.h in Headers */,
                                4198BDF11A81143100B22FB5 /* ReadableStreamJSSource.h in Headers */,
                                BC904B760D10998F00680D32 /* ClassNodeList.cpp in Sources */,
                                A14090FB1AA51E1D0091191A /* ContentFilterUnblockHandlerCocoa.mm in Sources */,
                                BCC0657D0F3CE1B700CD2D87 /* ClientRect.cpp in Sources */,
+                               0709D7921AE5557E004E42F8 /* WebMediaSessionManagerMac.cpp in Sources */,
                                BCC065800F3CE1B700CD2D87 /* ClientRectList.cpp in Sources */,
                                85031B3F0A44EFC700F992E0 /* ClipboardEvent.cpp in Sources */,
                                CDEA76351460B71A008B31F1 /* Clock.cpp in Sources */,
                                85CA975D0A962E5400690CCF /* DOMDocumentType.mm in Sources */,
                                8518DCEA0A9CC80D0091B7A6 /* DOMDOMImplementation.mm in Sources */,
                                52CCA9E915E3F64C0053C77F /* DOMDOMNamedFlowCollection.mm in Sources */,
+                               0709D78E1AE55554004E42F8 /* WebMediaSessionManager.cpp in Sources */,
                                2D9A247315B9C2D100D34527 /* DOMDOMSecurityPolicy.mm in Sources */,
                                7694565C1214DB630007CBAE /* DOMDOMTokenList.mm in Sources */,
                                7AABA25914BC613300AA9A11 /* DOMEditor.cpp in Sources */,
index 4f75a36..4fa02bc 100644 (file)
@@ -31,7 +31,6 @@
 #include "AXObjectCache.h"
 #include "AnimationController.h"
 #include "Attr.h"
-#include "AudioProducer.h"
 #include "CDATASection.h"
 #include "CSSFontSelector.h"
 #include "CSSStyleDeclaration.h"
 #include "Logging.h"
 #include "MainFrame.h"
 #include "MediaCanStartListener.h"
+#include "MediaProducer.h"
 #include "MediaQueryList.h"
 #include "MediaQueryMatcher.h"
 #include "MouseEventWithHitTestResults.h"
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-#include "HTMLVideoElement.h"
+#include "MediaPlaybackTargetClient.h"
 #endif
 
 using namespace WTF;
@@ -523,7 +523,6 @@ Document::Document(Frame* frame, const URL& url, unsigned documentClasses, unsig
     , m_renderTreeBeingDestroyed(false)
     , m_hasPreparedForDestruction(false)
     , m_hasStyleWithViewportUnits(false)
-    , m_isPlayingAudio(false)
 {
     allDocuments().add(this);
 
@@ -3415,13 +3414,13 @@ void Document::updateViewportUnitsOnResize()
     }
 }
 
-void Document::addAudioProducer(AudioProducer* audioProducer)
+void Document::addAudioProducer(MediaProducer* audioProducer)
 {
     m_audioProducers.add(audioProducer);
     updateIsPlayingMedia();
 }
 
-void Document::removeAudioProducer(AudioProducer* audioProducer)
+void Document::removeAudioProducer(MediaProducer* audioProducer)
 {
     m_audioProducers.remove(audioProducer);
     updateIsPlayingMedia();
@@ -3429,18 +3428,14 @@ void Document::removeAudioProducer(AudioProducer* audioProducer)
 
 void Document::updateIsPlayingMedia()
 {
-    bool isPlayingAudio = false;
-    for (auto audioProducer : m_audioProducers) {
-        if (audioProducer->isPlayingAudio()) {
-            isPlayingAudio = true;
-            break;
-        }
-    }
+    MediaProducer::MediaStateFlags state = MediaProducer::IsNotPlaying;
+    for (auto audioProducer : m_audioProducers)
+        state |= audioProducer->mediaState();
 
-    if (isPlayingAudio == m_isPlayingAudio)
+    if (state == m_mediaState)
         return;
 
-    m_isPlayingAudio = isPlayingAudio;
+    m_mediaState = state;
 
     if (page())
         page()->updateIsPlayingMedia();
@@ -6533,72 +6528,85 @@ void Document::setInputCursor(PassRefPtr<InputCursor> cursor)
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-void Document::showPlaybackTargetPicker(const HTMLMediaElement& element)
+static uint64_t nextPlaybackTargetClientContextId()
+{
+    static uint64_t contextId = 0;
+    return ++contextId;
+}
+
+void Document::addPlaybackTargetPickerClient(MediaPlaybackTargetClient& client)
 {
     Page* page = this->page();
     if (!page)
         return;
 
-    page->showPlaybackTargetPicker(view()->lastKnownMousePosition(), is<HTMLVideoElement>(element));
+    ASSERT(!m_clientToIDMap.contains(&client));
+
+    uint64_t contextId = nextPlaybackTargetClientContextId();
+    m_clientToIDMap.add(&client, contextId);
+    m_idToClientMap.add(contextId, &client);
+    page->addPlaybackTargetPickerClient(contextId);
 }
 
-void Document::addPlaybackTargetPickerClient(MediaPlaybackTargetPickerClient& client)
+void Document::removePlaybackTargetPickerClient(MediaPlaybackTargetClient& client)
 {
+    ASSERT(m_clientToIDMap.contains(&client));
+    uint64_t contextId = m_clientToIDMap.get(&client);
+    m_idToClientMap.remove(contextId);
+    m_clientToIDMap.remove(&client);
+
     Page* page = this->page();
     if (!page)
         return;
-
-    m_playbackTargetClients.add(&client);
-
-    RefPtr<MediaPlaybackTarget> target = page->playbackTarget();
-    if (target)
-        client.didChoosePlaybackTarget(*target);
-    client.externalOutputDeviceAvailableDidChange(page->hasWirelessPlaybackTarget());
+    page->removePlaybackTargetPickerClient(contextId);
 }
 
-void Document::removePlaybackTargetPickerClient(MediaPlaybackTargetPickerClient& client)
+void Document::showPlaybackTargetPicker(MediaPlaybackTargetClient& client, bool isVideo)
 {
-    m_playbackTargetClients.remove(&client);
-    configurePlaybackTargetMonitoring();
+    Page* page = this->page();
+    if (!page)
+        return;
+
+    ASSERT(m_clientToIDMap.contains(&client));
+    page->showPlaybackTargetPicker(m_clientToIDMap.get(&client), view()->lastKnownMousePosition(), isVideo);
 }
 
-void Document::configurePlaybackTargetMonitoring()
+void Document::playbackTargetPickerClientStateDidChange(MediaPlaybackTargetClient& client, MediaProducer::MediaStateFlags state)
 {
     Page* page = this->page();
     if (!page)
         return;
 
-    page->configurePlaybackTargetMonitoring();
+    ASSERT(m_clientToIDMap.contains(&client));
+    page->playbackTargetPickerClientStateDidChange(m_clientToIDMap.get(&client), state);
 }
 
-bool Document::requiresPlaybackTargetRouteMonitoring()
+void Document::playbackTargetAvailabilityDidChange(uint64_t clientId, bool available)
 {
-    for (auto* client : m_playbackTargetClients) {
-        if (client->requiresPlaybackTargetRouteMonitoring()) {
-            return true;
-            break;
-        }
-    }
+    TargetClientToIdMap::iterator it = m_idToClientMap.find(clientId);
+    if (it == m_idToClientMap.end())
+        return;
 
-    return false;
+    it->value->externalOutputDeviceAvailableDidChange(available);
 }
 
-void Document::playbackTargetAvailabilityDidChange(bool available)
+void Document::setPlaybackTarget(uint64_t clientId, Ref<MediaPlaybackTarget>&& target)
 {
-    if (m_playbackTargetsAvailable == available)
+    TargetClientToIdMap::iterator it = m_idToClientMap.find(clientId);
+    if (it == m_idToClientMap.end())
         return;
-    m_playbackTargetsAvailable = available;
 
-    for (auto* client : m_playbackTargetClients)
-        client->externalOutputDeviceAvailableDidChange(available);
+    it->value->setPlaybackTarget(target.copyRef());
 }
 
-void Document::didChoosePlaybackTarget(Ref<MediaPlaybackTarget>&& device)
+void Document::setShouldPlayToPlaybackTarget(uint64_t clientId, bool shouldPlay)
 {
-    for (auto* client : m_playbackTargetClients)
-        client->didChoosePlaybackTarget(device.copyRef());
-}
+    TargetClientToIdMap::iterator it = m_idToClientMap.find(clientId);
+    if (it == m_idToClientMap.end())
+        return;
 
-#endif
+    it->value->setShouldPlayToPlaybackTarget(shouldPlay);
+}
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
 
 } // namespace WebCore
index 0b9e68c..3a99911 100644 (file)
@@ -36,6 +36,7 @@
 #include "DocumentTiming.h"
 #include "FocusDirection.h"
 #include "FontSelector.h"
+#include "MediaProducer.h"
 #include "MutationObserver.h"
 #include "PageVisibilityState.h"
 #include "PlatformEvent.h"
@@ -69,7 +70,6 @@ namespace WebCore {
 
 class AXObjectCache;
 class Attr;
-class AudioProducer;
 class CDATASection;
 class CSSFontSelector;
 class CSSStyleDeclaration;
@@ -126,7 +126,7 @@ class JSNode;
 class Locale;
 class MediaCanStartListener;
 class MediaPlaybackTarget;
-class MediaPlaybackTargetPickerClient;
+class MediaPlaybackTargetClient;
 class MediaQueryList;
 class MediaQueryMatcher;
 class MouseEventWithHitTestResults;
@@ -1229,21 +1229,22 @@ public:
     bool hasStyleWithViewportUnits() const { return m_hasStyleWithViewportUnits; }
     void updateViewportUnitsOnResize();
 
-    WEBCORE_EXPORT void addAudioProducer(AudioProducer*);
-    WEBCORE_EXPORT void removeAudioProducer(AudioProducer*);
-    bool isPlayingAudio() const { return m_isPlayingAudio; }
+    WEBCORE_EXPORT void addAudioProducer(MediaProducer*);
+    WEBCORE_EXPORT void removeAudioProducer(MediaProducer*);
+    MediaProducer::MediaStateFlags mediaState() const { return m_mediaState; }
     WEBCORE_EXPORT void updateIsPlayingMedia();
     void pageMutedStateDidChange();
     WeakPtr<Document> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    void showPlaybackTargetPicker(const HTMLMediaElement&);
-    void didChoosePlaybackTarget(Ref<MediaPlaybackTarget>&&);
-    void addPlaybackTargetPickerClient(MediaPlaybackTargetPickerClient&);
-    void removePlaybackTargetPickerClient(MediaPlaybackTargetPickerClient&);
-    bool requiresPlaybackTargetRouteMonitoring();
-    void configurePlaybackTargetMonitoring();
-    void playbackTargetAvailabilityDidChange(bool);
+    void addPlaybackTargetPickerClient(MediaPlaybackTargetClient&);
+    void removePlaybackTargetPickerClient(MediaPlaybackTargetClient&);
+    void showPlaybackTargetPicker(MediaPlaybackTargetClient&, bool);
+    void playbackTargetPickerClientStateDidChange(MediaPlaybackTargetClient&, MediaProducer::MediaStateFlags);
+
+    void setPlaybackTarget(uint64_t, Ref<MediaPlaybackTarget>&&);
+    void playbackTargetAvailabilityDidChange(uint64_t, bool);
+    void setShouldPlayToPlaybackTarget(uint64_t, bool);
 #endif
 
 protected:
@@ -1684,12 +1685,14 @@ private:
 
     bool m_hasStyleWithViewportUnits;
 
-    HashSet<AudioProducer*> m_audioProducers;
-    bool m_isPlayingAudio;
+    HashSet<MediaProducer*> m_audioProducers;
+    MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    HashSet<WebCore::MediaPlaybackTargetPickerClient*> m_playbackTargetClients;
-    bool m_playbackTargetsAvailable { false };
+    typedef HashMap<uint64_t, WebCore::MediaPlaybackTargetClient*> TargetClientToIdMap;
+    TargetClientToIdMap m_idToClientMap;
+    typedef HashMap<WebCore::MediaPlaybackTargetClient*, uint64_t> TargetIdToClientMap;
+    TargetIdToClientMap m_clientToIDMap;
 #endif
 };
 
index 6404d43..f85e3ac 100644 (file)
@@ -401,8 +401,10 @@ HTMLMediaElement::~HTMLMediaElement()
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent))
+    if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent)) {
+        m_hasPlaybackTargetAvailabilityListeners = false;
         m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
+    }
 #endif
 
     if (m_mediaController) {
@@ -428,7 +430,7 @@ HTMLMediaElement::~HTMLMediaElement()
 
 void HTMLMediaElement::registerWithDocument(Document& document)
 {
-    m_mediaSession->registerWithDocument(document);
+    m_mediaSession->registerWithDocument(*this);
 
     if (m_isWaitingUntilMediaCanStart)
         document.addMediaCanStartListener(this);
@@ -455,7 +457,7 @@ void HTMLMediaElement::registerWithDocument(Document& document)
 
 void HTMLMediaElement::unregisterWithDocument(Document& document)
 {
-    m_mediaSession->unregisterWithDocument(document);
+    m_mediaSession->unregisterWithDocument(*this);
 
     if (m_isWaitingUntilMediaCanStart)
         document.removeMediaCanStartListener(this);
@@ -3017,6 +3019,10 @@ void HTMLMediaElement::setMuted(bool muted)
         }
         scheduleEvent(eventNames().volumechangeEvent);
         document().updateIsPlayingMedia();
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+        m_mediaSession->mediaStateDidChange(*this, mediaState());
+#endif
     }
 #endif
 }
@@ -4292,7 +4298,7 @@ void HTMLMediaElement::mediaPlayerEngineUpdated(MediaPlayer*)
 
     m_havePreparedToPlay = false;
 
-    m_mediaSession->applyMediaPlayerRestrictions(*this);
+    m_mediaSession->mediaEngineUpdated(*this);
 
 #if ENABLE(WEB_AUDIO)
     if (m_audioSourceNode && audioSourceProvider()) {
@@ -4597,9 +4603,13 @@ void HTMLMediaElement::setPlaying(bool playing)
 {
     if (m_playing == playing)
         return;
-    
+
     m_playing = playing;
     document().updateIsPlayingMedia();
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    m_mediaSession->mediaStateDidChange(*this, mediaState());
+#endif
 }
 
 void HTMLMediaElement::setPausedInternal(bool b)
@@ -4689,6 +4699,7 @@ void HTMLMediaElement::clearMediaPlayer(int flags)
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent)) {
+        m_hasPlaybackTargetAvailabilityListeners = false;
         m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
 
         // Send an availability event in case scripts want to hide the picker when the element
@@ -4863,6 +4874,10 @@ void HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPl
 {
     LOG(Media, "HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged(%p) - webkitCurrentPlaybackTargetIsWireless = %s", this, boolString(webkitCurrentPlaybackTargetIsWireless()));
     scheduleEvent(eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent);
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    m_mediaSession->mediaStateDidChange(*this, mediaState());
+#endif
 }
 
 bool HTMLMediaElement::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
@@ -4874,8 +4889,10 @@ bool HTMLMediaElement::addEventListener(const AtomicString& eventType, PassRefPt
     if (!Node::addEventListener(eventType, listener, useCapture))
         return false;
 
-    if (isFirstAvailabilityChangedListener)
+    if (isFirstAvailabilityChangedListener) {
+        m_hasPlaybackTargetAvailabilityListeners = true;
         m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, true);
+    }
 
     LOG(Media, "HTMLMediaElement::addEventListener(%p) - 'webkitplaybacktargetavailabilitychanged'", this);
     
@@ -4893,8 +4910,10 @@ bool HTMLMediaElement::removeEventListener(const AtomicString& eventType, EventL
 
     bool didRemoveLastAvailabilityChangedListener = !hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent);
     LOG(Media, "HTMLMediaElement::removeEventListener(%p) - removed last listener = %s", this, boolString(didRemoveLastAvailabilityChangedListener));
-    if (didRemoveLastAvailabilityChangedListener)
+    if (didRemoveLastAvailabilityChangedListener) {
+        m_hasPlaybackTargetAvailabilityListeners = false;
         m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, false);
+    }
 
     return true;
 }
@@ -4932,16 +4951,10 @@ bool HTMLMediaElement::isPlayingToWirelessPlaybackTarget() const
     return isPlaying;
 }
 
-void HTMLMediaElement::startPlayingToPlaybackTarget()
+void HTMLMediaElement::setShouldPlayToPlaybackTarget(bool shouldPlay)
 {
     if (m_player)
-        m_player->startPlayingToPlaybackTarget();
-}
-
-void HTMLMediaElement::stopPlayingToPlaybackTarget()
-{
-    if (m_player)
-        m_player->stopPlayingToPlaybackTarget();
+        m_player->setShouldPlayToPlaybackTarget(shouldPlay);
 }
 #endif
 
@@ -5473,6 +5486,7 @@ void HTMLMediaElement::createMediaPlayer()
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     if (hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent)) {
+        m_hasPlaybackTargetAvailabilityListeners = true;
         m_mediaSession->setHasPlaybackTargetAvailabilityListeners(*this, true);
         enqueuePlaybackTargetAvailabilityChangedEvent(); // Ensure the event listener gets at least one event.
     }
@@ -6171,9 +6185,29 @@ bool HTMLMediaElement::overrideBackgroundPlaybackRestriction() const
     return false;
 }
 
-bool HTMLMediaElement::isPlayingAudio()
+MediaProducer::MediaStateFlags HTMLMediaElement::mediaState() const
 {
-    return isPlaying() && hasAudio() && !muted();
+
+    MediaStateFlags state = IsNotPlaying;
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    if (isPlayingToWirelessPlaybackTarget())
+        state |= IsPlayingToExternalDevice;
+
+    if (m_hasPlaybackTargetAvailabilityListeners)
+        state |= RequiresPlaybackTargetMonitoring;
+#endif
+
+    if (!isPlaying())
+        return state;
+
+    if (hasAudio() && !muted())
+        state |= IsPlayingAudio;
+
+    if (hasVideo())
+        state |= IsPlayingVideo;
+
+    return state;
 }
 
 void HTMLMediaElement::pageMutedStateDidChange()
index 1409e6b..fd9dca2 100644 (file)
 #if ENABLE(VIDEO)
 #include "HTMLElement.h"
 #include "ActiveDOMObject.h"
-#include "AudioProducer.h"
 #include "GenericEventQueue.h"
 #include "HTMLMediaSession.h"
 #include "MediaCanStartListener.h"
 #include "MediaControllerInterface.h"
 #include "MediaPlayer.h"
+#include "MediaProducer.h"
 #include "PageThrottler.h"
 
 #if ENABLE(VIDEO_TRACK)
@@ -95,7 +95,7 @@ class MediaStream;
 
 class HTMLMediaElement
     : public HTMLElement
-    , private MediaPlayerClient, public MediaPlayerSupportsTypeClient, private MediaCanStartListener, public ActiveDOMObject, public MediaControllerInterface , public MediaSessionClient, private AudioProducer
+    , private MediaPlayerClient, public MediaPlayerSupportsTypeClient, private MediaCanStartListener, public ActiveDOMObject, public MediaControllerInterface , public MediaSessionClient, private MediaProducer
 #if ENABLE(VIDEO_TRACK)
     , private AudioTrackClient
     , private TextTrackClient
@@ -365,8 +365,7 @@ public:
     virtual bool canPlayToWirelessPlaybackTarget() const override;
     virtual bool isPlayingToWirelessPlaybackTarget() const override;
     virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
-    virtual void startPlayingToPlaybackTarget() override;
-    virtual void stopPlayingToPlaybackTarget() override;
+    virtual void setShouldPlayToPlaybackTarget(bool) override;
 #endif
 
     // EventTarget function.
@@ -457,6 +456,8 @@ public:
 
     double maxBufferedTime() const;
 
+    virtual MediaProducer::MediaStateFlags mediaState() const override;
+
 protected:
     HTMLMediaElement(const QualifiedName&, Document&, bool);
     virtual ~HTMLMediaElement();
@@ -723,8 +724,6 @@ private:
     virtual void didReceiveRemoteControlCommand(MediaSession::RemoteControlCommandType) override;
     virtual bool overrideBackgroundPlaybackRestriction() const override;
 
-    // AudioProducer overrides
-    virtual bool isPlayingAudio() override;
     virtual void pageMutedStateDidChange() override;
 
     bool effectiveMuted() const;
@@ -919,6 +918,10 @@ private:
 #if ENABLE(MEDIA_STREAM)
     RefPtr<MediaStream> m_mediaStreamSrcObject;
 #endif
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    bool m_hasPlaybackTargetAvailabilityListeners { false };
+#endif
 };
 
 #if ENABLE(VIDEO_TRACK)
index ac03f3f..b48c7a8 100644 (file)
@@ -36,6 +36,7 @@
 #include "FrameView.h"
 #include "HTMLMediaElement.h"
 #include "HTMLNames.h"
+#include "HTMLVideoElement.h"
 #include "Logging.h"
 #include "MediaSessionManager.h"
 #include "Page.h"
@@ -80,21 +81,21 @@ HTMLMediaSession::HTMLMediaSession(MediaSessionClient& client)
 {
 }
 
-void HTMLMediaSession::registerWithDocument(Document& document)
+void HTMLMediaSession::registerWithDocument(const HTMLMediaElement& element)
 {
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    document.addPlaybackTargetPickerClient(*this);
+    element.document().addPlaybackTargetPickerClient(*this);
 #else
-    UNUSED_PARAM(document);
+    UNUSED_PARAM(element);
 #endif
 }
 
-void HTMLMediaSession::unregisterWithDocument(Document& document)
+void HTMLMediaSession::unregisterWithDocument(const HTMLMediaElement& element)
 {
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    document.removePlaybackTargetPickerClient(*this);
+    element.document().removePlaybackTargetPickerClient(*this);
 #else
-    UNUSED_PARAM(document);
+    UNUSED_PARAM(element);
 #endif
 }
 
@@ -205,8 +206,7 @@ void HTMLMediaSession::showPlaybackTargetPicker(const HTMLMediaElement& element)
         return;
     }
 
-    MediaSessionManager::sharedManager().setCurrentSession(*this);
-    element.document().showPlaybackTargetPicker(element);
+    element.document().showPlaybackTargetPicker(*this, is<HTMLVideoElement>(element));
 }
 
 bool HTMLMediaSession::hasWirelessPlaybackTargets(const HTMLMediaElement&) const
@@ -274,25 +274,20 @@ void HTMLMediaSession::setWirelessVideoPlaybackDisabled(const HTMLMediaElement&
 void HTMLMediaSession::setHasPlaybackTargetAvailabilityListeners(const HTMLMediaElement& element, bool hasListeners)
 {
     LOG(Media, "HTMLMediaSession::setHasPlaybackTargetAvailabilityListeners - hasListeners %s", hasListeners ? "TRUE" : "FALSE");
-    UNUSED_PARAM(element);
-
-    m_hasPlaybackTargetAvailabilityListeners = hasListeners;
 
 #if PLATFORM(IOS)
+    UNUSED_PARAM(element);
+    m_hasPlaybackTargetAvailabilityListeners = hasListeners;
     MediaSessionManager::sharedManager().configureWireLessTargetMonitoring();
 #else
-    element.document().configurePlaybackTargetMonitoring();
+    element.document().playbackTargetPickerClientStateDidChange(*this, element.mediaState());
 #endif
 }
 
-void HTMLMediaSession::didChoosePlaybackTarget(Ref<MediaPlaybackTarget>&& device)
+void HTMLMediaSession::setPlaybackTarget(Ref<MediaPlaybackTarget>&& device)
 {
     m_playbackTarget = WTF::move(device);
     client().setWirelessPlaybackTarget(*m_playbackTarget.copyRef());
-    if (m_playbackTarget->hasActiveRoute() && MediaSessionManager::sharedManager().currentSession() == this)
-        startPlayingToPlaybackTarget();
-    else
-        stopPlayingToPlaybackTarget();
 }
 
 void HTMLMediaSession::targetAvailabilityChangedTimerFired()
@@ -300,7 +295,7 @@ void HTMLMediaSession::targetAvailabilityChangedTimerFired()
     client().wirelessRoutesAvailableDidChange();
 }
 
-void HTMLMediaSession::externalOutputDeviceAvailableDidChange(bool hasTargets) const
+void HTMLMediaSession::externalOutputDeviceAvailableDidChange(bool hasTargets)
 {
     if (m_hasPlaybackTargets == hasTargets)
         return;
@@ -312,11 +307,6 @@ void HTMLMediaSession::externalOutputDeviceAvailableDidChange(bool hasTargets) c
         m_targetAvailabilityChangedTimer.startOneShot(0);
 }
 
-bool HTMLMediaSession::requiresPlaybackTargetRouteMonitoring() const
-{
-    return m_hasPlaybackTargetAvailabilityListeners;
-}
-
 bool HTMLMediaSession::canPlayToWirelessPlaybackTarget() const
 {
     if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
@@ -333,21 +323,16 @@ bool HTMLMediaSession::isPlayingToWirelessPlaybackTarget() const
     return client().isPlayingToWirelessPlaybackTarget();
 }
 
-void HTMLMediaSession::startPlayingToPlaybackTarget()
+void HTMLMediaSession::setShouldPlayToPlaybackTarget(bool shouldPlay)
 {
-    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
-        return;
-
-    client().startPlayingToPlaybackTarget();
+    m_shouldPlayToPlaybackTarget = shouldPlay;
+    client().setShouldPlayToPlaybackTarget(shouldPlay);
 }
 
-void HTMLMediaSession::stopPlayingToPlaybackTarget()
+void HTMLMediaSession::mediaStateDidChange(const HTMLMediaElement& element, MediaProducer::MediaStateFlags state)
 {
-    if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
-        return;
-
-    client().stopPlayingToPlaybackTarget();
-}    
+    element.document().playbackTargetPickerClientStateDidChange(*this, state);
+}
 #endif
 
 MediaPlayer::Preload HTMLMediaSession::effectivePreloadForElement(const HTMLMediaElement& element) const
@@ -386,12 +371,16 @@ bool HTMLMediaSession::requiresFullscreenForVideoPlayback(const HTMLMediaElement
     return true;
 }
 
-void HTMLMediaSession::applyMediaPlayerRestrictions(const HTMLMediaElement& element)
+void HTMLMediaSession::mediaEngineUpdated(const HTMLMediaElement& element)
 {
-    LOG(Media, "HTMLMediaSession::applyMediaPlayerRestrictions");
+    LOG(Media, "HTMLMediaSession::mediaEngineUpdated");
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     setWirelessVideoPlaybackDisabled(element, m_restrictions & WirelessVideoPlaybackDisabled);
+    if (m_playbackTarget)
+        client().setWirelessPlaybackTarget(*m_playbackTarget.copyRef());
+    if (m_shouldPlayToPlaybackTarget)
+        client().setShouldPlayToPlaybackTarget(m_shouldPlayToPlaybackTarget);
 #else
     UNUSED_PARAM(element);
 #endif
index 015a5df..9b4a47c 100644 (file)
@@ -44,8 +44,8 @@ public:
     explicit HTMLMediaSession(MediaSessionClient&);
     virtual ~HTMLMediaSession() { }
 
-    void registerWithDocument(Document&);
-    void unregisterWithDocument(Document&);
+    void registerWithDocument(const HTMLMediaElement&);
+    void unregisterWithDocument(const HTMLMediaElement&);
 
     bool playbackPermitted(const HTMLMediaElement&) const;
     bool dataLoadingPermitted(const HTMLMediaElement&) const;
@@ -54,9 +54,9 @@ public:
     bool pageAllowsPlaybackAfterResuming(const HTMLMediaElement&) const;
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    void showPlaybackTargetPicker(const HTMLMediaElement&);
     bool currentPlaybackTargetIsWireless(const HTMLMediaElement&) const;
     bool currentPlaybackTargetIsSupported(const HTMLMediaElement&) const;
-    void showPlaybackTargetPicker(const HTMLMediaElement&);
     bool hasWirelessPlaybackTargets(const HTMLMediaElement&) const;
 
     bool wirelessVideoPlaybackDisabled(const HTMLMediaElement&) const;
@@ -66,15 +66,15 @@ public:
 
     virtual bool canPlayToWirelessPlaybackTarget() const override;
     virtual bool isPlayingToWirelessPlaybackTarget() const override;
-    virtual void startPlayingToPlaybackTarget() override;
-    virtual void stopPlayingToPlaybackTarget() override;
+
+    void mediaStateDidChange(const HTMLMediaElement&, MediaProducer::MediaStateFlags);
 #endif
 
     bool requiresFullscreenForVideoPlayback(const HTMLMediaElement&) const;
     WEBCORE_EXPORT bool allowsAlternateFullscreen(const HTMLMediaElement&) const;
     MediaPlayer::Preload effectivePreloadForElement(const HTMLMediaElement&) const;
 
-    void applyMediaPlayerRestrictions(const HTMLMediaElement&);
+    void mediaEngineUpdated(const HTMLMediaElement&);
 
     // Restrictions to modify default behaviors.
     enum BehaviorRestrictionFlags {
@@ -103,10 +103,13 @@ private:
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     void targetAvailabilityChangedTimerFired();
 
-    // MediaPlaybackTargetPickerClient
-    virtual void didChoosePlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
-    virtual void externalOutputDeviceAvailableDidChange(bool) const override;
-    virtual bool requiresPlaybackTargetRouteMonitoring() const override;
+    // MediaPlaybackTargetClient
+    virtual void setPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
+    virtual void externalOutputDeviceAvailableDidChange(bool) override;
+    virtual void setShouldPlayToPlaybackTarget(bool) override;
+#endif
+#if PLATFORM(IOS)
+    bool requiresPlaybackTargetRouteMonitoring() const override { return m_hasPlaybackTargetAvailabilityListeners; }
 #endif
 
     BehaviorRestrictions m_restrictions;
@@ -114,9 +117,12 @@ private:
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     mutable Timer m_targetAvailabilityChangedTimer;
     RefPtr<MediaPlaybackTarget> m_playbackTarget;
-    bool m_hasPlaybackTargetAvailabilityListeners { false };
+    bool m_shouldPlayToPlaybackTarget { false };
     mutable bool m_hasPlaybackTargets { false };
 #endif
+#if PLATFORM(IOS)
+    bool m_hasPlaybackTargetAvailabilityListeners { false };
+#endif
 };
 
 }
index 23b77eb..536959f 100644 (file)
@@ -32,6 +32,7 @@
 #include "HTMLMediaElement.h"
 #include "HostWindow.h"
 #include "LayerFlushThrottleState.h"
+#include "MediaProducer.h"
 #include "PageThrottler.h"
 #include "PopupMenu.h"
 #include "PopupMenuClient.h"
@@ -423,14 +424,7 @@ public:
 
     virtual bool shouldUseTiledBackingForFrameView(const FrameView*) const { return false; }
 
-    enum MediaState {
-        IsNotPlaying = 0,
-        IsPlayingAudio = 1 << 0,
-        IsPlayingVideo = 1 << 1,
-        IsPlayingToExternalDevice = 1 << 2,
-    };
-    typedef unsigned MediaStateFlags;
-    virtual void isPlayingMediaDidChange(MediaStateFlags) { }
+    virtual void isPlayingMediaDidChange(MediaProducer::MediaStateFlags) { }
 
     virtual void setPageActivityState(PageActivityState::Flags) { }
 
@@ -452,9 +446,10 @@ public:
     virtual void handleAutoFillButtonClick(HTMLInputElement&) { }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    virtual void showPlaybackTargetPicker(const WebCore::IntPoint&, bool /* isVideo */) { }
-    virtual void startingMonitoringPlaybackTargets() { }
-    virtual void stopMonitoringPlaybackTargets() { }
+    virtual void addPlaybackTargetPickerClient(uint64_t /*contextId*/) { }
+    virtual void removePlaybackTargetPickerClient(uint64_t /*contextId*/) { }
+    virtual void showPlaybackTargetPicker(uint64_t /*contextId*/, const WebCore::IntPoint&, bool /* isVideo */) { }
+    virtual void playbackTargetPickerClientStateDidChange(uint64_t /*contextId*/, MediaProducer::MediaStateFlags) { }
 #endif
 
 protected:
similarity index 77%
rename from Source/WebCore/page/AudioProducer.h
rename to Source/WebCore/page/MediaProducer.h
index e14750b..c00d6c0 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef AudioProducer_h
-#define AudioProducer_h
+#ifndef MediaProducer_h
+#define MediaProducer_h
 
 namespace WebCore {
 
-class AudioProducer {
+class MediaProducer {
 public:
-    virtual bool isPlayingAudio() = 0;
+    enum MediaState {
+        IsNotPlaying = 0,
+        IsPlayingAudio = 1 << 0,
+        IsPlayingVideo = 1 << 1,
+        IsPlayingToExternalDevice = 1 << 2,
+        RequiresPlaybackTargetMonitoring = 1 << 3,
+    };
+    typedef unsigned MediaStateFlags;
+
+    virtual MediaStateFlags mediaState() const = 0;
     virtual void pageMutedStateDidChange() = 0;
 
 protected:
-    virtual ~AudioProducer() { }
+    virtual ~MediaProducer() { }
 };
 
 }
index 43843ab..5f0b813 100644 (file)
@@ -214,7 +214,6 @@ Page::Page(PageConfiguration& pageConfiguration)
     , m_visitedLinkStore(*WTF::move(pageConfiguration.visitedLinkStore))
     , m_sessionID(SessionID::defaultSessionID())
     , m_isClosing(false)
-    , m_isPlayingAudio(false)
 {
     setTimerThrottlingEnabled(m_viewState & ViewState::IsVisuallyIdle);
 
@@ -1199,20 +1198,17 @@ void Page::enableLegacyPrivateBrowsing(bool privateBrowsingEnabled)
 
 void Page::updateIsPlayingMedia()
 {
-    bool isPlayingAudio = false;
+    MediaProducer::MediaStateFlags state = MediaProducer::IsNotPlaying;
     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
-        if (frame->document()->isPlayingAudio()) {
-            isPlayingAudio = true;
-            break;
-        }
+        state |= frame->document()->mediaState();
     }
 
-    if (isPlayingAudio == m_isPlayingAudio)
+    if (state == m_mediaState)
         return;
 
-    m_isPlayingAudio = isPlayingAudio;
+    m_mediaState = state;
 
-    chrome().client().isPlayingMediaDidChange(m_isPlayingAudio ? ChromeClient::IsPlayingAudio : ChromeClient::IsNotPlaying);
+    chrome().client().isPlayingMediaDidChange(state);
 }
 
 void Page::setMuted(bool muted)
@@ -1682,53 +1678,49 @@ void Page::setSessionID(SessionID sessionID)
 }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-RefPtr<MediaPlaybackTarget> Page::playbackTarget() const
+void Page::addPlaybackTargetPickerClient(uint64_t contextId)
 {
-    if (!m_playbackTarget)
-        return nullptr;
+    chrome().client().addPlaybackTargetPickerClient(contextId);
+}
 
-    return m_playbackTarget.copyRef();
+void Page::removePlaybackTargetPickerClient(uint64_t contextId)
+{
+    chrome().client().removePlaybackTargetPickerClient(contextId);
 }
 
-void Page::showPlaybackTargetPicker(const WebCore::IntPoint& location, bool isVideo)
+void Page::showPlaybackTargetPicker(uint64_t contextId, const WebCore::IntPoint& location, bool isVideo)
 {
 #if PLATFORM(IOS)
     // FIXME: refactor iOS implementation.
+    UNUSED_PARAM(contextId);
     UNUSED_PARAM(location);
     chrome().client().showPlaybackTargetPicker(isVideo);
 #else
-    chrome().client().showPlaybackTargetPicker(location, isVideo);
+    chrome().client().showPlaybackTargetPicker(contextId, location, isVideo);
 #endif
 }
 
-void Page::didChoosePlaybackTarget(Ref<MediaPlaybackTarget>&& target)
+void Page::playbackTargetPickerClientStateDidChange(uint64_t contextId, MediaProducer::MediaStateFlags state)
 {
-    m_playbackTarget = WTF::move(target);
-    for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
-        frame->document()->didChoosePlaybackTarget(*m_playbackTarget.copyRef());
+    chrome().client().playbackTargetPickerClientStateDidChange(contextId, state);
 }
 
-void Page::playbackTargetAvailabilityDidChange(bool available)
+void Page::setPlaybackTarget(uint64_t contextId, Ref<MediaPlaybackTarget>&& target)
 {
-    m_hasWirelessPlaybackTarget = available;
     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
-        frame->document()->playbackTargetAvailabilityDidChange(available);
+        frame->document()->setPlaybackTarget(contextId, target.copyRef());
 }
 
-void Page::configurePlaybackTargetMonitoring()
+void Page::playbackTargetAvailabilityDidChange(uint64_t contextId, bool available)
 {
-    bool monitoringRequired = false;
-    for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
-        if (frame->document()->requiresPlaybackTargetRouteMonitoring()) {
-            monitoringRequired = true;
-            break;
-        }
-    }
+    for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
+        frame->document()->playbackTargetAvailabilityDidChange(contextId, available);
+}
 
-    if (monitoringRequired)
-        chrome().client().startingMonitoringPlaybackTargets();
-    else
-        chrome().client().stopMonitoringPlaybackTargets();
+void Page::setShouldPlayToPlaybackTarget(uint64_t clientId, bool shouldPlay)
+{
+    for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext())
+        frame->document()->setShouldPlayToPlaybackTarget(clientId, shouldPlay);
 }
 #endif
 
index 8c3b153..b3a6088 100644 (file)
@@ -25,6 +25,7 @@
 #include "FrameLoaderTypes.h"
 #include "LayoutMilestones.h"
 #include "LayoutRect.h"
+#include "MediaProducer.h"
 #include "PageThrottler.h"
 #include "PageVisibilityState.h"
 #include "Pagination.h"
@@ -422,19 +423,20 @@ public:
     WEBCORE_EXPORT void enableLegacyPrivateBrowsing(bool privateBrowsingEnabled);
     bool usesEphemeralSession() const { return m_sessionID.isEphemeral(); }
 
-    bool isPlayingAudio() const { return m_isPlayingAudio; }
+    MediaProducer::MediaStateFlags mediaState() const { return m_mediaState; }
     void updateIsPlayingMedia();
     bool isMuted() const { return m_muted; }
     WEBCORE_EXPORT void setMuted(bool);
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    void showPlaybackTargetPicker(const WebCore::IntPoint&, bool);
-    bool hasWirelessPlaybackTarget() const { return m_hasWirelessPlaybackTarget; }
-    RefPtr<MediaPlaybackTarget> playbackTarget() const;
-    void configurePlaybackTargetMonitoring();
-
-    WEBCORE_EXPORT void didChoosePlaybackTarget(Ref<MediaPlaybackTarget>&&);
-    WEBCORE_EXPORT void playbackTargetAvailabilityDidChange(bool);
+    void addPlaybackTargetPickerClient(uint64_t);
+    void removePlaybackTargetPickerClient(uint64_t);
+    void showPlaybackTargetPicker(uint64_t, const WebCore::IntPoint&, bool);
+    void playbackTargetPickerClientStateDidChange(uint64_t, MediaProducer::MediaStateFlags);
+
+    WEBCORE_EXPORT void setPlaybackTarget(uint64_t, Ref<MediaPlaybackTarget>&&);
+    WEBCORE_EXPORT void playbackTargetAvailabilityDidChange(uint64_t, bool);
+    WEBCORE_EXPORT void setShouldPlayToPlaybackTarget(uint64_t, bool);
 #endif
 
 private:
@@ -589,14 +591,9 @@ private:
 
     SessionID m_sessionID;
 
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    RefPtr<MediaPlaybackTarget> m_playbackTarget;
-    bool m_hasWirelessPlaybackTarget { false };
-#endif
-
     bool m_isClosing;
 
-    bool m_isPlayingAudio;
+    MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
 };
 
 inline PageGroup& Page::group()
index 9990cea..ede0601 100644 (file)
 #ifndef MediaSession_h
 #define MediaSession_h
 
+#include "MediaProducer.h"
 #include "Timer.h"
 #include <wtf/Noncopyable.h>
 #include <wtf/text/WTFString.h>
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-#include "MediaPlaybackTargetPickerClient.h"
+#include "MediaPlaybackTargetClient.h"
 #endif
 
 namespace WebCore {
@@ -41,7 +42,7 @@ class MediaSessionClient;
 
 class MediaSession
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    : public MediaPlaybackTargetPickerClient
+    : public MediaPlaybackTargetClient
 #endif
 {
 public:
@@ -119,14 +120,16 @@ public:
 
     virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
     virtual bool isPlayingToWirelessPlaybackTarget() const { return false; }
-    virtual void startPlayingToPlaybackTarget() { }
-    virtual void stopPlayingToPlaybackTarget() { }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    // MediaPlaybackTargetPickerClient
-    virtual void didChoosePlaybackTarget(Ref<MediaPlaybackTarget>&&) override { }
-    virtual void externalOutputDeviceAvailableDidChange(bool) const override { }
-    virtual bool requiresPlaybackTargetRouteMonitoring() const override { return false; }
+    // MediaPlaybackTargetClient
+    virtual void setPlaybackTarget(Ref<MediaPlaybackTarget>&&) override { }
+    virtual void externalOutputDeviceAvailableDidChange(bool) override { }
+    virtual void setShouldPlayToPlaybackTarget(bool) override { }
+#endif
+
+#if PLATFORM(IOS)
+    virtual bool requiresPlaybackTargetRouteMonitoring() const { return false; }
 #endif
 
 protected:
@@ -172,8 +175,7 @@ public:
     virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) { }
     virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
     virtual bool isPlayingToWirelessPlaybackTarget() const { return false; }
-    virtual void startPlayingToPlaybackTarget() { }
-    virtual void stopPlayingToPlaybackTarget() { }
+    virtual void setShouldPlayToPlaybackTarget(bool) { }
 
 protected:
     virtual ~MediaSessionClient() { }
index cb3f31b..f570477 100644 (file)
@@ -166,25 +166,6 @@ MediaSessionManager::SessionRestrictions MediaSessionManager::restrictions(Media
     return m_restrictions[type];
 }
 
-bool MediaSessionManager::sessionShouldBeginPlayingToWirelessPlaybackTarget(MediaSession& session) const
-{
-    if (!session.canPlayToWirelessPlaybackTarget())
-        return false;
-
-    if (session.isPlayingToWirelessPlaybackTarget())
-        return false;
-
-    Vector<MediaSession*> sessions = m_sessions;
-    for (auto* oneSession : sessions) {
-        if (oneSession == &session)
-            continue;
-        if (oneSession->isPlayingToWirelessPlaybackTarget())
-            return false;
-    }
-
-    return true;
-}
-
 bool MediaSessionManager::sessionWillBeginPlayback(MediaSession& session)
 {
     LOG(Media, "MediaSessionManager::sessionWillBeginPlayback - %p", &session);
@@ -204,20 +185,14 @@ bool MediaSessionManager::sessionWillBeginPlayback(MediaSession& session)
     if (m_interrupted)
         endInterruption(MediaSession::NoFlags);
 
-    bool shouldPlayToPlaybackTarget = sessionShouldBeginPlayingToWirelessPlaybackTarget(session);
     Vector<MediaSession*> sessions = m_sessions;
     for (auto* oneSession : sessions) {
         if (oneSession == &session)
             continue;
-        if (shouldPlayToPlaybackTarget)
-            oneSession->stopPlayingToPlaybackTarget();
         if (oneSession->mediaType() == sessionType && restrictions & ConcurrentPlaybackNotPermitted)
             oneSession->pauseSession();
     }
 
-    if (shouldPlayToPlaybackTarget)
-        session.startPlayingToPlaybackTarget();
-
     updateSessionState();
     return true;
 }
@@ -294,7 +269,7 @@ bool MediaSessionManager::sessionRestrictsInlineVideoPlayback(const MediaSession
 
 bool MediaSessionManager::sessionCanLoadMedia(const MediaSession& session) const
 {
-    return session.state() == MediaSession::Playing || !session.isHidden();
+    return session.state() == MediaSession::Playing || !session.isHidden() || session.isPlayingToWirelessPlaybackTarget();
 }
 
 void MediaSessionManager::applicationWillEnterBackground() const
index 74026dd..d940d5a 100644 (file)
@@ -101,7 +101,6 @@ private:
     friend class Internals;
 
     void updateSessionState();
-    bool sessionShouldBeginPlayingToWirelessPlaybackTarget(MediaSession&) const;
 
     // RemoteCommandListenerClient
     WEBCORE_EXPORT virtual void didReceiveRemoteControlCommand(MediaSession::RemoteControlCommandType) override;
@@ -116,12 +115,16 @@ private:
     virtual void systemDidWake() override;
 
     SessionRestrictions m_restrictions[MediaSession::WebAudio + 1];
-
     Vector<MediaSession*> m_sessions;
-
     std::unique_ptr<RemoteCommandListener> m_remoteCommandListener;
     std::unique_ptr<SystemSleepListener> m_systemSleepListener;
     RefPtr<AudioHardwareListener> m_audioHardwareListener;
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+    RefPtr<MediaPlaybackTarget> m_playbackTarget;
+    bool m_canPlayToTarget { false };
+#endif
+
     bool m_interrupted { false };
 };
 
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef MediaPlaybackTargetPickerClient_h
-#define MediaPlaybackTargetPickerClient_h
+#ifndef MediaPlaybackTargetClient_h
+#define MediaPlaybackTargetClient_h
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
 
 #include "MediaPlaybackTarget.h"
+#include "MediaProducer.h"
 
 namespace WebCore {
 
 class MediaPlaybackTarget;
 
-class MediaPlaybackTargetPickerClient {
+class MediaPlaybackTargetClient {
 public:
-    virtual ~MediaPlaybackTargetPickerClient() { }
+    virtual ~MediaPlaybackTargetClient() { }
 
-    virtual void didChoosePlaybackTarget(Ref<MediaPlaybackTarget>&&) = 0;
-    virtual void externalOutputDeviceAvailableDidChange(bool) const = 0;
-
-    virtual bool requiresPlaybackTargetRouteMonitoring() const = 0;
+    virtual void setPlaybackTarget(Ref<MediaPlaybackTarget>&&) = 0;
+    virtual void externalOutputDeviceAvailableDidChange(bool) = 0;
+    virtual void setShouldPlayToPlaybackTarget(bool) = 0;
 };
 
 } // namespace WebCore
 
 #endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
 
-#endif // MediaPlaybackTargetPickerClient_h
+#endif // MediaPlaybackTargetClient_h
index 6a91a1d..9ac7eb2 100644 (file)
@@ -43,19 +43,16 @@ MediaPlaybackTargetPicker::~MediaPlaybackTargetPicker()
 void MediaPlaybackTargetPicker::showPlaybackTargetPicker(const FloatRect&, bool)
 {
     ASSERT_NOT_REACHED();
-    return;
 }
 
 void MediaPlaybackTargetPicker::startingMonitoringPlaybackTargets()
 {
     ASSERT_NOT_REACHED();
-    return;
 }
 
 void MediaPlaybackTargetPicker::stopMonitoringPlaybackTargets()
 {
     ASSERT_NOT_REACHED();
-    return;
 }
 
 } // namespace WebCore
index 0ed1d37..696cec6 100644 (file)
@@ -42,7 +42,7 @@ public:
         virtual ~Client() { }
 
     public:
-        virtual void didChoosePlaybackTarget(Ref<MediaPlaybackTarget>&&) = 0;
+        virtual void setPlaybackTarget(Ref<MediaPlaybackTarget>&&) = 0;
         virtual void externalOutputDeviceAvailableDidChange(bool) = 0;
 
         void invalidate();
index 15c02e2..5a7c5d2 100644 (file)
@@ -888,14 +888,9 @@ void MediaPlayer::setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&& device)
     m_private->setWirelessPlaybackTarget(WTF::move(device));
 }
 
-void MediaPlayer::startPlayingToPlaybackTarget()
+void MediaPlayer::setShouldPlayToPlaybackTarget(bool shouldPlay)
 {
-    m_private->startPlayingToPlaybackTarget();
-}
-
-void MediaPlayer::stopPlayingToPlaybackTarget()
-{
-    m_private->stopPlayingToPlaybackTarget();
+    m_private->setShouldPlayToPlaybackTarget(shouldPlay);
 }
 #endif
 
index 97c1613..c1117f5 100644 (file)
@@ -483,8 +483,7 @@ public:
     bool isPlayingToWirelessPlaybackTarget() const;
     void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&);
 
-    void startPlayingToPlaybackTarget();
-    void stopPlayingToPlaybackTarget();
+    void setShouldPlayToPlaybackTarget(bool);
 #endif
 
     double minFastReverseRate() const;
index 54460ad..9938af2 100644 (file)
@@ -173,8 +173,7 @@ public:
     virtual bool isPlayingToWirelessPlaybackTarget() { return false; }
     virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) { }
 
-    virtual void startPlayingToPlaybackTarget() { }
-    virtual void stopPlayingToPlaybackTarget() { }
+    virtual void setShouldPlayToPlaybackTarget(bool) { }
 #endif
 
 #if USE(NATIVE_FULLSCREEN_VIDEO)
diff --git a/Source/WebCore/platform/graphics/avfoundation/WebMediaSessionManagerMac.cpp b/Source/WebCore/platform/graphics/avfoundation/WebMediaSessionManagerMac.cpp
new file mode 100644 (file)
index 0000000..8862c6c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebMediaSessionManagerMac.h"
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+
+#include "MediaPlaybackTargetPickerMac.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+WebMediaSessionManager& WebMediaSessionManagerMac::singleton()
+{
+    static NeverDestroyed<WebMediaSessionManagerMac> sharedManager;
+    return sharedManager;
+}
+
+WebMediaSessionManagerMac::WebMediaSessionManagerMac()
+    : WebMediaSessionManager()
+{
+}
+
+WebMediaSessionManagerMac::~WebMediaSessionManagerMac()
+{
+}
+
+WebCore::MediaPlaybackTargetPicker& WebMediaSessionManagerMac::targetPicker()
+{
+    if (!m_targetPicker)
+        m_targetPicker = MediaPlaybackTargetPickerMac::create(*this);
+
+    return *m_targetPicker.get();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
diff --git a/Source/WebCore/platform/graphics/avfoundation/WebMediaSessionManagerMac.h b/Source/WebCore/platform/graphics/avfoundation/WebMediaSessionManagerMac.h
new file mode 100644 (file)
index 0000000..3fc8a00
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebMediaSessionManagerMac_h
+#define WebMediaSessionManagerMac_h
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+
+#include "WebMediaSessionManager.h"
+
+namespace WebCore {
+
+class WebMediaSessionManagerMac : public WebMediaSessionManager {
+    friend class NeverDestroyed<WebMediaSessionManagerMac>;
+public:
+    WEBCORE_EXPORT static WebMediaSessionManager& singleton();
+
+private:
+    WebMediaSessionManagerMac();
+    virtual ~WebMediaSessionManagerMac();
+
+    virtual WebCore::MediaPlaybackTargetPicker& targetPicker();
+
+    std::unique_ptr<WebCore::MediaPlaybackTargetPicker> m_targetPicker;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+#endif // WebMediaSessionManagerMac_h
index bb9934a..4a6d1c6 100644 (file)
@@ -62,7 +62,7 @@ private:
     RunLoop::Timer<MediaPlaybackTargetPickerMac> m_deviceChangeTimer;
 };
 
-} // namespace WebKit
+} // namespace WebCore
 
 #endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
 
index a441567..1b052bb 100644 (file)
@@ -133,7 +133,7 @@ void MediaPlaybackTargetPickerMac::currentDeviceDidChange()
     if (!devicePicker)
         return;
 
-    m_client->didChoosePlaybackTarget(WebCore::MediaPlaybackTargetMac::create([devicePicker outputContext]));
+    m_client->setPlaybackTarget(WebCore::MediaPlaybackTargetMac::create([devicePicker outputContext]));
 }
 
 void MediaPlaybackTargetPickerMac::startingMonitoringPlaybackTargets()
index ddead33..68e54c1 100644 (file)
@@ -283,8 +283,7 @@ private:
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
     virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
-    virtual void startPlayingToPlaybackTarget() override;
-    virtual void stopPlayingToPlaybackTarget() override;
+    virtual void setShouldPlayToPlaybackTarget(bool) override;
     virtual bool isPlayingToWirelessPlaybackTarget();
 #endif
 
index 6475a06..d3e4994 100644 (file)
@@ -942,11 +942,6 @@ void MediaPlayerPrivateAVFoundationObjC::createAVPlayer()
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     updateDisableExternalPlayback();
     [m_avPlayer.get() setAllowsExternalPlayback:m_allowsWirelessVideoPlayback];
-
-#if !PLATFORM(IOS)
-    if (m_outputContext)
-        m_avPlayer.get().outputContext = m_outputContext.get();
-#endif
 #endif
 
     if (player()->client().mediaPlayerIsVideo())
@@ -2785,35 +2780,24 @@ void MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(Ref<MediaPlay
     LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(%p) - target = %p", this, m_outputContext.get());
 
     if (!m_outputContext || !m_outputContext.get().deviceName)
-        stopPlayingToPlaybackTarget();
+        setShouldPlayToPlaybackTarget(false);
 }
 
-void MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget()
+void MediaPlayerPrivateAVFoundationObjC::setShouldPlayToPlaybackTarget(bool shouldPlay)
 {
     if (!m_avPlayer)
         return;
 
-    if ([m_avPlayer.get().outputContext isEqual:m_outputContext.get()])
-        return;
-
-    setDelayCallbacks(true);
-    m_avPlayer.get().outputContext = m_outputContext.get();
-    setDelayCallbacks(false);
-
-    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::startPlayingToPlaybackTarget(%p) - target = %p", this, m_avPlayer.get().outputContext);
-}
-
-void MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget()
-{
-    if (!m_avPlayer)
+    AVOutputContext *newContext = shouldPlay ? m_outputContext.get() : nil;
+    AVOutputContext *currentContext = m_avPlayer.get().outputContext;
+    if ((!newContext && !currentContext) || [currentContext isEqual:newContext])
         return;
 
     setDelayCallbacks(true);
-    // FIXME: uncomment the following line once rdar://20335217 has been fixed.
-    // m_avPlayer.get().outputContext = nil;
+    m_avPlayer.get().outputContext = newContext;
     setDelayCallbacks(false);
 
-    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::stopPlayingToPlaybackTarget(%p) - target = %p", this, m_avPlayer.get().outputContext);
+    LOG(Media, "MediaPlayerPrivateAVFoundationObjC::setShouldPlayToPlaybackTarget(%p) - target = %p, playing to target = %s", this, m_avPlayer.get().outputContext, boolString(shouldPlay));
 }
 
 bool MediaPlayerPrivateAVFoundationObjC::isPlayingToWirelessPlaybackTarget()
index 8ab049f..58e04ad 100644 (file)
@@ -174,9 +174,7 @@ private:
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     virtual bool isCurrentPlaybackTargetSupported() const override;
     virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&);
-    virtual void startPlayingToPlaybackTarget() override;
-    virtual void stopPlayingToPlaybackTarget() override;
-    void togglePlayingToPlaybackTarget();
+    virtual void setShouldPlayToPlaybackTarget(bool) override;
 #endif
 
     void ensureLayer();
index 4bbc397..9c17f82 100644 (file)
@@ -820,24 +820,14 @@ void MediaPlayerPrivateMediaSourceAVFObjC::setWirelessPlaybackTarget(Ref<MediaPl
     m_playbackTarget = WTF::move(target);
 }
 
-void MediaPlayerPrivateMediaSourceAVFObjC::togglePlayingToPlaybackTarget()
+void MediaPlayerPrivateMediaSourceAVFObjC::setShouldPlayToPlaybackTarget(bool shouldPlayToTarget)
 {
     bool oldSupported = m_currentPlaybackTargetIsSupported;
-    m_currentPlaybackTargetIsSupported = !m_playbackTarget || !m_playbackTarget->hasActiveRoute();
+    m_currentPlaybackTargetIsSupported = !shouldPlayToTarget;
 
     if (m_player && oldSupported != m_currentPlaybackTargetIsSupported)
         m_player->currentPlaybackTargetIsWirelessChanged();
 }
-
-void MediaPlayerPrivateMediaSourceAVFObjC::startPlayingToPlaybackTarget()
-{
-    togglePlayingToPlaybackTarget();
-}
-
-void MediaPlayerPrivateMediaSourceAVFObjC::stopPlayingToPlaybackTarget()
-{
-    togglePlayingToPlaybackTarget();
-}
 #endif
 
 }
index 3f4e6a3..313270e 100644 (file)
@@ -182,8 +182,7 @@ private:
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     virtual bool isCurrentPlaybackTargetSupported() const override;
     virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&);
-    virtual void startPlayingToPlaybackTarget() override;
-    virtual void stopPlayingToPlaybackTarget() override;
+    virtual void setShouldPlayToPlaybackTarget(bool) override;
     void togglePlayingToPlaybackTarget();
 #endif
 
index 25d4d9c..b3eec9f 100644 (file)
@@ -1554,24 +1554,14 @@ void MediaPlayerPrivateQTKit::setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>
     m_playbackTarget = WTF::move(target);
 }
 
-void MediaPlayerPrivateQTKit::togglePlayingToPlaybackTarget()
+void MediaPlayerPrivateQTKit::setShouldPlayToPlaybackTarget(bool shouldPlayToTarget)
 {
     bool oldSupported = m_currentPlaybackTargetIsSupported;
-    m_currentPlaybackTargetIsSupported = !m_playbackTarget || !m_playbackTarget->hasActiveRoute();
+    m_currentPlaybackTargetIsSupported = !shouldPlayToTarget;
 
     if (m_player && oldSupported != m_currentPlaybackTargetIsSupported)
         m_player->currentPlaybackTargetIsWirelessChanged();
 }
-
-void MediaPlayerPrivateQTKit::startPlayingToPlaybackTarget()
-{
-    togglePlayingToPlaybackTarget();
-}
-
-void MediaPlayerPrivateQTKit::stopPlayingToPlaybackTarget()
-{
-    togglePlayingToPlaybackTarget();
-}
 #endif
 
 } // namespace WebCore
index 514e0c4..c6b053e 100644 (file)
@@ -2642,7 +2642,7 @@ bool Internals::isPagePlayingAudio()
     if (!document || !document->page())
         return false;
 
-    return document->page()->isPlayingAudio();
+    return !!(document->page()->mediaState() & MediaProducer::IsPlayingAudio);
 }
 
 RefPtr<File> Internals::createFile(const String& path)
index ae6d67c..57fa0ae 100644 (file)
@@ -1,3 +1,44 @@
+2015-04-21  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] Use one playback target for all web processes
+        https://bugs.webkit.org/show_bug.cgi?id=144009
+
+        Reviewed by Tim Horton.
+
+        Update to use WebMediaSessionManager for playback target management.
+
+        * WebCoreSupport/WebChromeClient.h:
+        * WebCoreSupport/WebChromeClient.mm:
+        (WebChromeClient::addPlaybackTargetPickerClient):
+        (WebChromeClient::removePlaybackTargetPickerClient):
+        (WebChromeClient::showPlaybackTargetPicker):
+        (WebChromeClient::playbackTargetPickerClientStateDidChange):
+        (WebChromeClient::startingMonitoringPlaybackTargets): Deleted.
+        (WebChromeClient::stopMonitoringPlaybackTargets): Deleted.
+        * WebView/WebMediaPlaybackTargetPicker.h:
+        * WebView/WebMediaPlaybackTargetPicker.mm:
+        (WebMediaPlaybackTargetPicker::addPlaybackTargetPickerClient):
+        (WebMediaPlaybackTargetPicker::removePlaybackTargetPickerClient):
+        (WebMediaPlaybackTargetPicker::showPlaybackTargetPicker):
+        (WebMediaPlaybackTargetPicker::playbackTargetPickerClientStateDidChange):
+        (WebMediaPlaybackTargetPicker::setPlaybackTarget):
+        (WebMediaPlaybackTargetPicker::externalOutputDeviceAvailableDidChange):
+        (WebMediaPlaybackTargetPicker::setShouldPlayToPlaybackTarget):
+        (WebMediaPlaybackTargetPicker::invalidate):
+        (WebMediaPlaybackTargetPicker::startingMonitoringPlaybackTargets): Deleted.
+        (WebMediaPlaybackTargetPicker::stopMonitoringPlaybackTargets): Deleted.
+        (WebMediaPlaybackTargetPicker::didChoosePlaybackTarget): Deleted.
+        (WebMediaPlaybackTargetPicker::targetPicker): Deleted.
+        * WebView/WebView.mm:
+        (-[WebView _addPlaybackTargetPickerClient:]):
+        (-[WebView _removePlaybackTargetPickerClient:]):
+        (-[WebView _showPlaybackTargetPicker:location:hasVideo:]):
+        (-[WebView _playbackTargetPickerClientStateDidChange:state:]):
+        (-[WebView _showPlaybackTargetPicker:hasVideo:]): Deleted.
+        (-[WebView _startingMonitoringPlaybackTargets]): Deleted.
+        (-[WebView _stopMonitoringPlaybackTargets]): Deleted.
+        * WebView/WebViewInternal.h:
+
 2015-04-20  Alexey Proskuryakov  <ap@apple.com>
 
         Disable mixed content blocking for existing WebKit1 clients
index 3b9326c..a347499 100644 (file)
@@ -214,9 +214,10 @@ public:
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-    virtual void showPlaybackTargetPicker(const WebCore::IntPoint&, bool /* hasVideo */) override;
-    virtual void startingMonitoringPlaybackTargets() override;
-    virtual void stopMonitoringPlaybackTargets() override;
+    virtual void addPlaybackTargetPickerClient(uint64_t /*contextId*/) override;
+    virtual void removePlaybackTargetPickerClient(uint64_t /*contextId*/) override;
+    virtual void showPlaybackTargetPicker(uint64_t /*contextId*/, const WebCore::IntPoint&, bool /* hasVideo */) override;
+    virtual void playbackTargetPickerClientStateDidChange(uint64_t /*contextId*/, WebCore::MediaProducer::MediaStateFlags) override;
 #endif
 
 private:
index e31cda9..b9709f5 100644 (file)
@@ -1036,18 +1036,23 @@ bool WebChromeClient::hasRelevantSelectionServices(bool isTextOnly) const
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-void WebChromeClient::showPlaybackTargetPicker(const WebCore::IntPoint& location, bool hasVideo)
+void WebChromeClient::addPlaybackTargetPickerClient(uint64_t contextId)
 {
-    [m_webView _showPlaybackTargetPicker:location hasVideo:hasVideo];
+    [m_webView _addPlaybackTargetPickerClient:contextId];
 }
 
-void WebChromeClient::startingMonitoringPlaybackTargets()
+void WebChromeClient::removePlaybackTargetPickerClient(uint64_t contextId)
 {
-    [m_webView _startingMonitoringPlaybackTargets];
+    [m_webView _removePlaybackTargetPickerClient:contextId];
 }
 
-void WebChromeClient::stopMonitoringPlaybackTargets()
+void WebChromeClient::showPlaybackTargetPicker(uint64_t contextId, const WebCore::IntPoint& location, bool hasVideo)
 {
-    [m_webView _stopMonitoringPlaybackTargets];
+    [m_webView _showPlaybackTargetPicker:contextId location:location hasVideo:hasVideo];
+}
+
+void WebChromeClient::playbackTargetPickerClientStateDidChange(uint64_t contextId, MediaProducer::MediaStateFlags state)
+{
+    [m_webView _playbackTargetPickerClientStateDidChange:contextId state:state];
 }
 #endif
index f07b4d9..6efbdf3 100644 (file)
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
 
-#import <WebCore/MediaPlaybackTargetPicker.h>
+#import <WebCore/MediaPlaybackTarget.h>
+#import <WebCore/WebMediaSessionManagerClient.h>
+#include <wtf/Ref.h>
 
 namespace WebCore {
 class FloatRect;
+class MediaPlaybackTarget;
 class Page;
 }
 
-class WebMediaPlaybackTargetPicker : public WebCore::MediaPlaybackTargetPicker::Client {
+class WebMediaPlaybackTargetPicker : public WebCore::WebMediaSessionManagerClient {
 public:
     static std::unique_ptr<WebMediaPlaybackTargetPicker> create(WebCore::Page&);
 
     explicit WebMediaPlaybackTargetPicker(WebCore::Page&);
     virtual ~WebMediaPlaybackTargetPicker() { }
 
-    void showPlaybackTargetPicker(const WebCore::FloatRect&, bool /* hasVideo */);
-    void startingMonitoringPlaybackTargets();
-    void stopMonitoringPlaybackTargets();
+    void addPlaybackTargetPickerClient(uint64_t);
+    void removePlaybackTargetPickerClient(uint64_t);
+    void showPlaybackTargetPicker(uint64_t, const WebCore::FloatRect&, bool hasVideo);
+    void playbackTargetPickerClientStateDidChange(uint64_t, WebCore::MediaProducer::MediaStateFlags);
 
-    // WebCore::MediaPlaybackTargetPicker::Client
-    virtual void didChoosePlaybackTarget(Ref<WebCore::MediaPlaybackTarget>&&) override;
-    virtual void externalOutputDeviceAvailableDidChange(bool) override;
+    // WebMediaSessionManagerClient
+    virtual void setPlaybackTarget(uint64_t, Ref<WebCore::MediaPlaybackTarget>&&) override;
+    virtual void externalOutputDeviceAvailableDidChange(uint64_t, bool) override;
+    virtual void setShouldPlayToPlaybackTarget(uint64_t, bool) override;
 
     void invalidate();
 
 private:
-    WebCore::MediaPlaybackTargetPicker& targetPicker();
-
     WebCore::Page* m_page;
-    std::unique_ptr<WebCore::MediaPlaybackTargetPicker> m_targetPicker;
 };
+
 #endif
index b56ab45..b35c433 100644 (file)
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #import "WebMediaPlaybackTargetPicker.h"
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
 
-#import <WebCore/MediaPlaybackTargetPickerMac.h>
+#import <WebCore/MediaPlaybackTarget.h>
 #import <WebCore/Page.h>
+#import <WebCore/WebMediaSessionManagerMac.h>
 
 std::unique_ptr<WebMediaPlaybackTargetPicker> WebMediaPlaybackTargetPicker::create(WebCore::Page& page)
 {
@@ -40,48 +41,54 @@ WebMediaPlaybackTargetPicker::WebMediaPlaybackTargetPicker(WebCore::Page& page)
 {
 }
 
-void WebMediaPlaybackTargetPicker::showPlaybackTargetPicker(const WebCore::FloatRect& rect, bool hasVideo)
+void WebMediaPlaybackTargetPicker::addPlaybackTargetPickerClient(uint64_t contextId)
 {
-    targetPicker().showPlaybackTargetPicker(WebCore::IntRect(rect), hasVideo);
+    WebCore::WebMediaSessionManagerMac::singleton().addPlaybackTargetPickerClient(*this, contextId);
 }
 
-void WebMediaPlaybackTargetPicker::startingMonitoringPlaybackTargets()
+void WebMediaPlaybackTargetPicker::removePlaybackTargetPickerClient(uint64_t contextId)
 {
-    targetPicker().startingMonitoringPlaybackTargets();
+    WebCore::WebMediaSessionManagerMac::singleton().removePlaybackTargetPickerClient(*this, contextId);
 }
 
-void WebMediaPlaybackTargetPicker::stopMonitoringPlaybackTargets()
+void WebMediaPlaybackTargetPicker::showPlaybackTargetPicker(uint64_t contextId, const WebCore::FloatRect& rect, bool hasVideo)
 {
-    targetPicker().stopMonitoringPlaybackTargets();
+    WebCore::WebMediaSessionManagerMac::singleton().showPlaybackTargetPicker(*this, contextId, WebCore::IntRect(rect), hasVideo);
 }
 
-void WebMediaPlaybackTargetPicker::didChoosePlaybackTarget(Ref<WebCore::MediaPlaybackTarget>&& target)
+void WebMediaPlaybackTargetPicker::playbackTargetPickerClientStateDidChange(uint64_t contextId, WebCore::MediaProducer::MediaStateFlags state)
+{
+    WebCore::WebMediaSessionManagerMac::singleton().clientStateDidChange(*this, contextId, state);
+}
+
+void WebMediaPlaybackTargetPicker::setPlaybackTarget(uint64_t contextId, Ref<WebCore::MediaPlaybackTarget>&& target)
 {
     if (!m_page)
         return;
 
-    m_page->didChoosePlaybackTarget(WTF::move(target));
+    m_page->setPlaybackTarget(contextId, WTF::move(target));
 }
 
-void WebMediaPlaybackTargetPicker::externalOutputDeviceAvailableDidChange(bool available)
+void WebMediaPlaybackTargetPicker::externalOutputDeviceAvailableDidChange(uint64_t contextId, bool available)
 {
     if (!m_page)
         return;
 
-    m_page->playbackTargetAvailabilityDidChange(available);
+    m_page->playbackTargetAvailabilityDidChange(contextId, available);
 }
 
-void WebMediaPlaybackTargetPicker::invalidate()
+void WebMediaPlaybackTargetPicker::setShouldPlayToPlaybackTarget(uint64_t contextId, bool shouldPlay)
 {
-    m_page = nullptr;
+    if (!m_page)
+        return;
+
+    m_page->setShouldPlayToPlaybackTarget(contextId, shouldPlay);
 }
 
-WebCore::MediaPlaybackTargetPicker& WebMediaPlaybackTargetPicker::targetPicker()
+void WebMediaPlaybackTargetPicker::invalidate()
 {
-    if (!m_targetPicker)
-        m_targetPicker = WebCore::MediaPlaybackTargetPickerMac::create(*this);
-
-    return *m_targetPicker.get();
+    m_page = nullptr;
+    WebCore::WebMediaSessionManagerMac::singleton().removeAllPlaybackTargetPickerClients(*this);
 }
 
 #endif
index 66f5a1a..6a4ff77 100644 (file)
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
 #import "WebMediaPlaybackTargetPicker.h"
+#import <WebCore/WebMediaSessionManagerMac.h>
 #endif
 
 #if PLATFORM(MAC)
@@ -8669,30 +8670,29 @@ bool LayerFlushController::flushLayers()
     return _private->m_playbackTargetPicker.get();
 }
 
-- (void)_showPlaybackTargetPicker:(const WebCore::IntPoint&)location hasVideo:(BOOL)hasVideo
+- (void)_addPlaybackTargetPickerClient:(uint64_t)clientId
 {
-    if (!_private->page)
-        return;
+    [self _devicePicker]->addPlaybackTargetPickerClient(clientId);
+}
 
-    NSRect rectInWindowCoordinates = [self convertRect:[self _convertRectFromRootView:NSMakeRect(location.x(), location.y(), 0, 0)] toView:nil];
-    NSRect rectInScreenCoordinates = [self.window convertRectToScreen:rectInWindowCoordinates];
-    [self _devicePicker]->showPlaybackTargetPicker(rectInScreenCoordinates, hasVideo);
+- (void)_removePlaybackTargetPickerClient:(uint64_t)clientId
+{
+    [self _devicePicker]->removePlaybackTargetPickerClient(clientId);
 }
 
-- (void)_startingMonitoringPlaybackTargets
+- (void)_showPlaybackTargetPicker:(uint64_t)clientId location:(const WebCore::IntPoint&)location hasVideo:(BOOL)hasVideo
 {
     if (!_private->page)
         return;
 
-    [self _devicePicker]->startingMonitoringPlaybackTargets();
+    NSRect rectInWindowCoordinates = [self convertRect:[self _convertRectFromRootView:NSMakeRect(location.x(), location.y(), 0, 0)] toView:nil];
+    NSRect rectInScreenCoordinates = [self.window convertRectToScreen:rectInWindowCoordinates];
+    [self _devicePicker]->showPlaybackTargetPicker(clientId, rectInScreenCoordinates, hasVideo);
 }
 
-- (void)_stopMonitoringPlaybackTargets
+- (void)_playbackTargetPickerClientStateDidChange:(uint64_t)clientId state:(WebCore::MediaProducer::MediaStateFlags)state
 {
-    if (!_private->page)
-        return;
-
-    [self _devicePicker]->stopMonitoringPlaybackTargets();
+    [self _devicePicker]->playbackTargetPickerClientStateDidChange(clientId, state);
 }
 #endif
 
index 73f3975..5374200 100644 (file)
@@ -271,9 +271,10 @@ OBJC_CLASS NSTextAlternatives;
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) && defined(__cplusplus)
 - (WebMediaPlaybackTargetPicker *) _devicePicker;
-- (void)_showPlaybackTargetPicker:(const WebCore::IntPoint&)location hasVideo:(BOOL)hasVideo;
-- (void)_startingMonitoringPlaybackTargets;
-- (void)_stopMonitoringPlaybackTargets;
+- (void)_addPlaybackTargetPickerClient:(uint64_t)clientId;
+- (void)_removePlaybackTargetPickerClient:(uint64_t)contextId;
+- (void)_showPlaybackTargetPicker:(uint64_t)contextId location:(const WebCore::IntPoint&)location hasVideo:(BOOL)hasVideo;
+- (void)_playbackTargetPickerClientStateDidChange:(uint64_t)contextId state:(WebCore::MediaProducer::MediaStateFlags)state;
 #endif
 
 @end
index 901d02a..9541183 100644 (file)
@@ -1,3 +1,61 @@
+2015-04-21  Eric Carlson  <eric.carlson@apple.com>
+
+        [Mac] Use one playback target for all web processes
+        https://bugs.webkit.org/show_bug.cgi?id=144009
+
+        Reviewed by Tim Horton.
+
+        Every WebPageProxy uses the WebMediaSessionManager singleton to talk to the playback target
+        picker.
+
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::WebPageProxy):
+        (WebKit::WebPageProxy::resetState):
+        (WebKit::WebPageProxy::isPlayingMediaDidChange):
+        (WebKit::WebPageProxy::addPlaybackTargetPickerClient):
+        (WebKit::WebPageProxy::removePlaybackTargetPickerClient):
+        (WebKit::WebPageProxy::showPlaybackTargetPicker):
+        (WebKit::WebPageProxy::playbackTargetPickerClientStateDidChange):
+        (WebKit::WebPageProxy::setPlaybackTarget):
+        (WebKit::WebPageProxy::externalOutputDeviceAvailableDidChange):
+        (WebKit::WebPageProxy::setShouldPlayToPlaybackTarget):
+        (WebKit::WebPageProxy::devicePickerProxy): Deleted.
+        (WebKit::WebPageProxy::startingMonitoringPlaybackTargets): Deleted.
+        (WebKit::WebPageProxy::stopMonitoringPlaybackTargets): Deleted.
+        (WebKit::WebPageProxy::didChoosePlaybackTarget): Deleted.
+        * UIProcess/WebPageProxy.h:
+        (WebKit::WebPageProxy::isPlayingAudio):
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/mac/PageClientImpl.h:
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::mediaSessionManager):
+        (WebKit::PageClientImpl::createPlaybackTargetPicker): Deleted.
+        * UIProcess/mac/WebMediaSessionManagerMac.cpp: Added.
+        (WebKit::WebMediaSessionManagerMac::singleton):
+        (WebKit::WebMediaSessionManagerMac::WebMediaSessionManagerMac):
+        (WebKit::WebMediaSessionManagerMac::~WebMediaSessionManagerMac):
+        (WebKit::WebMediaSessionManagerMac::targetPicker):
+        * UIProcess/mac/WebMediaSessionManagerMac.h: Added.
+        * WebProcess/Plugins/PluginView.h:
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::isPlayingMediaDidChange):
+        (WebKit::WebChromeClient::addPlaybackTargetPickerClient):
+        (WebKit::WebChromeClient::removePlaybackTargetPickerClient):
+        (WebKit::WebChromeClient::showPlaybackTargetPicker):
+        (WebKit::WebChromeClient::playbackTargetPickerClientStateDidChange):
+        (WebKit::WebChromeClient::startingMonitoringPlaybackTargets): Deleted.
+        (WebKit::WebChromeClient::stopMonitoringPlaybackTargets): Deleted.
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
+        (WebKit::TiledCoreAnimationDrawingArea::dispatchAfterEnsuringUpdatedScrollPosition):
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::playbackTargetSelected):
+        (WebKit::WebPage::playbackTargetAvailabilityDidChange):
+        (WebKit::WebPage::setShouldPlayToPlaybackTarget):
+
 2015-04-21  Anders Carlsson  <andersca@apple.com>
 
         WKWebsiteDataStore doesn't track and remove IndexedDB databases
index e758f67..1e55328 100644 (file)
 #include <WebCore/EditorClient.h>
 #include <wtf/Forward.h>
 
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-#include <WebCore/MediaPlaybackTargetPicker.h>
-#endif
-
 #if PLATFORM(COCOA)
 #include "PluginComplexTextInputState.h"
 
@@ -52,6 +48,7 @@ OBJC_CLASS NSTextAlternatives;
 namespace WebCore {
 class Cursor;
 class TextIndicator;
+class WebMediaSessionManager;
 struct Highlight;
 struct ViewportAttributes;
 }
@@ -325,7 +322,7 @@ public:
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-    virtual std::unique_ptr<WebCore::MediaPlaybackTargetPicker> createPlaybackTargetPicker(WebPageProxy*) = 0;
+    virtual WebCore::WebMediaSessionManager& mediaSessionManager() = 0;
 #endif
 
 };
index 1f4e241..ca20e5b 100644 (file)
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
 #include <WebCore/MediaPlaybackTarget.h>
+#include <WebCore/WebMediaSessionManager.h>
 #endif
 
 // This controls what strategy we use for mouse wheel coalescing.
@@ -408,7 +409,6 @@ WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uin
     , m_configurationPreferenceValues(configuration.preferenceValues)
     , m_potentiallyChangedViewStateFlags(ViewState::NoFlags)
     , m_viewStateChangeWantsSynchronousReply(false)
-    , m_isPlayingAudio(false)
 {
     m_webProcessLifetimeTracker.addObserver(m_visitedLinkProvider);
     m_webProcessLifetimeTracker.addObserver(m_websiteDataStore);
@@ -4828,6 +4828,10 @@ void WebPageProxy::resetState(ResetStateReason resetStateReason)
     m_layerTreeTransactionIdAtLastTouchStart = 0;
 #endif
 
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
+    m_pageClient.mediaSessionManager().removeAllPlaybackTargetPickerClients(*this);
+#endif
+
     CallbackBase::Error error;
     switch (resetStateReason) {
     case ResetStateReason::PageInvalidated:
@@ -4849,7 +4853,7 @@ void WebPageProxy::resetState(ResetStateReason resetStateReason)
         editCommandVector[i]->invalidate();
 
     m_activePopupMenu = nullptr;
-    m_isPlayingAudio = false;
+    m_mediaState = MediaProducer::IsNotPlaying;
 }
 
 void WebPageProxy::resetStateAfterProcessExited()
@@ -5659,13 +5663,12 @@ void WebPageProxy::navigationGestureSnapshotWasRemoved()
     m_isShowingNavigationGestureSnapshot = false;
 }
 
-void WebPageProxy::isPlayingMediaDidChange(WebCore::ChromeClient::MediaStateFlags state)
+void WebPageProxy::isPlayingMediaDidChange(WebCore::MediaProducer::MediaStateFlags state)
 {
-    bool isPlayingAudio = state & WebCore::ChromeClient::IsPlayingAudio;
-    if (m_isPlayingAudio == isPlayingAudio)
+    if (state == m_mediaState)
         return;
 
-    m_isPlayingAudio = isPlayingAudio;
+    m_mediaState = state;
     m_uiClient->isPlayingAudioDidChange(*this);
 }
 
@@ -5738,46 +5741,49 @@ void WebPageProxy::handleAutoFillButtonClick(const UserData& userData)
 }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-
-WebCore::MediaPlaybackTargetPicker& WebPageProxy::devicePickerProxy()
+void WebPageProxy::addPlaybackTargetPickerClient(uint64_t contextId)
 {
-    if (!m_playbackTargetPicker)
-        m_playbackTargetPicker = m_pageClient.createPlaybackTargetPicker(this);
-
-    return *m_playbackTargetPicker.get();
+    m_pageClient.mediaSessionManager().addPlaybackTargetPickerClient(*this, contextId);
 }
 
-void WebPageProxy::showPlaybackTargetPicker(const WebCore::FloatRect& rect, bool hasVideo)
+void WebPageProxy::removePlaybackTargetPickerClient(uint64_t contextId)
 {
-    devicePickerProxy().showPlaybackTargetPicker(m_pageClient.rootViewToScreen(IntRect(rect)), hasVideo);
+    m_pageClient.mediaSessionManager().removePlaybackTargetPickerClient(*this, contextId);
 }
 
-void WebPageProxy::startingMonitoringPlaybackTargets()
+void WebPageProxy::showPlaybackTargetPicker(uint64_t contextId, const WebCore::FloatRect& rect, bool hasVideo)
 {
-    devicePickerProxy().startingMonitoringPlaybackTargets();
+    m_pageClient.mediaSessionManager().showPlaybackTargetPicker(*this, contextId, m_pageClient.rootViewToScreen(IntRect(rect)), hasVideo);
 }
 
-void WebPageProxy::stopMonitoringPlaybackTargets()
+void WebPageProxy::playbackTargetPickerClientStateDidChange(uint64_t contextId, WebCore::MediaProducer::MediaStateFlags state)
 {
-    devicePickerProxy().stopMonitoringPlaybackTargets();
+    m_pageClient.mediaSessionManager().clientStateDidChange(*this, contextId, state);
 }
 
-void WebPageProxy::didChoosePlaybackTarget(Ref<MediaPlaybackTarget>&& target)
+void WebPageProxy::setPlaybackTarget(uint64_t contextId, Ref<MediaPlaybackTarget>&& target)
 {
     if (!isValid())
         return;
 
-    m_process->send(Messages::WebPage::PlaybackTargetSelected(target->targetContext()), m_pageID);
+    m_process->send(Messages::WebPage::PlaybackTargetSelected(contextId, target->targetContext()), m_pageID);
 }
 
-void WebPageProxy::externalOutputDeviceAvailableDidChange(bool available)
+void WebPageProxy::externalOutputDeviceAvailableDidChange(uint64_t contextId, bool available)
 {
     if (!isValid())
         return;
 
-    m_process->send(Messages::WebPage::PlaybackTargetAvailabilityDidChange(available), m_pageID);
+    m_process->send(Messages::WebPage::PlaybackTargetAvailabilityDidChange(contextId, available), m_pageID);
 }
 
+void WebPageProxy::setShouldPlayToPlaybackTarget(uint64_t contextId, bool shouldPlay)
+{
+    if (!isValid())
+        return;
+
+    m_process->send(Messages::WebPage::SetShouldPlayToPlaybackTarget(contextId, shouldPlay), m_pageID);
+}
 #endif
 
 void WebPageProxy::didChangeBackgroundColor()
index c08b2b9..539603e 100644 (file)
 #include "WebPageProxyMessages.h"
 #include "WebPopupMenuProxy.h"
 #include "WebProcessLifetimeTracker.h"
-#include <WebCore/ChromeClient.h>
 #include <WebCore/Color.h>
 #include <WebCore/DragActions.h>
 #include <WebCore/HitTestResult.h>
+#include <WebCore/MediaProducer.h>
 #include <WebCore/Page.h>
 #include <WebCore/PlatformScreen.h>
 #include <WebCore/ScrollTypes.h>
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
 #include <WebCore/MediaPlaybackTargetPicker.h>
+#include <WebCore/WebMediaSessionManagerClient.h>
 #endif
 
 namespace API {
@@ -264,7 +265,7 @@ class WebPageProxy : public API::ObjectImpl<API::Object::Type::Page>
     , public WebColorPicker::Client
 #endif
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-    , public WebCore::MediaPlaybackTargetPicker::Client
+    , public WebCore::WebMediaSessionManagerClient
 #endif
     , public WebPopupMenuProxy::Client
     , public IPC::MessageReceiver
@@ -983,8 +984,8 @@ public:
 
     bool isShowingNavigationGestureSnapshot() const { return m_isShowingNavigationGestureSnapshot; }
 
-    void isPlayingMediaDidChange(WebCore::ChromeClient::MediaStateFlags);
-    bool isPlayingAudio() const { return m_isPlayingAudio; }
+    bool isPlayingAudio() const { return !!(m_mediaState & WebCore::MediaProducer::IsPlayingAudio); }
+    void isPlayingMediaDidChange(WebCore::MediaProducer::MediaStateFlags);
 
 #if PLATFORM(MAC)
     void removeNavigationGestureSnapshot();
@@ -1020,14 +1021,15 @@ public:
     void logDiagnosticMessageWithValue(const String& message, const String& description, const String& value, bool shouldSample);
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-    WebCore::MediaPlaybackTargetPicker& devicePickerProxy();
-    void showPlaybackTargetPicker(const WebCore::FloatRect&, bool hasVideo);
-    void startingMonitoringPlaybackTargets();
-    void stopMonitoringPlaybackTargets();
+    void addPlaybackTargetPickerClient(uint64_t);
+    void removePlaybackTargetPickerClient(uint64_t);
+    void showPlaybackTargetPicker(uint64_t, const WebCore::FloatRect&, bool hasVideo);
+    void playbackTargetPickerClientStateDidChange(uint64_t, WebCore::MediaProducer::MediaStateFlags);
 
-    // WebCore::MediaPlaybackTargetPicker::Client
-    virtual void didChoosePlaybackTarget(Ref<WebCore::MediaPlaybackTarget>&&) override;
-    virtual void externalOutputDeviceAvailableDidChange(bool) override;
+    // WebMediaSessionManagerClient
+    virtual void setPlaybackTarget(uint64_t, Ref<WebCore::MediaPlaybackTarget>&&) override;
+    virtual void externalOutputDeviceAvailableDidChange(uint64_t, bool) override;
+    virtual void setShouldPlayToPlaybackTarget(uint64_t, bool) override;
 #endif
 
     void didChangeBackgroundColor();
@@ -1706,11 +1708,12 @@ private:
     bool m_viewStateChangeWantsSynchronousReply;
     Vector<uint64_t> m_nextViewStateChangeCallbacks;
 
+    WebCore::MediaProducer::MediaStateFlags m_mediaState { WebCore::MediaProducer::IsNotPlaying };
+
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-    std::unique_ptr<WebCore::MediaPlaybackTargetPicker> m_playbackTargetPicker;
+    bool m_requiresTargetMonitoring { false };
 #endif
 
-    bool m_isPlayingAudio;
 };
 
 } // namespace WebKit
index 4917fd6..58d470e 100644 (file)
@@ -432,9 +432,10 @@ messages -> WebPageProxy {
     HandleAutoFillButtonClick(WebKit::UserData userData);
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-    ShowPlaybackTargetPicker(WebCore::FloatRect pickerLocation, bool hasVideo)
-    StartingMonitoringPlaybackTargets()
-    StopMonitoringPlaybackTargets()
+    AddPlaybackTargetPickerClient(uint64_t contextId)
+    RemovePlaybackTargetPickerClient(uint64_t contextId)
+    ShowPlaybackTargetPicker(uint64_t clientId, WebCore::FloatRect pickerLocation, bool hasVideo)
+    PlaybackTargetPickerClientStateDidChange(uint64_t contextId, unsigned mediaState)
 #endif
 
 }
index 8eef93a..57c3e8f 100644 (file)
@@ -211,7 +211,7 @@ private:
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    virtual std::unique_ptr<WebCore::MediaPlaybackTargetPicker> createPlaybackTargetPicker(WebPageProxy*) override;
+    virtual WebCore::WebMediaSessionManager& mediaSessionManager() override;
 #endif
 };
 
index f3ba203..e2c1243 100644 (file)
@@ -71,7 +71,7 @@
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-#include <WebCore/MediaPlaybackTargetPickerMac.h>
+#include <WebCore/WebMediaSessionManagerMac.h>
 #endif
 
 @interface NSApplication (WebNSApplicationDetails)
@@ -813,9 +813,9 @@ void PageClientImpl::showPlatformContextMenu(NSMenu *menu, IntPoint location)
 }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-std::unique_ptr<WebCore::MediaPlaybackTargetPicker> PageClientImpl::createPlaybackTargetPicker(WebPageProxy* page)
+WebCore::WebMediaSessionManager& PageClientImpl::mediaSessionManager()
 {
-    return MediaPlaybackTargetPickerMac::create(*page);
+    return WebMediaSessionManagerMac::singleton();
 }
 #endif
 
index 719b7f6..9a6b88f 100644 (file)
 #include "Plugin.h"
 #include "PluginController.h"
 #include "WebFrame.h"
-#include <WebCore/AudioProducer.h>
 #include <WebCore/FindOptions.h>
 #include <WebCore/Image.h>
 #include <WebCore/MediaCanStartListener.h>
+#include <WebCore/MediaProducer.h>
 #include <WebCore/PluginViewBase.h>
 #include <WebCore/ResourceError.h>
 #include <WebCore/ResourceResponse.h>
@@ -58,7 +58,7 @@ namespace WebKit {
 
 class WebEvent;
 
-class PluginView : public WebCore::PluginViewBase, public PluginController, private WebCore::MediaCanStartListener, private WebFrame::LoadListener, private WebCore::AudioProducer {
+class PluginView : public WebCore::PluginViewBase, public PluginController, private WebCore::MediaCanStartListener, private WebFrame::LoadListener, private WebCore::MediaProducer {
 public:
     static PassRefPtr<PluginView> create(PassRefPtr<WebCore::HTMLPlugInElement>, PassRefPtr<Plugin>, const Plugin::Parameters&);
 
@@ -181,8 +181,8 @@ private:
     // WebCore::MediaCanStartListener
     virtual void mediaCanStart() override;
 
-    // WebCore::AudioProducer
-    virtual bool isPlayingAudio() override { return m_pluginIsPlayingAudio; }
+    // WebCore::MediaProducer
+    virtual MediaProducer::MediaStateFlags mediaState() const override { return m_pluginIsPlayingAudio ? MediaProducer::IsPlayingAudio : MediaProducer::IsNotPlaying; }
     virtual void pageMutedStateDidChange() override;
 
     // PluginController
index fc9c4bb..9142bb1 100644 (file)
@@ -1050,7 +1050,7 @@ bool WebChromeClient::shouldUseTiledBackingForFrameView(const FrameView* frameVi
     return m_page->drawingArea()->shouldUseTiledBackingForFrameView(frameView);
 }
 
-void WebChromeClient::isPlayingMediaDidChange(MediaStateFlags state)
+void WebChromeClient::isPlayingMediaDidChange(WebCore::MediaProducer::MediaStateFlags state)
 {
     m_page->send(Messages::WebPageProxy::IsPlayingMediaDidChange(state));
 }
@@ -1115,21 +1115,27 @@ void WebChromeClient::handleAutoFillButtonClick(HTMLInputElement& inputElement)
 }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-void WebChromeClient::showPlaybackTargetPicker(const WebCore::IntPoint& position, bool isVideo)
+void WebChromeClient::addPlaybackTargetPickerClient(uint64_t contextId)
 {
-    FrameView* frameView = m_page->mainFrame()->view();
-    FloatRect rect(frameView->contentsToRootView(frameView->windowToContents(position)), FloatSize());
-    m_page->send(Messages::WebPageProxy::ShowPlaybackTargetPicker(rect, isVideo));
+    m_page->send(Messages::WebPageProxy::AddPlaybackTargetPickerClient(contextId));
+}
+
+void WebChromeClient::removePlaybackTargetPickerClient(uint64_t contextId)
+{
+    m_page->send(Messages::WebPageProxy::RemovePlaybackTargetPickerClient(contextId));
 }
 
-void WebChromeClient::startingMonitoringPlaybackTargets()
+
+void WebChromeClient::showPlaybackTargetPicker(uint64_t contextId, const WebCore::IntPoint& position, bool isVideo)
 {
-    m_page->send(Messages::WebPageProxy::StartingMonitoringPlaybackTargets());
+    FrameView* frameView = m_page->mainFrame()->view();
+    FloatRect rect(frameView->contentsToRootView(frameView->windowToContents(position)), FloatSize());
+    m_page->send(Messages::WebPageProxy::ShowPlaybackTargetPicker(contextId, rect, isVideo));
 }
 
-void WebChromeClient::stopMonitoringPlaybackTargets()
+void WebChromeClient::playbackTargetPickerClientStateDidChange(uint64_t contextId, WebCore::MediaProducer::MediaStateFlags state)
 {
-    m_page->send(Messages::WebPageProxy::StopMonitoringPlaybackTargets());
+    m_page->send(Messages::WebPageProxy::PlaybackTargetPickerClientStateDidChange(contextId, state));
 }
 #endif
 
index b82c127..1e596cb 100644 (file)
@@ -292,7 +292,7 @@ private:
 
     virtual bool shouldUseTiledBackingForFrameView(const WebCore::FrameView*) const override;
 
-    virtual void isPlayingMediaDidChange(MediaStateFlags) override;
+    virtual void isPlayingMediaDidChange(WebCore::MediaProducer::MediaStateFlags) override;
     virtual void setPageActivityState(WebCore::PageActivityState::Flags) override;
 
 #if ENABLE(SUBTLE_CRYPTO)
@@ -313,9 +313,10 @@ private:
     virtual void handleAutoFillButtonClick(WebCore::HTMLInputElement&) override;
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-    virtual void showPlaybackTargetPicker(const WebCore::IntPoint&, bool) override;
-    virtual void startingMonitoringPlaybackTargets() override;
-    virtual void stopMonitoringPlaybackTargets() override;
+    virtual void addPlaybackTargetPickerClient(uint64_t /*contextId*/) override;
+    virtual void removePlaybackTargetPickerClient(uint64_t /*contextId*/) override;
+    virtual void showPlaybackTargetPicker(uint64_t contextId, const WebCore::IntPoint&, bool) override;
+    virtual void playbackTargetPickerClientStateDidChange(uint64_t, WebCore::MediaProducer::MediaStateFlags) override;
 #endif
 
     String m_cachedToolTip;
index 44dde24..ef20374 100644 (file)
@@ -1107,8 +1107,9 @@ private:
     void setShouldDispatchFakeMouseMoveEvents(bool dispatch) { m_shouldDispatchFakeMouseMoveEvents = dispatch; }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-    void playbackTargetSelected(const WebCore::MediaPlaybackTargetContext& outputDevice) const;
-    void playbackTargetAvailabilityDidChange(bool);
+    void playbackTargetSelected(uint64_t, const WebCore::MediaPlaybackTargetContext& outputDevice) const;
+    void playbackTargetAvailabilityDidChange(uint64_t, bool);
+    void setShouldPlayToPlaybackTarget(uint64_t, bool);
 #endif
 
     uint64_t m_pageID;
index f3d78ea..852ead1 100644 (file)
@@ -418,8 +418,9 @@ messages -> WebPage LegacyReceiver {
     SetShouldDispatchFakeMouseMoveEvents(bool shouldDispatchFakeMouseMoveEvents)
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-    PlaybackTargetSelected(struct WebCore::MediaPlaybackTargetContext target)
-    PlaybackTargetAvailabilityDidChange(bool available)
+    PlaybackTargetSelected(uint64_t contextId, struct WebCore::MediaPlaybackTargetContext target)
+    PlaybackTargetAvailabilityDidChange(uint64_t contextId, bool available)
+    SetShouldPlayToPlaybackTarget(uint64_t contextId, bool shouldPlay)
 #endif
 
 }
index e0648da..1ba52c3 100644 (file)
@@ -1203,16 +1203,21 @@ void WebPage::setFont(const String& fontFamily, double fontSize, uint64_t fontTr
 }
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS)
-void WebPage::playbackTargetSelected(const WebCore::MediaPlaybackTargetContext& targetContext) const
+void WebPage::playbackTargetSelected(uint64_t contextId, const WebCore::MediaPlaybackTargetContext& targetContext) const
 {
     ASSERT(targetContext.type == MediaPlaybackTargetContext::AVOutputContextType);
 
-    m_page->didChoosePlaybackTarget(WebCore::MediaPlaybackTargetMac::create(targetContext.context.avOutputContext));
+    m_page->setPlaybackTarget(contextId, WebCore::MediaPlaybackTargetMac::create(targetContext.context.avOutputContext));
 }
 
-void WebPage::playbackTargetAvailabilityDidChange(bool changed)
+void WebPage::playbackTargetAvailabilityDidChange(uint64_t contextId, bool changed)
 {
-    m_page->playbackTargetAvailabilityDidChange(changed);
+    m_page->playbackTargetAvailabilityDidChange(contextId, changed);
+}
+
+void WebPage::setShouldPlayToPlaybackTarget(uint64_t contextId, bool shouldPlay)
+{
+    m_page->setShouldPlayToPlaybackTarget(contextId, shouldPlay);
 }
 #endif