<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[181423] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/181423">181423</a></dd>
<dt>Author</dt> <dd>eric.carlson@apple.com</dd>
<dt>Date</dt> <dd>2015-03-11 18:54:06 -0700 (Wed, 11 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Mac] Update AirPlay handling
https://bugs.webkit.org/show_bug.cgi?id=142541

Reviewed by Sam Weinig.

Source/WebCore:

* WebCore.xcodeproj/project.pbxproj:
* dom/Document.cpp:
(WebCore::Document::showPlaybackTargetPicker):
(WebCore::Document::addPlaybackTargetPickerClient):
(WebCore::Document::removePlaybackTargetPickerClient):
(WebCore::Document::configurePlaybackTargetMonitoring):
(WebCore::Document::requiresPlaybackTargetRouteMonitoring):
(WebCore::Document::playbackTargetAvailabilityDidChange):
(WebCore::Document::didChoosePlaybackTarget):
* dom/Document.h:
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::registerWithDocument):
(WebCore::HTMLMediaElement::unregisterWithDocument):
(WebCore::HTMLMediaElement::parseAttribute):
* html/HTMLMediaElement.h:
* html/HTMLMediaSession.cpp:
(WebCore::HTMLMediaSession::HTMLMediaSession):
(WebCore::HTMLMediaSession::registerWithDocument):
(WebCore::HTMLMediaSession::unregisterWithDocument):
(WebCore::HTMLMediaSession::showPlaybackTargetPicker):
(WebCore::HTMLMediaSession::hasWirelessPlaybackTargets):
(WebCore::HTMLMediaSession::setHasPlaybackTargetAvailabilityListeners):
(WebCore::HTMLMediaSession::didChoosePlaybackTarget):
(WebCore::HTMLMediaSession::externalOutputDeviceAvailableDidChange):
(WebCore::HTMLMediaSession::requiresPlaybackTargetRouteMonitoring):
* html/HTMLMediaSession.h:
* page/ChromeClient.h:
* page/Page.cpp:
(WebCore::Page::didChoosePlaybackTarget):
(WebCore::Page::playbackTargetAvailabilityDidChange):
(WebCore::Page::configurePlaybackTargetMonitoring):
* page/Page.h:
(WebCore::Page::hasWirelessPlaybackTarget):
(WebCore::Page::playbackTarget):
* platform/audio/MediaSession.cpp:
(WebCore::MediaSession::clientDataBufferingTimerFired):
(WebCore::MediaSession::wirelessRoutesAvailableDidChange): Deleted.
* platform/audio/MediaSession.h:
(WebCore::MediaSession::didChoosePlaybackTarget):
(WebCore::MediaSession::externalOutputDeviceAvailableDidChange):
(WebCore::MediaSession::requiresPlaybackTargetRouteMonitoring):
(WebCore::MediaSessionClient::setWirelessPlaybackTarget):
* platform/audio/MediaSessionManager.cpp:
(WebCore::MediaSessionManager::wirelessRoutesAvailableChanged): Deleted.
* platform/audio/MediaSessionManager.h:
(WebCore::MediaSessionManager::configureWireLessTargetMonitoring):
* platform/audio/ios/MediaSessionManagerIOS.h:
* platform/audio/ios/MediaSessionManagerIOS.mm:
(WebCore::MediaSessionManageriOS::externalOutputDeviceAvailableDidChange):
(-[WebMediaSessionHelper wirelessRoutesAvailableDidChange:]):
* platform/graphics/AVPlaybackTarget.h: Added.
(WebCore::AVPlaybackTarget::~AVPlaybackTarget):
(WebCore::AVPlaybackTarget::AVPlaybackTarget):
(WebCore::AVPlaybackTarget::setDevicePickerContext):
(WebCore::AVPlaybackTarget::devicePickerContext):
* platform/graphics/AVPlaybackTargetPickerClient.h: Added.
(WebCore::AVPlaybackTargetPickerClient::~AVPlaybackTargetPickerClient):
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::setWirelessPlaybackTarget):
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::setWirelessPlaybackTarget):
* platform/graphics/avfoundation/AVPlaybackTargetMac.mm: Added.
(WebCore::AVPlaybackTarget::encode):
(WebCore::AVPlaybackTarget::decode):
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::cancelLoad):
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayer):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenLayer):
(WebCore::MediaPlayerPrivateAVFoundationObjC::isCurrentPlaybackTargetWireless):
(WebCore::MediaPlayerPrivateAVFoundationObjC::wirelessPlaybackTargetType):
(WebCore::MediaPlayerPrivateAVFoundationObjC::wirelessVideoPlaybackDisabled):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessVideoPlaybackDisabled):
(WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget):
(WebCore::MediaPlayerPrivateAVFoundationObjC::updateDisableExternalPlayback):
(-[WebCoreAVFMovieObserver observeValueForKeyPath:ofObject:change:context:]):

Source/WebKit2:

* Shared/WebCoreArgumentCoders.h:
* Shared/mac/WebCoreArgumentCodersMac.mm:
(IPC::ArgumentCoder&lt;AVPlaybackTarget&gt;::encode):
(IPC::ArgumentCoder&lt;AVPlaybackTarget&gt;::decode):
* UIProcess/PageClient.h:
* UIProcess/WebAVPlaybackTargetPickerProxy.cpp: Added.
(WebKit::WebAVPlaybackTargetPickerProxy::WebAVPlaybackTargetPickerProxy):
(WebKit::WebAVPlaybackTargetPickerProxy::~WebAVPlaybackTargetPickerProxy):
(WebKit::WebAVPlaybackTargetPickerProxy::showPlaybackTargetPicker):
(WebKit::WebAVPlaybackTargetPickerProxy::startingMonitoringPlaybackTargets):
(WebKit::WebAVPlaybackTargetPickerProxy::stopMonitoringPlaybackTargets):
* UIProcess/WebAVPlaybackTargetPickerProxy.h: Added.
(WebKit::WebAVPlaybackTargetPickerProxy::Client::~Client):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::devicePickerProxy):
(WebKit::WebPageProxy::showPlaybackTargetPicker):
(WebKit::WebPageProxy::startingMonitoringPlaybackTargets):
(WebKit::WebPageProxy::stopMonitoringPlaybackTargets):
(WebKit::WebPageProxy::didChoosePlaybackTarget):
(WebKit::WebPageProxy::externalOutputDeviceAvailableDidChange):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::createPlaybackTargetPicker):
* UIProcess/mac/WebAVPlaybackTargetPickerProxyMac.h: Added.
* UIProcess/mac/WebAVPlaybackTargetPickerProxyMac.mm: Added.
(WebKit::WebAVPlaybackTargetPickerProxyMac::create):
(WebKit::WebAVPlaybackTargetPickerProxyMac::WebAVPlaybackTargetPickerProxyMac):
(WebKit::WebAVPlaybackTargetPickerProxyMac::~WebAVPlaybackTargetPickerProxyMac):
(WebKit::WebAVPlaybackTargetPickerProxyMac::outputeDeviceAvailabilityChangedTimerFired):
(WebKit::WebAVPlaybackTargetPickerProxyMac::availableDevicesDidChange):
(WebKit::WebAVPlaybackTargetPickerProxyMac::devicePicker):
(WebKit::WebAVPlaybackTargetPickerProxyMac::showPlaybackTargetPicker):
(WebKit::WebAVPlaybackTargetPickerProxyMac::currentDeviceDidChange):
(WebKit::WebAVPlaybackTargetPickerProxyMac::startingMonitoringPlaybackTargets):
(WebKit::WebAVPlaybackTargetPickerProxyMac::stopMonitoringPlaybackTargets):
(-[WebAVOutputDevicePickerMenuControllerHelper initWithCallback:]):
(-[WebAVOutputDevicePickerMenuControllerHelper clearCallback]):
(-[WebAVOutputDevicePickerMenuControllerHelper observeValueForKeyPath:ofObject:change:context:]):
* WebKit2.xcodeproj/project.pbxproj:
* WebProcess/WebCoreSupport/WebAVPlaybackTargetPicker.cpp: Added.
(WebKit::WebAVPlaybackTargetPicker::WebAVPlaybackTargetPicker):
(WebKit::WebAVPlaybackTargetPicker::showPlaybackDevicePicker):
(WebKit::WebAVPlaybackTargetPicker::configureWireLessTargetMonitoring):
(WebKit::WebAVPlaybackTargetPicker::addClient):
(WebKit::WebAVPlaybackTargetPicker::removeClient):
(WebKit::WebAVPlaybackTargetPicker::didChoosePlaybackTarget):
(WebKit::WebAVPlaybackTargetPicker::playbackTargetAvailabilityDidChange):
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::showPlaybackTargetPicker):
(WebKit::WebChromeClient::startingMonitoringPlaybackTargets):
(WebKit::WebChromeClient::stopMonitoringPlaybackTargets):
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::playbackTargetSelected):
(WebKit::WebPage::playbackTargetAvailabilityDidChange):
* WebProcess/com.apple.WebProcess.sb.in:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumenth">trunk/Source/WebCore/dom/Document.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementcpp">trunk/Source/WebCore/html/HTMLMediaElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementh">trunk/Source/WebCore/html/HTMLMediaElement.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaSessioncpp">trunk/Source/WebCore/html/HTMLMediaSession.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaSessionh">trunk/Source/WebCore/html/HTMLMediaSession.h</a></li>
<li><a href="#trunkSourceWebCorepageChromeClienth">trunk/Source/WebCore/page/ChromeClient.h</a></li>
<li><a href="#trunkSourceWebCorepagePagecpp">trunk/Source/WebCore/page/Page.cpp</a></li>
<li><a href="#trunkSourceWebCorepagePageh">trunk/Source/WebCore/page/Page.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioMediaSessioncpp">trunk/Source/WebCore/platform/audio/MediaSession.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioMediaSessionh">trunk/Source/WebCore/platform/audio/MediaSession.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioMediaSessionManagercpp">trunk/Source/WebCore/platform/audio/MediaSessionManager.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioMediaSessionManagerh">trunk/Source/WebCore/platform/audio/MediaSessionManager.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioiosMediaSessionManagerIOSh">trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioiosMediaSessionManagerIOSmm">trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlayercpp">trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlayerh">trunk/Source/WebCore/platform/graphics/MediaPlayer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlayerPrivateh">trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateAVFoundationObjCh">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateAVFoundationObjCmm">trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm</a></li>
<li><a href="#trunkSourceWebCoretestingInternalSettingscpp">trunk/Source/WebCore/testing/InternalSettings.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingInternalSettingsh">trunk/Source/WebCore/testing/InternalSettings.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedWebCoreArgumentCodersh">trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h</a></li>
<li><a href="#trunkSourceWebKit2SharedmacWebCoreArgumentCodersMacmm">trunk/Source/WebKit2/Shared/mac/WebCoreArgumentCodersMac.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPageClienth">trunk/Source/WebKit2/UIProcess/PageClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxycpp">trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxymessagesin">trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlaybackTargeth">trunk/Source/WebCore/platform/graphics/MediaPlaybackTarget.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsMediaPlaybackTargetPickerClienth">trunk/Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsavfoundationMediaPlaybackTargetMacmm">trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlaybackTargetMac.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebMediaPlaybackTargetPickerProxycpp">trunk/Source/WebKit2/UIProcess/WebMediaPlaybackTargetPickerProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebMediaPlaybackTargetPickerProxyh">trunk/Source/WebKit2/UIProcess/WebMediaPlaybackTargetPickerProxy.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/ChangeLog        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -1,3 +1,88 @@
</span><ins>+2015-03-11  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [Mac] Update AirPlay handling
+        https://bugs.webkit.org/show_bug.cgi?id=142541
+
+        Reviewed by Sam Weinig.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/Document.cpp:
+        (WebCore::Document::showPlaybackTargetPicker):
+        (WebCore::Document::addPlaybackTargetPickerClient):
+        (WebCore::Document::removePlaybackTargetPickerClient):
+        (WebCore::Document::configurePlaybackTargetMonitoring):
+        (WebCore::Document::requiresPlaybackTargetRouteMonitoring):
+        (WebCore::Document::playbackTargetAvailabilityDidChange):
+        (WebCore::Document::didChoosePlaybackTarget):
+        * dom/Document.h:
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::registerWithDocument):
+        (WebCore::HTMLMediaElement::unregisterWithDocument):
+        (WebCore::HTMLMediaElement::parseAttribute):
+        * html/HTMLMediaElement.h:
+        * html/HTMLMediaSession.cpp:
+        (WebCore::HTMLMediaSession::HTMLMediaSession):
+        (WebCore::HTMLMediaSession::registerWithDocument):
+        (WebCore::HTMLMediaSession::unregisterWithDocument):
+        (WebCore::HTMLMediaSession::showPlaybackTargetPicker):
+        (WebCore::HTMLMediaSession::hasWirelessPlaybackTargets):
+        (WebCore::HTMLMediaSession::setHasPlaybackTargetAvailabilityListeners):
+        (WebCore::HTMLMediaSession::didChoosePlaybackTarget):
+        (WebCore::HTMLMediaSession::externalOutputDeviceAvailableDidChange):
+        (WebCore::HTMLMediaSession::requiresPlaybackTargetRouteMonitoring):
+        * html/HTMLMediaSession.h:
+        * page/ChromeClient.h:
+        * page/Page.cpp:
+        (WebCore::Page::didChoosePlaybackTarget):
+        (WebCore::Page::playbackTargetAvailabilityDidChange):
+        (WebCore::Page::configurePlaybackTargetMonitoring):
+        * page/Page.h:
+        (WebCore::Page::hasWirelessPlaybackTarget):
+        (WebCore::Page::playbackTarget):
+        * platform/audio/MediaSession.cpp:
+        (WebCore::MediaSession::clientDataBufferingTimerFired):
+        (WebCore::MediaSession::wirelessRoutesAvailableDidChange): Deleted.
+        * platform/audio/MediaSession.h:
+        (WebCore::MediaSession::didChoosePlaybackTarget):
+        (WebCore::MediaSession::externalOutputDeviceAvailableDidChange):
+        (WebCore::MediaSession::requiresPlaybackTargetRouteMonitoring):
+        (WebCore::MediaSessionClient::setWirelessPlaybackTarget):
+        * platform/audio/MediaSessionManager.cpp:
+        (WebCore::MediaSessionManager::wirelessRoutesAvailableChanged): Deleted.
+        * platform/audio/MediaSessionManager.h:
+        (WebCore::MediaSessionManager::configureWireLessTargetMonitoring):
+        * platform/audio/ios/MediaSessionManagerIOS.h:
+        * platform/audio/ios/MediaSessionManagerIOS.mm:
+        (WebCore::MediaSessionManageriOS::externalOutputDeviceAvailableDidChange):
+        (-[WebMediaSessionHelper wirelessRoutesAvailableDidChange:]):
+        * platform/graphics/AVPlaybackTarget.h: Added.
+        (WebCore::AVPlaybackTarget::~AVPlaybackTarget):
+        (WebCore::AVPlaybackTarget::AVPlaybackTarget):
+        (WebCore::AVPlaybackTarget::setDevicePickerContext):
+        (WebCore::AVPlaybackTarget::devicePickerContext):
+        * platform/graphics/AVPlaybackTargetPickerClient.h: Added.
+        (WebCore::AVPlaybackTargetPickerClient::~AVPlaybackTargetPickerClient):
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::setWirelessPlaybackTarget):
+        * platform/graphics/MediaPlayer.h:
+        * platform/graphics/MediaPlayerPrivate.h:
+        (WebCore::MediaPlayerPrivateInterface::setWirelessPlaybackTarget):
+        * platform/graphics/avfoundation/AVPlaybackTargetMac.mm: Added.
+        (WebCore::AVPlaybackTarget::encode):
+        (WebCore::AVPlaybackTarget::decode):
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::cancelLoad):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayer):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenLayer):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::isCurrentPlaybackTargetWireless):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::wirelessPlaybackTargetType):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::wirelessVideoPlaybackDisabled):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessVideoPlaybackDisabled):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::updateDisableExternalPlayback):
+        (-[WebCoreAVFMovieObserver observeValueForKeyPath:ofObject:change:context:]):
+
</ins><span class="cx"> 2015-03-11  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [Content Extensions] Add resource type and load type triggers.
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -175,6 +175,7 @@
</span><span class="cx">                 074E82BB18A69F0E007EF54C /* PlatformTimeRanges.h in Headers */ = {isa = PBXBuildFile; fileRef = 074E82B918A69F0E007EF54C /* PlatformTimeRanges.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0753860214489E9800B78452 /* CachedTextTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0753860014489E9800B78452 /* CachedTextTrack.cpp */; };
</span><span class="cx">                 0753860314489E9800B78452 /* CachedTextTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = 0753860114489E9800B78452 /* CachedTextTrack.h */; };
</span><ins>+                0760C17A1AA8FC7D009ED7B8 /* MediaPlaybackTargetMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07E3DFD21A9E78A500764CA8 /* MediaPlaybackTargetMac.mm */; };
</ins><span class="cx">                 076306D017E1478D005A7C4E /* MediaStreamTrackSourcesCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 076306CC17E1478D005A7C4E /* MediaStreamTrackSourcesCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 076306D217E1478D005A7C4E /* MediaStreamTrackSourcesRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076306CE17E1478D005A7C4E /* MediaStreamTrackSourcesRequest.cpp */; };
</span><span class="cx">                 076306D317E1478D005A7C4E /* MediaStreamTrackSourcesRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 076306CF17E1478D005A7C4E /* MediaStreamTrackSourcesRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -269,6 +270,7 @@
</span><span class="cx">                 078E094717D16E1C00420AA1 /* RTCVoidRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 07221BB017CF0AD400848E51 /* RTCVoidRequest.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 078E094B17D1709600420AA1 /* MediaStreamAudioDestinationNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 078E094817D1709600420AA1 /* MediaStreamAudioDestinationNode.cpp */; };
</span><span class="cx">                 078E094C17D1709600420AA1 /* MediaStreamAudioDestinationNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 078E094917D1709600420AA1 /* MediaStreamAudioDestinationNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                079216551AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 07941791166E855F009416C2 /* InbandTextTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0794178F166E855F009416C2 /* InbandTextTrack.cpp */; };
</span><span class="cx">                 07941792166E855F009416C2 /* InbandTextTrack.h in Headers */ = {isa = PBXBuildFile; fileRef = 07941790166E855F009416C2 /* InbandTextTrack.h */; };
</span><span class="cx">                 07941794166EA04E009416C2 /* InbandTextTrackPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 07941793166EA04E009416C2 /* InbandTextTrackPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -338,8 +340,10 @@
</span><span class="cx">                 07DC5FD417D3EEE90099F890 /* JSRTCStatsResponseCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07DC5FD317D3EEE90099F890 /* JSRTCStatsResponseCustom.cpp */; };
</span><span class="cx">                 07E116B11489C9A100EC5ACE /* JSTextTrackCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07E116B01489C9A100EC5ACE /* JSTextTrackCustom.cpp */; };
</span><span class="cx">                 07E117071489EBEB00EC5ACE /* JSTextTrackCueCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07E117061489EBEB00EC5ACE /* JSTextTrackCueCustom.cpp */; };
</span><ins>+                07E3DFD11A9E786500764CA8 /* MediaPlaybackTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 07E3DFD01A9E786500764CA8 /* MediaPlaybackTarget.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 07E9E12E18F5E2760011A3A4 /* InbandMetadataTextTrackPrivateAVF.h in Headers */ = {isa = PBXBuildFile; fileRef = 07E9E12D18F5E2760011A3A4 /* InbandMetadataTextTrackPrivateAVF.h */; };
</span><span class="cx">                 07E9E13018F62B370011A3A4 /* InbandMetadataTextTrackPrivateAVF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07E9E12F18F62B370011A3A4 /* InbandMetadataTextTrackPrivateAVF.cpp */; };
</span><ins>+                07EDC3EE1AACB75D00983EB5 /* MediaSessionManagerMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07EDC3ED1AACB75D00983EB5 /* MediaSessionManagerMac.cpp */; };
</ins><span class="cx">                 07F944161864D046005D31CB /* MediaSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CDAE8C081746B95700532D78 /* MediaSessionManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 07FBDE2C18FED178001A7CFF /* JSDataCueCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07FBDE2B18FED178001A7CFF /* JSDataCueCustom.cpp */; };
</span><span class="cx">                 07FE99DC18807A7D00256648 /* HTMLMediaSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07FE99DA18807A7D00256648 /* HTMLMediaSession.cpp */; };
</span><span class="lines">@@ -5687,7 +5691,6 @@
</span><span class="cx">                 CD5393D4175E018600C07123 /* JSMemoryInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5393D2175E018600C07123 /* JSMemoryInfo.h */; };
</span><span class="cx">                 CD54A762180F9F7000B076C9 /* AudioTrackPrivateMediaSourceAVFObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD54A760180F9F7000B076C9 /* AudioTrackPrivateMediaSourceAVFObjC.cpp */; };
</span><span class="cx">                 CD54A763180F9F7000B076C9 /* AudioTrackPrivateMediaSourceAVFObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = CD54A761180F9F7000B076C9 /* AudioTrackPrivateMediaSourceAVFObjC.h */; };
</span><del>-                CD54DE4717468B6F005E5B36 /* MediaSessionManagerMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD54DE4517468B6F005E5B36 /* MediaSessionManagerMac.cpp */; };
</del><span class="cx">                 CD54DE4B17469C6D005E5B36 /* AudioSessionMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD54DE4917469C6D005E5B36 /* AudioSessionMac.cpp */; };
</span><span class="cx">                 CD5596911475B678001D0BD0 /* AudioFileReaderIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD55968F1475B678001D0BD0 /* AudioFileReaderIOS.cpp */; };
</span><span class="cx">                 CD5596921475B678001D0BD0 /* AudioFileReaderIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5596901475B678001D0BD0 /* AudioFileReaderIOS.h */; };
</span><span class="lines">@@ -7267,6 +7270,7 @@
</span><span class="cx">                 078E094817D1709600420AA1 /* MediaStreamAudioDestinationNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamAudioDestinationNode.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 078E094917D1709600420AA1 /* MediaStreamAudioDestinationNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamAudioDestinationNode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 078E094A17D1709600420AA1 /* MediaStreamAudioDestinationNode.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MediaStreamAudioDestinationNode.idl; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MediaPlaybackTargetPickerClient.h; path = graphics/MediaPlaybackTargetPickerClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0794178F166E855F009416C2 /* InbandTextTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InbandTextTrack.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07941790166E855F009416C2 /* InbandTextTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrack.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07941793166EA04E009416C2 /* InbandTextTrackPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandTextTrackPrivate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -7345,8 +7349,11 @@
</span><span class="cx">                 07DC5FD317D3EEE90099F890 /* JSRTCStatsResponseCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRTCStatsResponseCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07E116B01489C9A100EC5ACE /* JSTextTrackCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTextTrackCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07E117061489EBEB00EC5ACE /* JSTextTrackCueCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTextTrackCueCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                07E3DFD01A9E786500764CA8 /* MediaPlaybackTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTarget.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                07E3DFD21A9E78A500764CA8 /* MediaPlaybackTargetMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MediaPlaybackTargetMac.mm; path = platform/graphics/avfoundation/MediaPlaybackTargetMac.mm; sourceTree = SOURCE_ROOT; };
</ins><span class="cx">                 07E9E12D18F5E2760011A3A4 /* InbandMetadataTextTrackPrivateAVF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InbandMetadataTextTrackPrivateAVF.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07E9E12F18F62B370011A3A4 /* InbandMetadataTextTrackPrivateAVF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InbandMetadataTextTrackPrivateAVF.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                07EDC3ED1AACB75D00983EB5 /* MediaSessionManagerMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaSessionManagerMac.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 07FBDE2B18FED178001A7CFF /* JSDataCueCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDataCueCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07FE99DA18807A7D00256648 /* HTMLMediaSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLMediaSession.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 07FE99DB18807A7D00256648 /* HTMLMediaSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLMediaSession.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -13194,7 +13201,6 @@
</span><span class="cx">                 CD5393D2175E018600C07123 /* JSMemoryInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMemoryInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD54A760180F9F7000B076C9 /* AudioTrackPrivateMediaSourceAVFObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioTrackPrivateMediaSourceAVFObjC.cpp; path = objc/AudioTrackPrivateMediaSourceAVFObjC.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD54A761180F9F7000B076C9 /* AudioTrackPrivateMediaSourceAVFObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioTrackPrivateMediaSourceAVFObjC.h; path = objc/AudioTrackPrivateMediaSourceAVFObjC.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                CD54DE4517468B6F005E5B36 /* MediaSessionManagerMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaSessionManagerMac.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 CD54DE4917469C6D005E5B36 /* AudioSessionMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioSessionMac.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD55968F1475B678001D0BD0 /* AudioFileReaderIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioFileReaderIOS.cpp; path = ios/AudioFileReaderIOS.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 CD5596901475B678001D0BD0 /* AudioFileReaderIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioFileReaderIOS.h; path = ios/AudioFileReaderIOS.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -20559,6 +20565,7 @@
</span><span class="cx">                 B27535490B053814002CE64F /* mac */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                07E3DFD21A9E78A500764CA8 /* MediaPlaybackTargetMac.mm */,
</ins><span class="cx">                                 EDE3A4FF0C7A430600956A37 /* ColorMac.h */,
</span><span class="cx">                                 B275354A0B053814002CE64F /* ColorMac.mm */,
</span><span class="cx">                                 37C2360E1097EE7700EF9F72 /* ComplexTextController.cpp */,
</span><span class="lines">@@ -20609,6 +20616,7 @@
</span><span class="cx">                                 FBC220DD1237FBEB00BCF788 /* opengl */,
</span><span class="cx">                                 3721493318F0B6D600156EDC /* opentype */,
</span><span class="cx">                                 49E911B20EF86D27009D0CAF /* transforms */,
</span><ins>+                                07E3DFD01A9E786500764CA8 /* MediaPlaybackTarget.h */,
</ins><span class="cx">                                 490707E41219C04300D90E51 /* ANGLEWebKitBridge.cpp */,
</span><span class="cx">                                 490707E51219C04300D90E51 /* ANGLEWebKitBridge.h */,
</span><span class="cx">                                 BEF29EE91715DD0900C4B4C9 /* AudioTrackPrivate.h */,
</span><span class="lines">@@ -21529,6 +21537,7 @@
</span><span class="cx">                 BCF1A5BA097832090061A123 /* platform */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                079216531AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h */,
</ins><span class="cx">                                 49E912A40EFAC8E6009D0CAF /* animation */,
</span><span class="cx">                                 FD31604012B026A300C1A359 /* audio */,
</span><span class="cx">                                 1AE42F670AA4B8CB00C8612D /* cf */,
</span><span class="lines">@@ -23419,6 +23428,7 @@
</span><span class="cx">                 FD3160B012B0270700C1A359 /* mac */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                07EDC3ED1AACB75D00983EB5 /* MediaSessionManagerMac.cpp */,
</ins><span class="cx">                                 FD3160B512B0272A00C1A359 /* AudioBusMac.mm */,
</span><span class="cx">                                 FD3160B612B0272A00C1A359 /* AudioDestinationMac.cpp */,
</span><span class="cx">                                 FD3160B712B0272A00C1A359 /* AudioDestinationMac.h */,
</span><span class="lines">@@ -23430,7 +23440,6 @@
</span><span class="cx">                                 CDC734121977896C0046BFC5 /* CARingBuffer.cpp */,
</span><span class="cx">                                 CDC734131977896C0046BFC5 /* CARingBuffer.h */,
</span><span class="cx">                                 FD3160BA12B0272A00C1A359 /* FFTFrameMac.cpp */,
</span><del>-                                CD54DE4517468B6F005E5B36 /* MediaSessionManagerMac.cpp */,
</del><span class="cx">                         );
</span><span class="cx">                         path = mac;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -23735,6 +23744,7 @@
</span><span class="cx">                                 BCB16C1C0979C3BD00467741 /* CachedImage.h in Headers */,
</span><span class="cx">                                 319FBD5F15D2F464009640A6 /* CachedImageClient.h in Headers */,
</span><span class="cx">                                 510184690B08602A004A825F /* CachedPage.h in Headers */,
</span><ins>+                                07E3DFD11A9E786500764CA8 /* MediaPlaybackTarget.h in Headers */,
</ins><span class="cx">                                 D0EDA775143E303C0028E383 /* CachedRawResource.h in Headers */,
</span><span class="cx">                                 E1B533491717DEE300F205F9 /* CachedRawResourceClient.h in Headers */,
</span><span class="cx">                                 BCB16C200979C3BD00467741 /* CachedResource.h in Headers */,
</span><span class="lines">@@ -26200,6 +26210,7 @@
</span><span class="cx">                                 9391A991162746CB00297330 /* ScrollingCoordinatorMac.h in Headers */,
</span><span class="cx">                                 93C38BFF164473C700091EB2 /* ScrollingStateFixedNode.h in Headers */,
</span><span class="cx">                                 0FEA3E7B191B2FC5000F1B55 /* ScrollingStateFrameScrollingNode.h in Headers */,
</span><ins>+                                079216551AA560AA00A3C049 /* MediaPlaybackTargetPickerClient.h in Headers */,
</ins><span class="cx">                                 931CBD0D161A44E900E4C874 /* ScrollingStateNode.h in Headers */,
</span><span class="cx">                                 0FEA3E84191B31BF000F1B55 /* ScrollingStateOverflowScrollingNode.h in Headers */,
</span><span class="cx">                                 931CBD0F161A44E900E4C874 /* ScrollingStateScrollingNode.h in Headers */,
</span><span class="lines">@@ -27374,6 +27385,7 @@
</span><span class="cx">                                 FD315FF812B0267600C1A359 /* AudioBuffer.cpp in Sources */,
</span><span class="cx">                                 FD315FFB12B0267600C1A359 /* AudioBufferSourceNode.cpp in Sources */,
</span><span class="cx">                                 FD31607B12B026F700C1A359 /* AudioBus.cpp in Sources */,
</span><ins>+                                07EDC3EE1AACB75D00983EB5 /* MediaSessionManagerMac.cpp in Sources */,
</ins><span class="cx">                                 FD3160BB12B0272A00C1A359 /* AudioBusMac.mm in Sources */,
</span><span class="cx">                                 FD31607D12B026F700C1A359 /* AudioChannel.cpp in Sources */,
</span><span class="cx">                                 FD31600412B0267600C1A359 /* AudioContext.cpp in Sources */,
</span><span class="lines">@@ -27955,6 +27967,7 @@
</span><span class="cx">                                 9BAB6C6D12550631001626D4 /* EditingStyle.cpp in Sources */,
</span><span class="cx">                                 4B3043CC0AE0373B00A82647 /* Editor.cpp in Sources */,
</span><span class="cx">                                 93A38B4B0D0E5808006872C2 /* EditorCommand.cpp in Sources */,
</span><ins>+                                0760C17A1AA8FC7D009ED7B8 /* MediaPlaybackTargetMac.mm in Sources */,
</ins><span class="cx">                                 FED13D3A0CEA934600D89466 /* EditorIOS.mm in Sources */,
</span><span class="cx">                                 ED501DC60B249F2900AE18D9 /* EditorMac.mm in Sources */,
</span><span class="cx">                                 A8C4A80809D563270003AC8D /* Element.cpp in Sources */,
</span><span class="lines">@@ -29178,7 +29191,6 @@
</span><span class="cx">                                 070E091B1875EF71003A1D3C /* MediaSession.cpp in Sources */,
</span><span class="cx">                                 CDAE8C091746B95700532D78 /* MediaSessionManager.cpp in Sources */,
</span><span class="cx">                                 07638A9A1884487200E15A1B /* MediaSessionManagerIOS.mm in Sources */,
</span><del>-                                CD54DE4717468B6F005E5B36 /* MediaSessionManagerMac.cpp in Sources */,
</del><span class="cx">                                 CD3A495E17A9D01B00274E42 /* MediaSource.cpp in Sources */,
</span><span class="cx">                                 CDC8B5A6180474F70016E685 /* MediaSourcePrivateAVFObjC.mm in Sources */,
</span><span class="cx">                                 CD61FE671794AADB004101EB /* MediaSourceRegistry.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/dom/Document.cpp        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -228,6 +228,10 @@
</span><span class="cx"> #include &lt;replay/InputCursor.h&gt;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#include &quot;HTMLVideoElement.h&quot;
+#endif
+
</ins><span class="cx"> using namespace WTF;
</span><span class="cx"> using namespace Unicode;
</span><span class="cx"> 
</span><span class="lines">@@ -6451,4 +6455,82 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+void Document::showPlaybackTargetPicker(const HTMLMediaElement&amp; element)
+{
+    Page* page = this-&gt;page();
+    if (!page)
+        return;
+
+    page-&gt;showPlaybackTargetPicker(this, view()-&gt;lastKnownMousePosition(), is&lt;HTMLVideoElement&gt;(element));
+}
+
+void Document::addPlaybackTargetPickerClient(MediaPlaybackTargetPickerClient&amp; client)
+{
+    Page* page = this-&gt;page();
+    if (!page)
+        return;
+
+    m_playbackTargetClients.add(&amp;client);
+
+    client.didChoosePlaybackTarget(page-&gt;playbackTarget());
+    client.externalOutputDeviceAvailableDidChange(page-&gt;hasWirelessPlaybackTarget());
+}
+
+void Document::removePlaybackTargetPickerClient(MediaPlaybackTargetPickerClient&amp; client)
+{
+    m_playbackTargetClients.remove(&amp;client);
+    configurePlaybackTargetMonitoring();
+}
+
+void Document::configurePlaybackTargetMonitoring()
+{
+    Page* page = this-&gt;page();
+    if (!page)
+        return;
+
+    page-&gt;configurePlaybackTargetMonitoring();
+}
+
+bool Document::requiresPlaybackTargetRouteMonitoring()
+{
+    for (auto* client : m_playbackTargetClients) {
+        if (client-&gt;requiresPlaybackTargetRouteMonitoring()) {
+            return true;
+            break;
+        }
+    }
+
+    return false;
+}
+
+void Document::playbackTargetAvailabilityDidChange(bool available)
+{
+    if (m_playbackTargetsAvailable == available)
+        return;
+    m_playbackTargetsAvailable = available;
+
+    for (auto* client : m_playbackTargetClients)
+        client-&gt;externalOutputDeviceAvailableDidChange(available);
+}
+
+void Document::didChoosePlaybackTarget(MediaPlaybackTarget&amp; device)
+{
+    MediaPlaybackTargetPickerClient* clientThatRequestedPicker = nullptr;
+
+    for (auto* client : m_playbackTargetClients) {
+        if (client-&gt;requestedPlaybackTargetPicker()) {
+            clientThatRequestedPicker = client;
+            continue;
+        }
+
+        client-&gt;didChoosePlaybackTarget(device);
+    }
+
+    if (clientThatRequestedPicker)
+        clientThatRequestedPicker-&gt;didChoosePlaybackTarget(device);
+}
+
+#endif
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/dom/Document.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -124,6 +124,8 @@
</span><span class="cx"> class JSNode;
</span><span class="cx"> class Locale;
</span><span class="cx"> class MediaCanStartListener;
</span><ins>+class MediaPlaybackTarget;
+class MediaPlaybackTargetPickerClient;
</ins><span class="cx"> class MediaQueryList;
</span><span class="cx"> class MediaQueryMatcher;
</span><span class="cx"> class MouseEventWithHitTestResults;
</span><span class="lines">@@ -1218,6 +1220,16 @@
</span><span class="cx">     void pageMutedStateDidChange();
</span><span class="cx">     WeakPtr&lt;Document&gt; createWeakPtr() { return m_weakFactory.createWeakPtr(); }
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    void showPlaybackTargetPicker(const HTMLMediaElement&amp;);
+    void didChoosePlaybackTarget(MediaPlaybackTarget&amp;);
+    void addPlaybackTargetPickerClient(MediaPlaybackTargetPickerClient&amp;);
+    void removePlaybackTargetPickerClient(MediaPlaybackTargetPickerClient&amp;);
+    bool requiresPlaybackTargetRouteMonitoring();
+    void configurePlaybackTargetMonitoring();
+    void playbackTargetAvailabilityDidChange(bool);
+#endif
+
</ins><span class="cx"> protected:
</span><span class="cx">     enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 &lt;&lt; 1 };
</span><span class="cx">     Document(Frame*, const URL&amp;, unsigned = DefaultDocumentClass, unsigned constructionFlags = 0);
</span><span class="lines">@@ -1655,6 +1667,11 @@
</span><span class="cx"> 
</span><span class="cx">     HashSet&lt;AudioProducer*&gt; m_audioProducers;
</span><span class="cx">     bool m_isPlayingAudio;
</span><ins>+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    HashSet&lt;WebCore::MediaPlaybackTargetPickerClient*&gt; m_playbackTargetClients;
+    bool m_playbackTargetsAvailable { false };
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline void Document::notifyRemovePendingSheetIfNeeded()
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -426,6 +426,8 @@
</span><span class="cx"> 
</span><span class="cx"> void HTMLMediaElement::registerWithDocument(Document&amp; document)
</span><span class="cx"> {
</span><ins>+    m_mediaSession-&gt;registerWithDocument(document);
+
</ins><span class="cx">     if (m_isWaitingUntilMediaCanStart)
</span><span class="cx">         document.addMediaCanStartListener(this);
</span><span class="cx"> 
</span><span class="lines">@@ -451,6 +453,8 @@
</span><span class="cx"> 
</span><span class="cx"> void HTMLMediaElement::unregisterWithDocument(Document&amp; document)
</span><span class="cx"> {
</span><ins>+    m_mediaSession-&gt;unregisterWithDocument(document);
+
</ins><span class="cx">     if (m_isWaitingUntilMediaCanStart)
</span><span class="cx">         document.removeMediaCanStartListener(this);
</span><span class="cx"> 
</span><span class="lines">@@ -2471,6 +2475,9 @@
</span><span class="cx"> 
</span><span class="cx"> void HTMLMediaElement::invalidateCachedTime() const
</span><span class="cx"> {
</span><ins>+    if (!m_player-&gt;maximumDurationToCacheMediaTime())
+        return;
+
</ins><span class="cx"> #if !LOG_DISABLED
</span><span class="cx">     if (m_cachedTime.isValid())
</span><span class="cx">         LOG(Media, &quot;HTMLMediaElement::invalidateCachedTime(%p)&quot;, this);
</span><span class="lines">@@ -4856,6 +4863,13 @@
</span><span class="cx">     event-&gt;setTarget(this);
</span><span class="cx">     m_asyncEventQueue.enqueueEvent(event.release());
</span><span class="cx"> }
</span><ins>+
+void HTMLMediaElement::setWirelessPlaybackTarget(const MediaPlaybackTarget&amp; device)
+{
+    LOG(Media, &quot;HTMLMediaElement::setWirelessPlaybackTarget(%p)&quot;, this);
+    if (m_player)
+        m_player-&gt;setWirelessPlaybackTarget(device);
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> double HTMLMediaElement::minFastReverseRate() const
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2007-2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2007-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -357,7 +357,9 @@
</span><span class="cx"> 
</span><span class="cx">     virtual bool addEventListener(const AtomicString&amp; eventType, PassRefPtr&lt;EventListener&gt;, bool useCapture) override;
</span><span class="cx">     virtual bool removeEventListener(const AtomicString&amp; eventType, EventListener*, bool useCapture) override;
</span><ins>+
</ins><span class="cx">     virtual void wirelessRoutesAvailableDidChange() override;
</span><ins>+    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&amp;) override;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     // EventTarget function.
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaSessioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaSession.cpp (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaSession.cpp        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/html/HTMLMediaSession.cpp        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -31,7 +31,9 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Chrome.h&quot;
</span><span class="cx"> #include &quot;ChromeClient.h&quot;
</span><ins>+#include &quot;Document.h&quot;
</ins><span class="cx"> #include &quot;Frame.h&quot;
</span><ins>+#include &quot;FrameView.h&quot;
</ins><span class="cx"> #include &quot;HTMLMediaElement.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="lines">@@ -72,10 +74,30 @@
</span><span class="cx"> HTMLMediaSession::HTMLMediaSession(MediaSessionClient&amp; client)
</span><span class="cx">     : MediaSession(client)
</span><span class="cx">     , m_restrictions(NoRestrictions)
</span><del>-    , m_hasPlaybackTargetAvailabilityListeners(false)
</del><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    , m_targetAvailabilityChangedTimer(*this, &amp;HTMLMediaSession::targetAvailabilityChangedTimerFired)
+#endif
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void HTMLMediaSession::registerWithDocument(Document&amp; document)
+{
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    document.addPlaybackTargetPickerClient(*this);
+#else
+    UNUSED_PARAM(document);
+#endif
+}
+
+void HTMLMediaSession::unregisterWithDocument(Document&amp; document)
+{
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    document.removePlaybackTargetPickerClient(*this);
+#else
+    UNUSED_PARAM(document);
+#endif
+}
+
</ins><span class="cx"> void HTMLMediaSession::addBehaviorRestriction(BehaviorRestrictions restriction)
</span><span class="cx"> {
</span><span class="cx">     LOG(Media, &quot;HTMLMediaSession::addBehaviorRestriction - adding %s&quot;, restrictionName(restriction));
</span><span class="lines">@@ -177,19 +199,20 @@
</span><span class="cx">     if (!showingPlaybackTargetPickerPermitted(element))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS)
-    element.document().frame()-&gt;page()-&gt;chrome().client().showPlaybackTargetPicker(element.hasVideo());
-#endif
</del><ins>+    m_haveRequestedPlaybackTargetPicker = true;
+    element.document().showPlaybackTargetPicker(element);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool HTMLMediaSession::hasWirelessPlaybackTargets(const HTMLMediaElement&amp; element) const
</del><ins>+bool HTMLMediaSession::hasWirelessPlaybackTargets(const HTMLMediaElement&amp;) const
</ins><span class="cx"> {
</span><del>-    UNUSED_PARAM(element);
</del><ins>+#if PLATFORM(IOS)
+    // FIXME: consolidate Mac and iOS implementations
+    m_hasPlaybackTargets = MediaSessionManager::sharedManager().hasWirelessTargetsAvailable();
+#endif
</ins><span class="cx"> 
</span><del>-    bool hasTargets = MediaSessionManager::sharedManager().hasWirelessTargetsAvailable();
-    LOG(Media, &quot;HTMLMediaSession::hasWirelessPlaybackTargets - returning %s&quot;, hasTargets ? &quot;TRUE&quot; : &quot;FALSE&quot;);
</del><ins>+    LOG(Media, &quot;HTMLMediaSession::hasWirelessPlaybackTargets - returning %s&quot;, m_hasPlaybackTargets ? &quot;TRUE&quot; : &quot;FALSE&quot;);
</ins><span class="cx"> 
</span><del>-    return hasTargets;
</del><ins>+    return m_hasPlaybackTargets;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool HTMLMediaSession::wirelessVideoPlaybackDisabled(const HTMLMediaElement&amp; element) const
</span><span class="lines">@@ -244,8 +267,39 @@
</span><span class="cx">     UNUSED_PARAM(element);
</span><span class="cx"> 
</span><span class="cx">     m_hasPlaybackTargetAvailabilityListeners = hasListeners;
</span><ins>+
+#if PLATFORM(IOS)
</ins><span class="cx">     MediaSessionManager::sharedManager().configureWireLessTargetMonitoring();
</span><ins>+#else
+    element.document().configurePlaybackTargetMonitoring();
+#endif
</ins><span class="cx"> }
</span><ins>+
+void HTMLMediaSession::didChoosePlaybackTarget(MediaPlaybackTarget&amp; device)
+{
+    m_haveRequestedPlaybackTargetPicker = false;
+    client().setWirelessPlaybackTarget(device);
+}
+
+void HTMLMediaSession::targetAvailabilityChangedTimerFired()
+{
+    client().wirelessRoutesAvailableDidChange();
+}
+
+void HTMLMediaSession::externalOutputDeviceAvailableDidChange(bool hasTargets) const
+{
+    if (m_hasPlaybackTargets == hasTargets)
+        return;
+
+    m_hasPlaybackTargets = hasTargets;
+    if (!m_targetAvailabilityChangedTimer.isActive())
+        m_targetAvailabilityChangedTimer.startOneShot(0);
+}
+
+bool HTMLMediaSession::requiresPlaybackTargetRouteMonitoring() const
+{
+    return m_hasPlaybackTargetAvailabilityListeners;
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> MediaPlayer::Preload HTMLMediaSession::effectivePreloadForElement(const HTMLMediaElement&amp; element) const
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaSessionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaSession.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaSession.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/html/HTMLMediaSession.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -30,9 +30,11 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;MediaPlayer.h&quot;
</span><span class="cx"> #include &quot;MediaSession.h&quot;
</span><ins>+#include &quot;Timer.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class Document;
</ins><span class="cx"> class HTMLMediaElement;
</span><span class="cx"> class SourceBuffer;
</span><span class="cx"> 
</span><span class="lines">@@ -41,14 +43,17 @@
</span><span class="cx">     explicit HTMLMediaSession(MediaSessionClient&amp;);
</span><span class="cx">     virtual ~HTMLMediaSession() { }
</span><span class="cx"> 
</span><ins>+    void registerWithDocument(Document&amp;);
+    void unregisterWithDocument(Document&amp;);
+
</ins><span class="cx">     bool playbackPermitted(const HTMLMediaElement&amp;) const;
</span><span class="cx">     bool dataLoadingPermitted(const HTMLMediaElement&amp;) const;
</span><span class="cx">     bool fullscreenPermitted(const HTMLMediaElement&amp;) const;
</span><span class="cx">     bool pageAllowsDataLoading(const HTMLMediaElement&amp;) const;
</span><span class="cx">     bool pageAllowsPlaybackAfterResuming(const HTMLMediaElement&amp;) const;
</span><ins>+
</ins><span class="cx"> #if ENABLE(WIRELESS_PLAYBACK_TARGET)
</span><span class="cx">     bool showingPlaybackTargetPickerPermitted(const HTMLMediaElement&amp;) const;
</span><del>-
</del><span class="cx">     bool currentPlaybackTargetIsWireless(const HTMLMediaElement&amp;) const;
</span><span class="cx">     void showPlaybackTargetPicker(const HTMLMediaElement&amp;);
</span><span class="cx">     bool hasWirelessPlaybackTargets(const HTMLMediaElement&amp;) const;
</span><span class="lines">@@ -58,6 +63,7 @@
</span><span class="cx"> 
</span><span class="cx">     void setHasPlaybackTargetAvailabilityListeners(const HTMLMediaElement&amp;, bool);
</span><span class="cx"> #endif
</span><ins>+
</ins><span class="cx">     bool requiresFullscreenForVideoPlayback(const HTMLMediaElement&amp;) const;
</span><span class="cx">     WEBCORE_EXPORT bool allowsAlternateFullscreen(const HTMLMediaElement&amp;) const;
</span><span class="cx">     MediaPlayer::Preload effectivePreloadForElement(const HTMLMediaElement&amp;) const;
</span><span class="lines">@@ -87,10 +93,25 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    virtual bool requiresPlaybackTargetRouteMonitoring() const override { return m_hasPlaybackTargetAvailabilityListeners; }
</del><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    void targetAvailabilityChangedTimerFired();
+
+    // MediaPlaybackTargetPickerClient
+    virtual void didChoosePlaybackTarget(MediaPlaybackTarget&amp;) override;
+    virtual void externalOutputDeviceAvailableDidChange(bool) const override;
+    virtual bool requiresPlaybackTargetRouteMonitoring() const override;
+    virtual bool requestedPlaybackTargetPicker() const override { return m_haveRequestedPlaybackTargetPicker; }
+#endif
+
</ins><span class="cx">     BehaviorRestrictions m_restrictions;
</span><del>-    bool m_hasPlaybackTargetAvailabilityListeners;
</del><ins>+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    mutable Timer m_targetAvailabilityChangedTimer;
+    bool m_hasPlaybackTargetAvailabilityListeners { false };
+    mutable bool m_hasPlaybackTargets { false };
+    mutable bool m_haveRequestedPlaybackTargetPicker { false };
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorepageChromeClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/ChromeClient.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/ChromeClient.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/page/ChromeClient.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -447,6 +447,12 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void handleAutoFillButtonClick(HTMLInputElement&amp;) { }
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    virtual void showPlaybackTargetPicker(const WebCore::IntPoint&amp;, bool) { }
+    virtual void startingMonitoringPlaybackTargets() { }
+    virtual void stopMonitoringPlaybackTargets() { }
+#endif
+
</ins><span class="cx"> protected:
</span><span class="cx">     virtual ~ChromeClient() { }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCorepagePagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.cpp (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.cpp        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/page/Page.cpp        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -104,6 +104,12 @@
</span><span class="cx"> #include &lt;replay/InputCursor.h&gt;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#include &quot;HTMLVideoElement.h&quot;
+#include &quot;MediaPlaybackTarget.h&quot;
+#include &quot;MediaPlaybackTargetPickerClient.h&quot;
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> static HashSet&lt;Page*&gt;* allPages;
</span><span class="lines">@@ -1691,4 +1697,67 @@
</span><span class="cx">         view-&gt;privateBrowsingStateChanged(sessionID.isEphemeral());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+void Page::showPlaybackTargetPicker(Document* document, const WebCore::IntPoint&amp; location, bool isVideo)
+{
+
+    m_documentRequestingPlaybackTargetPicker = document;
+#if PLATFORM(IOS)
+    // FIXME: refactor iOS implementation.
+    UNUSED_PARAM(location);
+    chrome().client().showPlaybackTargetPicker(isVideo);
+#else
+    chrome().client().showPlaybackTargetPicker(location, isVideo);
+#endif
+}
+
+void Page::didChoosePlaybackTarget(MediaPlaybackTarget&amp; target)
+{
+    Document* documentThatRequestedPicker = nullptr;
+
+    m_playbackTarget = std::make_unique&lt;MediaPlaybackTarget&gt;(target.devicePickerContext());
+    for (Frame* frame = &amp;mainFrame(); frame; frame = frame-&gt;tree().traverseNext()) {
+        Document* document = frame-&gt;document();
+        if (frame-&gt;document() == m_documentRequestingPlaybackTargetPicker) {
+            documentThatRequestedPicker = document;
+            continue;
+        }
+        frame-&gt;document()-&gt;didChoosePlaybackTarget(target);
+    }
+
+    if (documentThatRequestedPicker)
+        documentThatRequestedPicker-&gt;didChoosePlaybackTarget(target);
+
+    m_documentRequestingPlaybackTargetPicker = nullptr;
+}
+
+void Page::playbackTargetAvailabilityDidChange(bool available)
+{
+    m_hasWirelessPlaybackTarget = available;
+    for (Frame* frame = &amp;mainFrame(); frame; frame = frame-&gt;tree().traverseNext())
+        frame-&gt;document()-&gt;playbackTargetAvailabilityDidChange(available);
+}
+
+void Page::configurePlaybackTargetMonitoring()
+{
+    bool monitoringRequired = false;
+    for (Frame* frame = &amp;mainFrame(); frame; frame = frame-&gt;tree().traverseNext()) {
+        if (frame-&gt;document()-&gt;requiresPlaybackTargetRouteMonitoring()) {
+            monitoringRequired = true;
+            break;
+        }
+    }
+
+    if (m_requiresPlaybackTargetMonitoring == monitoringRequired)
+        return;
+    m_requiresPlaybackTargetMonitoring = monitoringRequired;
+
+
+    if (monitoringRequired)
+        chrome().client().startingMonitoringPlaybackTargets();
+    else
+        chrome().client().stopMonitoringPlaybackTargets();
+}
+#endif
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorepagePageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/page/Page.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -76,11 +76,13 @@
</span><span class="cx"> class Frame;
</span><span class="cx"> class FrameLoaderClient;
</span><span class="cx"> class HistoryItem;
</span><ins>+class HTMLMediaElement;
</ins><span class="cx"> class UserInputBridge;
</span><span class="cx"> class InspectorClient;
</span><span class="cx"> class InspectorController;
</span><span class="cx"> class MainFrame;
</span><span class="cx"> class MediaCanStartListener;
</span><ins>+class MediaPlaybackTarget;
</ins><span class="cx"> class PageConfiguration;
</span><span class="cx"> class PageConsoleClient;
</span><span class="cx"> class PageDebuggable;
</span><span class="lines">@@ -422,6 +424,16 @@
</span><span class="cx">     bool isMuted() const { return m_muted; }
</span><span class="cx">     WEBCORE_EXPORT void setMuted(bool);
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    void showPlaybackTargetPicker(Document*, const WebCore::IntPoint&amp;, bool);
+    bool hasWirelessPlaybackTarget() const { return m_hasWirelessPlaybackTarget; }
+    MediaPlaybackTarget&amp; playbackTarget() const { return *m_playbackTarget.get(); }
+    void configurePlaybackTargetMonitoring();
+
+    WEBCORE_EXPORT void didChoosePlaybackTarget(MediaPlaybackTarget&amp;);
+    WEBCORE_EXPORT void playbackTargetAvailabilityDidChange(bool);
+#endif
+
</ins><span class="cx"> private:
</span><span class="cx">     WEBCORE_EXPORT void initGroup();
</span><span class="cx"> 
</span><span class="lines">@@ -581,6 +593,13 @@
</span><span class="cx"> 
</span><span class="cx">     SessionID m_sessionID;
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    Document* m_documentRequestingPlaybackTargetPicker { nullptr };
+    std::unique_ptr&lt;MediaPlaybackTarget&gt; m_playbackTarget;
+    bool m_requiresPlaybackTargetMonitoring { false };
+    bool m_hasWirelessPlaybackTarget { false };
+#endif
+
</ins><span class="cx">     bool m_isClosing;
</span><span class="cx"> 
</span><span class="cx">     bool m_isPlayingAudio;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioMediaSessioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/MediaSession.cpp (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/MediaSession.cpp        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/audio/MediaSession.cpp        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -190,7 +190,7 @@
</span><span class="cx"> 
</span><span class="cx"> void MediaSession::clientDataBufferingTimerFired()
</span><span class="cx"> {
</span><del>-    LOG(Media, &quot;MediaSession::visibilityChanged(%p)- visible = %s&quot;, this, m_client.elementIsHidden() ? &quot;false&quot; : &quot;true&quot;);
</del><ins>+    LOG(Media, &quot;MediaSession::clientDataBufferingTimerFired(%p)- visible = %s&quot;, this, m_client.elementIsHidden() ? &quot;false&quot; : &quot;true&quot;);
</ins><span class="cx"> 
</span><span class="cx">     updateClientDataBuffering();
</span><span class="cx"> 
</span><span class="lines">@@ -220,11 +220,6 @@
</span><span class="cx">     return m_client.displayType();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MediaSession::wirelessRoutesAvailableDidChange() const
-{
-    m_client.wirelessRoutesAvailableDidChange();
-}
-
</del><span class="cx"> String MediaSessionClient::mediaSessionTitle() const
</span><span class="cx"> {
</span><span class="cx">     return String();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioMediaSessionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/MediaSession.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/MediaSession.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/audio/MediaSession.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -30,11 +30,20 @@
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#include &quot;MediaPlaybackTargetPickerClient.h&quot;
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class MediaPlaybackTarget;
</ins><span class="cx"> class MediaSessionClient;
</span><span class="cx"> 
</span><del>-class MediaSession {
</del><ins>+class MediaSession
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    : public MediaPlaybackTargetPickerClient
+#endif
+{
</ins><span class="cx"> public:
</span><span class="cx">     static std::unique_ptr&lt;MediaSession&gt; create(MediaSessionClient&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -99,9 +108,6 @@
</span><span class="cx">     bool canReceiveRemoteControlCommands() const;
</span><span class="cx">     void didReceiveRemoteControlCommand(RemoteControlCommandType);
</span><span class="cx"> 
</span><del>-    virtual bool requiresPlaybackTargetRouteMonitoring() const { return false; }
-    void wirelessRoutesAvailableDidChange() const;
-
</del><span class="cx">     enum DisplayType {
</span><span class="cx">         Normal,
</span><span class="cx">         Fullscreen,
</span><span class="lines">@@ -111,6 +117,14 @@
</span><span class="cx"> 
</span><span class="cx">     bool isHidden() const;
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    // MediaPlaybackTargetPickerClient
+    virtual void didChoosePlaybackTarget(MediaPlaybackTarget&amp;) override { }
+    virtual void externalOutputDeviceAvailableDidChange(bool) const override { }
+    virtual bool requiresPlaybackTargetRouteMonitoring() const override { return false; }
+    virtual bool requestedPlaybackTargetPicker() const override { return false; }
+#endif
+
</ins><span class="cx"> protected:
</span><span class="cx">     MediaSessionClient&amp; client() const { return m_client; }
</span><span class="cx"> 
</span><span class="lines">@@ -150,7 +164,10 @@
</span><span class="cx"> 
</span><span class="cx">     virtual bool overrideBackgroundPlaybackRestriction() const = 0;
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
</ins><span class="cx">     virtual void wirelessRoutesAvailableDidChange() { }
</span><ins>+    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&amp;) { }
+#endif
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     virtual ~MediaSessionClient() { }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioMediaSessionManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/MediaSessionManager.cpp (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/MediaSessionManager.cpp        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/audio/MediaSessionManager.cpp        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -285,14 +285,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MediaSessionManager::wirelessRoutesAvailableChanged()
-{
-    LOG(Media, &quot;MediaSessionManager::wirelessRoutesAvailableChanged&quot;);
-    Vector&lt;MediaSession*&gt; sessions = m_sessions;
-    for (auto* session : sessions)
-        session-&gt;wirelessRoutesAvailableDidChange();
-}
-
</del><span class="cx"> #if !PLATFORM(COCOA)
</span><span class="cx"> void MediaSessionManager::updateSessionState()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioMediaSessionManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/MediaSessionManager.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/MediaSessionManager.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/audio/MediaSessionManager.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -54,7 +54,6 @@
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void applicationWillEnterForeground() const;
</span><span class="cx">     WEBCORE_EXPORT void applicationWillEnterBackground() const;
</span><del>-    void wirelessRoutesAvailableChanged();
</del><span class="cx"> 
</span><span class="cx">     enum SessionRestrictionFlags {
</span><span class="cx">         NoRestrictions = 0,
</span><span class="lines">@@ -79,9 +78,8 @@
</span><span class="cx"> 
</span><span class="cx">     virtual bool sessionCanLoadMedia(const MediaSession&amp;) const;
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
</ins><span class="cx">     virtual void configureWireLessTargetMonitoring() { }
</span><del>-
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
</del><span class="cx">     virtual bool hasWirelessTargetsAvailable() { return false; }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioiosMediaSessionManagerIOSh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -45,9 +45,14 @@
</span><span class="cx"> public:
</span><span class="cx">     virtual ~MediaSessionManageriOS();
</span><span class="cx"> 
</span><ins>+    void externalOutputDeviceAvailableDidChange();
+    virtual bool hasWirelessTargetsAvailable() override;
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class MediaSessionManager;
</span><span class="cx"> 
</span><ins>+    MediaSessionManageriOS();
+
</ins><span class="cx">     virtual void sessionWillBeginPlayback(MediaSession&amp;) override;
</span><span class="cx">     virtual void sessionWillEndPlayback(MediaSession&amp;) override;
</span><span class="cx">     
</span><span class="lines">@@ -55,14 +60,10 @@
</span><span class="cx">     
</span><span class="cx">     virtual void resetRestrictions() override;
</span><span class="cx"> 
</span><del>-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    virtual bool hasWirelessTargetsAvailable() override;
</del><span class="cx">     virtual void configureWireLessTargetMonitoring() override;
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">     virtual bool sessionCanLoadMedia(const MediaSession&amp;) const override;
</span><del>-
-    MediaSessionManageriOS();
</del><ins>+    
</ins><span class="cx">     RetainPtr&lt;WebMediaSessionHelper&gt; m_objcObserver;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioiosMediaSessionManagerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -159,7 +159,6 @@
</span><span class="cx">     addRestriction(MediaSession::Video, AutoPreloadingNotPermitted);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
</del><span class="cx"> bool MediaSessionManageriOS::hasWirelessTargetsAvailable()
</span><span class="cx"> {
</span><span class="cx">     return [m_objcObserver hasWirelessTargetsAvailable];
</span><span class="lines">@@ -184,8 +183,7 @@
</span><span class="cx">     else
</span><span class="cx">         [m_objcObserver stopMonitoringAirPlayRoutes];
</span><span class="cx"> }
</span><del>-#endif
-    
</del><ins>+
</ins><span class="cx"> void MediaSessionManageriOS::sessionWillBeginPlayback(MediaSession&amp; session)
</span><span class="cx"> {
</span><span class="cx">     MediaSessionManager::sessionWillBeginPlayback(session);
</span><span class="lines">@@ -233,6 +231,14 @@
</span><span class="cx">     return session.state() == MediaSession::Playing || !session.isHidden() || session.displayType() == MediaSession::Optimized;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void MediaSessionManageriOS::externalOutputDeviceAvailableDidChange()
+{
+    Vector&lt;MediaSession*&gt; sessionList = sessions();
+    bool haveTargets = [m_objcObserver hasWirelessTargetsAvailable];
+    for (auto* session : sessionList)
+        session-&gt;externalOutputDeviceAvailableDidChange(haveTargets);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> @implementation WebMediaSessionHelper
</span><span class="lines">@@ -445,7 +451,7 @@
</span><span class="cx">         if (!_callback)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        _callback-&gt;wirelessRoutesAvailableChanged();
</del><ins>+        _callback-&gt;externalOutputDeviceAvailableDidChange();
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> @end
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlaybackTargeth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/MediaPlaybackTarget.h (0 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlaybackTarget.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/MediaPlaybackTarget.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+/*
+ * 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. ``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
+ * 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 MediaPlaybackTarget_h
+#define MediaPlaybackTarget_h
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+#include &lt;wtf/RetainPtr.h&gt;
+
+#if PLATFORM(COCOA)
+OBJC_CLASS NSKeyedArchiver;
+OBJC_CLASS NSKeyedUnarchiver;
+OBJC_CLASS AVOutputDevicePickerContext;
+#endif
+
+namespace WebCore {
+
+class MediaPlaybackTarget {
+public:
+    virtual ~MediaPlaybackTarget() { }
+
+#if PLATFORM(COCOA)
+    WEBCORE_EXPORT MediaPlaybackTarget(AVOutputDevicePickerContext *context = nil) { m_devicePickerContext = context; }
+
+    WEBCORE_EXPORT void encode(NSKeyedArchiver *) const;
+    WEBCORE_EXPORT static bool decode(NSKeyedUnarchiver *, MediaPlaybackTarget&amp;);
+
+    void setDevicePickerContext(AVOutputDevicePickerContext *context) { m_devicePickerContext = context; }
+    AVOutputDevicePickerContext *devicePickerContext() const { return m_devicePickerContext.get(); }
+#endif
+
+protected:
+#if PLATFORM(COCOA)
+    RetainPtr&lt;AVOutputDevicePickerContext&gt; m_devicePickerContext;
+#endif
+};
+
+}
+
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlaybackTargetPickerClienth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h (0 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/MediaPlaybackTargetPickerClient.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+/*
+ * 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 MediaPlaybackTargetPickerClient_h
+#define MediaPlaybackTargetPickerClient_h
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+#include &quot;MediaPlaybackTarget.h&quot;
+
+namespace WebCore {
+
+class MediaPlaybackTarget;
+
+class MediaPlaybackTargetPickerClient {
+public:
+    virtual ~MediaPlaybackTargetPickerClient() { }
+
+    virtual void didChoosePlaybackTarget(MediaPlaybackTarget&amp;) = 0;
+    virtual void externalOutputDeviceAvailableDidChange(bool) const = 0;
+
+    virtual bool requiresPlaybackTargetRouteMonitoring() const = 0;
+    virtual bool requestedPlaybackTargetPicker() const = 0;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+#endif // MediaPlaybackTargetPickerClient_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -867,6 +867,11 @@
</span><span class="cx"> {
</span><span class="cx">     m_client.mediaPlayerCurrentPlaybackTargetIsWirelessChanged(this);
</span><span class="cx"> }
</span><ins>+
+void MediaPlayer::setWirelessPlaybackTarget(const MediaPlaybackTarget&amp; device)
+{
+    m_private-&gt;setWirelessPlaybackTarget(device);
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> double MediaPlayer::maxFastForwardRate() const
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/MediaPlayer.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlayer.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayer.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -71,6 +71,7 @@
</span><span class="cx"> 
</span><span class="cx"> class AudioSourceProvider;
</span><span class="cx"> class AuthenticationChallenge;
</span><ins>+class MediaPlaybackTarget;
</ins><span class="cx"> #if ENABLE(MEDIA_SOURCE)
</span><span class="cx"> class MediaSourcePrivateClient;
</span><span class="cx"> #endif
</span><span class="lines">@@ -476,6 +477,8 @@
</span><span class="cx"> 
</span><span class="cx">     void currentPlaybackTargetIsWirelessChanged();
</span><span class="cx">     void playbackTargetAvailabilityChanged();
</span><ins>+
+    void setWirelessPlaybackTarget(const MediaPlaybackTarget&amp;);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     double minFastReverseRate() const;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsMediaPlayerPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/graphics/MediaPlayerPrivate.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> 
</span><span class="cx"> class IntRect;
</span><span class="cx"> class IntSize;
</span><ins>+class MediaPlaybackTarget;
</ins><span class="cx"> class PlatformTextTrack;
</span><span class="cx"> 
</span><span class="cx"> class MediaPlayerPrivateInterface {
</span><span class="lines">@@ -166,6 +167,8 @@
</span><span class="cx"> 
</span><span class="cx">     virtual bool wirelessVideoPlaybackDisabled() const { return false; }
</span><span class="cx">     virtual void setWirelessVideoPlaybackDisabled(bool) { }
</span><ins>+
+    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&amp;) { }
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if USE(NATIVE_FULLSCREEN_VIDEO)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationMediaPlaybackTargetMacmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlaybackTargetMac.mm (0 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlaybackTargetMac.mm                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaPlaybackTargetMac.mm        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+/*
+ * 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. ``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
+ * 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. 
+ */
+
+#import &quot;config.h&quot;
+#import &quot;MediaPlaybackTarget.h&quot;
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
+
+#import &lt;AVFoundation/AVOutputDevicePickerContext.h&gt;
+#import &lt;WebCore/MediaPlaybackTarget.h&gt;
+#import &lt;WebCore/SoftLinking.h&gt;
+#import &lt;objc/runtime.h&gt;
+
+typedef AVOutputDevicePickerContext AVOutputDevicePickerContextType;
+
+SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
+SOFT_LINK_CLASS(AVFoundation, AVOutputDevicePickerContext)
+
+namespace WebCore {
+
+static NSString * const deviceContextKey = @&quot;deviceContext&quot;;
+
+void MediaPlaybackTarget::encode(NSKeyedArchiver *archiver) const
+{
+    if ([getAVOutputDevicePickerContextClass() conformsToProtocol:@protocol(NSSecureCoding)])
+        [archiver encodeObject:m_devicePickerContext.get() forKey:deviceContextKey];
+}
+
+bool MediaPlaybackTarget::decode(NSKeyedUnarchiver *unarchiver, MediaPlaybackTarget&amp; playbackTarget)
+{
+    if (![getAVOutputDevicePickerContextClass() conformsToProtocol:@protocol(NSSecureCoding)])
+        return false;
+
+    AVOutputDevicePickerContext *context = nil;
+
+    @try {
+        context = [unarchiver decodeObjectOfClass:getAVOutputDevicePickerContextClass() forKey:deviceContextKey];
+    } @catch (NSException *exception) {
+        LOG_ERROR(&quot;The target picker being decoded is not a AVOutputDevicePickerContext.&quot;);
+    }
+
+    playbackTarget.m_devicePickerContext = context;
+
+    return context;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateAVFoundationObjCh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> OBJC_CLASS AVAssetImageGenerator;
</span><span class="cx"> OBJC_CLASS AVAssetResourceLoadingRequest;
</span><span class="cx"> OBJC_CLASS AVMediaSelectionGroup;
</span><ins>+OBJC_CLASS AVOutputDevicePickerContext;
</ins><span class="cx"> OBJC_CLASS AVPlayer;
</span><span class="cx"> OBJC_CLASS AVPlayerItem;
</span><span class="cx"> OBJC_CLASS AVPlayerItemLegibleOutput;
</span><span class="lines">@@ -59,13 +60,14 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-class WebCoreAVFResourceLoader;
</del><ins>+class AudioSourceProviderAVFObjC;
+class AudioTrackPrivateAVFObjC;
</ins><span class="cx"> class InbandMetadataTextTrackPrivateAVF;
</span><span class="cx"> class InbandTextTrackPrivateAVFObjC;
</span><del>-class AudioSourceProviderAVFObjC;
-class AudioTrackPrivateAVFObjC;
</del><ins>+class MediaPlaybackTarget;
</ins><span class="cx"> class MediaSelectionGroupAVFObjC;
</span><span class="cx"> class VideoTrackPrivateAVFObjC;
</span><ins>+class WebCoreAVFResourceLoader;
</ins><span class="cx"> 
</span><span class="cx"> class MediaPlayerPrivateAVFoundationObjC : public MediaPlayerPrivateAVFoundation {
</span><span class="cx"> public:
</span><span class="lines">@@ -274,6 +276,9 @@
</span><span class="cx">     virtual String wirelessPlaybackTargetName() const override;
</span><span class="cx">     virtual MediaPlayer::WirelessPlaybackTargetType wirelessPlaybackTargetType() const override;
</span><span class="cx">     virtual bool wirelessVideoPlaybackDisabled() const override;
</span><ins>+#if !PLATFORM(IOS)
+    virtual void setWirelessPlaybackTarget(const MediaPlaybackTarget&amp;) override;
+#endif
</ins><span class="cx">     virtual void setWirelessVideoPlaybackDisabled(bool) override;
</span><span class="cx">     void updateDisableExternalPlayback();
</span><span class="cx"> #endif
</span><span class="lines">@@ -345,6 +350,10 @@
</span><span class="cx">     RefPtr&lt;InbandMetadataTextTrackPrivateAVF&gt; m_metadataTrack;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC) &amp;&amp; ENABLE(WIRELESS_PLAYBACK_TARGET)
+    RetainPtr&lt;AVOutputDevicePickerContext&gt; m_outputDevicePickerContext;
+#endif
+
</ins><span class="cx">     mutable RetainPtr&lt;NSArray&gt; m_cachedSeekableRanges;
</span><span class="cx">     mutable RetainPtr&lt;NSArray&gt; m_cachedLoadedRanges;
</span><span class="cx">     RetainPtr&lt;NSArray&gt; m_cachedTracks;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateAVFoundationObjCmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> #import &quot;OutOfBandTextTrackPrivateAVF.h&quot;
</span><span class="cx"> #import &quot;URL.h&quot;
</span><span class="cx"> #import &quot;Logging.h&quot;
</span><ins>+#import &quot;MediaPlaybackTarget.h&quot;
</ins><span class="cx"> #import &quot;MediaSelectionGroupAVFObjC.h&quot;
</span><span class="cx"> #import &quot;MediaTimeAVFoundation.h&quot;
</span><span class="cx"> #import &quot;PlatformTimeRanges.h&quot;
</span><span class="lines">@@ -135,6 +136,14 @@
</span><span class="cx"> @property (nonatomic, readonly) NSURL *resolvedURL;
</span><span class="cx"> @end
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC) &amp;&amp; ENABLE(WIRELESS_PLAYBACK_TARGET)
+typedef AVOutputDevicePickerContext AVOutputDevicePickerContextType;
+
+@interface AVPlayer (WebKitExtensions)
+@property (nonatomic) AVOutputDevicePickerContext *outputDevicePickerContext;
+@end
+#endif
+
</ins><span class="cx"> typedef AVPlayer AVPlayerType;
</span><span class="cx"> typedef AVPlayerItem AVPlayerItemType;
</span><span class="cx"> typedef AVPlayerItemLegibleOutput AVPlayerItemLegibleOutputType;
</span><span class="lines">@@ -546,6 +555,7 @@
</span><span class="cx">         [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:@&quot;rate&quot;];
</span><span class="cx"> #if ENABLE(WIRELESS_PLAYBACK_TARGET)
</span><span class="cx">         [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:@&quot;externalPlaybackActive&quot;];
</span><ins>+        [m_avPlayer.get() removeObserver:m_objcObserver.get() forKeyPath:@&quot;outputDevicePickerContext&quot;];
</ins><span class="cx"> #endif
</span><span class="cx">         m_avPlayer = nil;
</span><span class="cx">     }
</span><span class="lines">@@ -927,6 +937,10 @@
</span><span class="cx">     [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:@&quot;rate&quot; options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
</span><span class="cx"> #if ENABLE(WIRELESS_PLAYBACK_TARGET)
</span><span class="cx">     [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:@&quot;externalPlaybackActive&quot; options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
</span><ins>+    [m_avPlayer.get() addObserver:m_objcObserver.get() forKeyPath:@&quot;outputDevicePickerContext&quot; options:NSKeyValueObservingOptionNew context:(void *)MediaPlayerAVFoundationObservationContextPlayer];
+#endif
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
</ins><span class="cx">     updateDisableExternalPlayback();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -938,6 +952,11 @@
</span><span class="cx">     [m_avPlayer.get() setAllowsExternalPlayback:m_allowsWirelessVideoPlayback];
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
+    if (m_outputDevicePickerContext)
+        m_avPlayer.get().outputDevicePickerContext = m_outputDevicePickerContext.get();
+#endif
+
</ins><span class="cx">     if (player()-&gt;client().mediaPlayerIsVideo())
</span><span class="cx">         createAVPlayerLayer();
</span><span class="cx"> 
</span><span class="lines">@@ -1134,9 +1153,8 @@
</span><span class="cx">         syncTextTrackBounds();
</span><span class="cx">         [m_videoFullscreenLayer addSublayer:m_textTrackRepresentationLayer.get()];
</span><span class="cx">     }
</span><del>-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
</del><ins>+
</ins><span class="cx">     updateDisableExternalPlayback();
</span><del>-#endif
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaPlayerPrivateAVFoundationObjC::setVideoFullscreenFrame(FloatRect frame)
</span><span class="lines">@@ -2687,8 +2705,9 @@
</span><span class="cx">     if (!m_avPlayer)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    bool wirelessTarget = [m_avPlayer.get() isExternalPlaybackActive];
</del><ins>+    bool wirelessTarget = m_avPlayer.get().externalPlaybackActive;
</ins><span class="cx">     LOG(Media, &quot;MediaPlayerPrivateAVFoundationObjC::isCurrentPlaybackTargetWireless(%p) - returning %s&quot;, this, boolString(wirelessTarget));
</span><ins>+
</ins><span class="cx">     return wirelessTarget;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2697,6 +2716,7 @@
</span><span class="cx">     if (!m_avPlayer)
</span><span class="cx">         return MediaPlayer::TargetTypeNone;
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
</ins><span class="cx">     switch (wkExernalDeviceTypeForPlayer(m_avPlayer.get())) {
</span><span class="cx">     case wkExternalPlaybackTypeNone:
</span><span class="cx">         return MediaPlayer::TargetTypeNone;
</span><span class="lines">@@ -2708,6 +2728,10 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx">     return MediaPlayer::TargetTypeNone;
</span><ins>+
+#else
+    return MediaPlayer::TargetTypeAirPlay;
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String MediaPlayerPrivateAVFoundationObjC::wirelessPlaybackTargetName() const
</span><span class="lines">@@ -2725,7 +2749,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (!m_avPlayer)
</span><span class="cx">         return !m_allowsWirelessVideoPlayback;
</span><del>-    
</del><ins>+
</ins><span class="cx">     m_allowsWirelessVideoPlayback = [m_avPlayer.get() allowsExternalPlayback];
</span><span class="cx">     LOG(Media, &quot;MediaPlayerPrivateAVFoundationObjC::wirelessVideoPlaybackDisabled(%p) - returning %s&quot;, this, boolString(!m_allowsWirelessVideoPlayback));
</span><span class="cx"> 
</span><span class="lines">@@ -2738,16 +2762,32 @@
</span><span class="cx">     m_allowsWirelessVideoPlayback = !disabled;
</span><span class="cx">     if (!m_avPlayer)
</span><span class="cx">         return;
</span><del>-    
</del><ins>+
</ins><span class="cx">     [m_avPlayer.get() setAllowsExternalPlayback:!disabled];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if !PLATFORM(IOS)
+void MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(const MediaPlaybackTarget&amp; target)
+{
+    m_outputDevicePickerContext = target.devicePickerContext();
+
+    LOG(Media, &quot;MediaPlayerPrivateAVFoundationObjC::setWirelessPlaybackTarget(%p) - target = %p&quot;, this, m_outputDevicePickerContext.get());
+
+    if (!m_avPlayer)
+        return;
+
+    m_avPlayer.get().outputDevicePickerContext = m_outputDevicePickerContext.get();
+}
+#endif
+
</ins><span class="cx"> void MediaPlayerPrivateAVFoundationObjC::updateDisableExternalPlayback()
</span><span class="cx"> {
</span><span class="cx">     if (!m_avPlayer)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
</ins><span class="cx">     [m_avPlayer setUsesExternalPlaybackWhileExternalScreenIsActive:m_videoFullscreenLayer != nil];
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -3169,6 +3209,8 @@
</span><span class="cx"> #if ENABLE(WIRELESS_PLAYBACK_TARGET)
</span><span class="cx">         else if ([keyPath isEqualToString:@&quot;externalPlaybackActive&quot;])
</span><span class="cx">             function = WTF::bind(&amp;MediaPlayerPrivateAVFoundationObjC::playbackTargetIsWirelessDidChange, m_callback);
</span><ins>+        else if ([keyPath isEqualToString:@&quot;outputDevicePickerContext&quot;])
+            function = WTF::bind(&amp;MediaPlayerPrivateAVFoundationObjC::playbackTargetIsWirelessDidChange, m_callback);
</ins><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalSettingscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/InternalSettings.cpp (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/InternalSettings.cpp        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/testing/InternalSettings.cpp        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -97,6 +97,9 @@
</span><span class="cx"> #if ENABLE(TOUCH_EVENTS)
</span><span class="cx">     , m_touchEventEmulationEnabled(settings.isTouchEventEmulationEnabled())
</span><span class="cx"> #endif
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    , m_mediaPlaybackAllowsAirPlay(settings.mediaPlaybackAllowsAirPlay())
+#endif
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -201,6 +204,9 @@
</span><span class="cx">     , m_page(page)
</span><span class="cx">     , m_backup(page-&gt;settings())
</span><span class="cx"> {
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+    page-&gt;settings().setMediaPlaybackAllowsAirPlay(false);
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InternalSettings::resetToConsistentState()
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalSettingsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/InternalSettings.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/InternalSettings.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebCore/testing/InternalSettings.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -95,6 +95,9 @@
</span><span class="cx"> #if ENABLE(TOUCH_EVENTS)
</span><span class="cx">         bool m_touchEventEmulationEnabled;
</span><span class="cx"> #endif
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+        bool m_mediaPlaybackAllowsAirPlay;
+#endif
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     static PassRefPtr&lt;InternalSettings&gt; create(Page* page)
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebKit2/ChangeLog        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -1,3 +1,71 @@
</span><ins>+2015-03-11  Eric Carlson  &lt;eric.carlson@apple.com&gt;
+
+        [Mac] Update AirPlay handling
+        https://bugs.webkit.org/show_bug.cgi?id=142541
+
+        Reviewed by Sam Weinig.
+
+        * Shared/WebCoreArgumentCoders.h:
+        * Shared/mac/WebCoreArgumentCodersMac.mm:
+        (IPC::ArgumentCoder&lt;AVPlaybackTarget&gt;::encode):
+        (IPC::ArgumentCoder&lt;AVPlaybackTarget&gt;::decode):
+        * UIProcess/PageClient.h:
+        * UIProcess/WebAVPlaybackTargetPickerProxy.cpp: Added.
+        (WebKit::WebAVPlaybackTargetPickerProxy::WebAVPlaybackTargetPickerProxy):
+        (WebKit::WebAVPlaybackTargetPickerProxy::~WebAVPlaybackTargetPickerProxy):
+        (WebKit::WebAVPlaybackTargetPickerProxy::showPlaybackTargetPicker):
+        (WebKit::WebAVPlaybackTargetPickerProxy::startingMonitoringPlaybackTargets):
+        (WebKit::WebAVPlaybackTargetPickerProxy::stopMonitoringPlaybackTargets):
+        * UIProcess/WebAVPlaybackTargetPickerProxy.h: Added.
+        (WebKit::WebAVPlaybackTargetPickerProxy::Client::~Client):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::devicePickerProxy):
+        (WebKit::WebPageProxy::showPlaybackTargetPicker):
+        (WebKit::WebPageProxy::startingMonitoringPlaybackTargets):
+        (WebKit::WebPageProxy::stopMonitoringPlaybackTargets):
+        (WebKit::WebPageProxy::didChoosePlaybackTarget):
+        (WebKit::WebPageProxy::externalOutputDeviceAvailableDidChange):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/mac/PageClientImpl.h:
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::createPlaybackTargetPicker):
+        * UIProcess/mac/WebAVPlaybackTargetPickerProxyMac.h: Added.
+        * UIProcess/mac/WebAVPlaybackTargetPickerProxyMac.mm: Added.
+        (WebKit::WebAVPlaybackTargetPickerProxyMac::create):
+        (WebKit::WebAVPlaybackTargetPickerProxyMac::WebAVPlaybackTargetPickerProxyMac):
+        (WebKit::WebAVPlaybackTargetPickerProxyMac::~WebAVPlaybackTargetPickerProxyMac):
+        (WebKit::WebAVPlaybackTargetPickerProxyMac::outputeDeviceAvailabilityChangedTimerFired):
+        (WebKit::WebAVPlaybackTargetPickerProxyMac::availableDevicesDidChange):
+        (WebKit::WebAVPlaybackTargetPickerProxyMac::devicePicker):
+        (WebKit::WebAVPlaybackTargetPickerProxyMac::showPlaybackTargetPicker):
+        (WebKit::WebAVPlaybackTargetPickerProxyMac::currentDeviceDidChange):
+        (WebKit::WebAVPlaybackTargetPickerProxyMac::startingMonitoringPlaybackTargets):
+        (WebKit::WebAVPlaybackTargetPickerProxyMac::stopMonitoringPlaybackTargets):
+        (-[WebAVOutputDevicePickerMenuControllerHelper initWithCallback:]):
+        (-[WebAVOutputDevicePickerMenuControllerHelper clearCallback]):
+        (-[WebAVOutputDevicePickerMenuControllerHelper observeValueForKeyPath:ofObject:change:context:]):
+        * WebKit2.xcodeproj/project.pbxproj:
+        * WebProcess/WebCoreSupport/WebAVPlaybackTargetPicker.cpp: Added.
+        (WebKit::WebAVPlaybackTargetPicker::WebAVPlaybackTargetPicker):
+        (WebKit::WebAVPlaybackTargetPicker::showPlaybackDevicePicker):
+        (WebKit::WebAVPlaybackTargetPicker::configureWireLessTargetMonitoring):
+        (WebKit::WebAVPlaybackTargetPicker::addClient):
+        (WebKit::WebAVPlaybackTargetPicker::removeClient):
+        (WebKit::WebAVPlaybackTargetPicker::didChoosePlaybackTarget):
+        (WebKit::WebAVPlaybackTargetPicker::playbackTargetAvailabilityDidChange):
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::showPlaybackTargetPicker):
+        (WebKit::WebChromeClient::startingMonitoringPlaybackTargets):
+        (WebKit::WebChromeClient::stopMonitoringPlaybackTargets):
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::playbackTargetSelected):
+        (WebKit::WebPage::playbackTargetAvailabilityDidChange):
+        * WebProcess/com.apple.WebProcess.sb.in:
+
</ins><span class="cx"> 2015-03-11  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix the build
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebCoreArgumentCodersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -115,6 +115,12 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+namespace WebCore {
+class MediaPlaybackTarget;
+}
+#endif
+
</ins><span class="cx"> namespace IPC {
</span><span class="cx"> 
</span><span class="cx"> template&lt;&gt; struct ArgumentCoder&lt;WebCore::AffineTransform&gt; {
</span><span class="lines">@@ -454,6 +460,13 @@
</span><span class="cx">     static bool decode(ArgumentDecoder&amp;, WebCore::TextIndicatorData&amp;);
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+template&lt;&gt; struct ArgumentCoder&lt;WebCore::MediaPlaybackTarget&gt; {
+    static void encode(ArgumentEncoder&amp;, const WebCore::MediaPlaybackTarget&amp;);
+    static bool decode(ArgumentDecoder&amp;, WebCore::MediaPlaybackTarget&amp;);
+};
+#endif
+
</ins><span class="cx"> } // namespace IPC
</span><span class="cx"> 
</span><span class="cx"> #endif // WebCoreArgumentCoders_h
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedmacWebCoreArgumentCodersMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/mac/WebCoreArgumentCodersMac.mm (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/mac/WebCoreArgumentCodersMac.mm        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebKit2/Shared/mac/WebCoreArgumentCodersMac.mm        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -38,11 +38,17 @@
</span><span class="cx"> #import &lt;WebCore/ProtectionSpace.h&gt;
</span><span class="cx"> #import &lt;WebCore/ResourceError.h&gt;
</span><span class="cx"> #import &lt;WebCore/ResourceRequest.h&gt;
</span><ins>+#import &lt;WebCore/SoftLinking.h&gt;
+#import &lt;objc/runtime.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #if USE(CFNETWORK)
</span><span class="cx"> #import &lt;CFNetwork/CFURLRequest.h&gt;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#import &lt;WebCore/MediaPlaybackTarget.h&gt;
+#endif
+
</ins><span class="cx"> using namespace WebCore;
</span><span class="cx"> 
</span><span class="cx"> namespace IPC {
</span><span class="lines">@@ -432,4 +438,31 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+void ArgumentCoder&lt;MediaPlaybackTarget&gt;::encode(ArgumentEncoder&amp; encoder, const MediaPlaybackTarget&amp; target)
+{
+    RetainPtr&lt;NSMutableData&gt; data = adoptNS([[NSMutableData alloc] init]);
+    RetainPtr&lt;NSKeyedArchiver&gt; archiver = adoptNS([[NSKeyedArchiver alloc] initForWritingWithMutableData:data.get()]);
+    [archiver setRequiresSecureCoding:YES];
+    target.encode(archiver.get());
+    [archiver finishEncoding];
+    IPC::encode(encoder, reinterpret_cast&lt;CFDataRef&gt;(data.get()));
+}
+
+bool ArgumentCoder&lt;MediaPlaybackTarget&gt;::decode(ArgumentDecoder&amp; decoder, MediaPlaybackTarget&amp; target)
+{
+    RetainPtr&lt;CFDataRef&gt; data;
+    if (!IPC::decode(decoder, data))
+        return false;
+
+    RetainPtr&lt;NSKeyedUnarchiver&gt; unarchiver = adoptNS([[NSKeyedUnarchiver alloc] initForReadingWithData:(NSData *)data.get()]);
+    [unarchiver setRequiresSecureCoding:YES];
+    if (!MediaPlaybackTarget::decode(unarchiver.get(), target))
+        return false;
+    
+    [unarchiver finishDecoding];
+    return true;
+}
+#endif
+
</ins><span class="cx"> } // namespace IPC
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPageClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/PageClient.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -34,6 +34,10 @@
</span><span class="cx"> #include &lt;WebCore/EditorClient.h&gt;
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+#include &quot;WebMediaPlaybackTargetPickerProxy.h&quot;
+#endif
+
</ins><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx"> #include &quot;PluginComplexTextInputState.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -313,6 +317,11 @@
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     virtual void didPerformActionMenuHitTest(const ActionMenuHitTestResult&amp;, bool forImmediateAction, API::Object*) = 0;
</span><span class="cx"> #endif
</span><ins>+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
+    virtual std::unique_ptr&lt;WebMediaPlaybackTargetPickerProxy&gt; createPlaybackTargetPicker(WebPageProxy*) = 0;
+#endif
+
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebMediaPlaybackTargetPickerProxycpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/WebMediaPlaybackTargetPickerProxy.cpp (0 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebMediaPlaybackTargetPickerProxy.cpp                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/WebMediaPlaybackTargetPickerProxy.cpp        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+/*
+ * 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 &quot;config.h&quot;
+#include &quot;WebMediaPlaybackTargetPickerProxy.h&quot;
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+namespace WebKit {
+
+WebMediaPlaybackTargetPickerProxy::WebMediaPlaybackTargetPickerProxy(Client&amp; client)
+    : m_client(&amp;client)
+{
+}
+
+WebMediaPlaybackTargetPickerProxy::~WebMediaPlaybackTargetPickerProxy()
+{
+    m_client = 0;
+}
+
+void WebMediaPlaybackTargetPickerProxy::showPlaybackTargetPicker(const WebCore::FloatRect&amp;, bool)
+{
+    ASSERT_NOT_REACHED();
+    return;
+}
+
+void WebMediaPlaybackTargetPickerProxy::startingMonitoringPlaybackTargets()
+{
+    ASSERT_NOT_REACHED();
+    return;
+}
+
+void WebMediaPlaybackTargetPickerProxy::stopMonitoringPlaybackTargets()
+{
+    ASSERT_NOT_REACHED();
+    return;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebMediaPlaybackTargetPickerProxyh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/WebMediaPlaybackTargetPickerProxy.h (0 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebMediaPlaybackTargetPickerProxy.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/WebMediaPlaybackTargetPickerProxy.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+/*
+ * 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 WebMediaPlaybackTargetPickerProxy_h
+#define WebMediaPlaybackTargetPickerProxy_h
+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+#include &lt;wtf/RefCounted.h&gt;
+#include &lt;wtf/RefPtr.h&gt;
+
+namespace WebCore {
+class FloatRect;
+class MediaPlaybackTarget;
+}
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class WebMediaPlaybackTargetPickerProxy {
+public:
+    class Client {
+    protected:
+        virtual ~Client() { }
+
+    public:
+        virtual void didChoosePlaybackTarget(const WebCore::MediaPlaybackTarget&amp;) = 0;
+        virtual void externalOutputDeviceAvailableDidChange(bool) = 0;
+
+        void invalidate();
+    };
+
+    virtual ~WebMediaPlaybackTargetPickerProxy();
+
+    virtual void showPlaybackTargetPicker(const WebCore::FloatRect&amp;, bool);
+    virtual void startingMonitoringPlaybackTargets();
+    virtual void stopMonitoringPlaybackTargets();
+
+protected:
+    explicit WebMediaPlaybackTargetPickerProxy(Client&amp;);
+
+    Client* m_client;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
+
+#endif // WebMediaPlaybackTargetPickerProxy_h
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -5597,4 +5597,47 @@
</span><span class="cx">     m_uiClient-&gt;didClickAutoFillButton(*this, m_process-&gt;transformHandlesToObjects(userData.object()).get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
+
+WebMediaPlaybackTargetPickerProxy&amp; WebPageProxy::devicePickerProxy()
+{
+    if (!m_playbackTargetPicker)
+        m_playbackTargetPicker = m_pageClient.createPlaybackTargetPicker(this);
+
+    return *m_playbackTargetPicker.get();
+}
+
+void WebPageProxy::showPlaybackTargetPicker(const WebCore::FloatRect&amp; rect, bool hasVideo)
+{
+    devicePickerProxy().showPlaybackTargetPicker(m_pageClient.rootViewToScreen(IntRect(rect)), hasVideo);
+}
+
+void WebPageProxy::startingMonitoringPlaybackTargets()
+{
+    devicePickerProxy().startingMonitoringPlaybackTargets();
+}
+
+void WebPageProxy::stopMonitoringPlaybackTargets()
+{
+    devicePickerProxy().stopMonitoringPlaybackTargets();
+}
+
+void WebPageProxy::didChoosePlaybackTarget(const WebCore::MediaPlaybackTarget&amp; target)
+{
+    if (!isValid())
+        return;
+
+    m_process-&gt;send(Messages::WebPage::PlaybackTargetSelected(target), m_pageID);
+}
+
+void WebPageProxy::externalOutputDeviceAvailableDidChange(bool available)
+{
+    if (!isValid())
+        return;
+
+    m_process-&gt;send(Messages::WebPage::PlaybackTargetAvailabilityDidChange(available), m_pageID);
+}
+
+#endif
+
</ins><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -111,6 +111,10 @@
</span><span class="cx"> #include &quot;ArgumentCodersGtk.h&quot;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
+#include &quot;WebMediaPlaybackTargetPickerProxy.h&quot;
+#endif
+
</ins><span class="cx"> namespace API {
</span><span class="cx"> class ContextMenuClient;
</span><span class="cx"> class FindClient;
</span><span class="lines">@@ -258,6 +262,9 @@
</span><span class="cx"> #if ENABLE(INPUT_TYPE_COLOR)
</span><span class="cx">     , public WebColorPicker::Client
</span><span class="cx"> #endif
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
+    , public WebMediaPlaybackTargetPickerProxy::Client
+#endif
</ins><span class="cx">     , public WebPopupMenuProxy::Client
</span><span class="cx">     , public IPC::MessageReceiver
</span><span class="cx">     , public IPC::MessageSender {
</span><span class="lines">@@ -999,6 +1006,17 @@
</span><span class="cx">     void logDiagnosticMessageWithResult(const String&amp; message, const String&amp; description, uint32_t result, bool shouldSample);
</span><span class="cx">     void logDiagnosticMessageWithValue(const String&amp; message, const String&amp; description, const String&amp; value, bool shouldSample);
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
+    WebMediaPlaybackTargetPickerProxy&amp; devicePickerProxy();
+    void showPlaybackTargetPicker(const WebCore::FloatRect&amp;, bool hasVideo);
+    void startingMonitoringPlaybackTargets();
+    void stopMonitoringPlaybackTargets();
+
+    // WebMediaPlaybackTargetPickerProxy::Client
+    virtual void didChoosePlaybackTarget(const WebCore::MediaPlaybackTarget&amp;) override;
+    virtual void externalOutputDeviceAvailableDidChange(bool) override;
+#endif
+
</ins><span class="cx"> private:
</span><span class="cx">     WebPageProxy(PageClient&amp;, WebProcessProxy&amp;, uint64_t pageID, const WebPageConfiguration&amp;);
</span><span class="cx">     void platformInitialize();
</span><span class="lines">@@ -1664,6 +1682,10 @@
</span><span class="cx">     bool m_viewStateChangeWantsSynchronousReply;
</span><span class="cx">     Vector&lt;uint64_t&gt; m_nextViewStateChangeCallbacks;
</span><span class="cx"> 
</span><ins>+#if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
+    std::unique_ptr&lt;WebMediaPlaybackTargetPickerProxy&gt; m_playbackTargetPicker;
+#endif
+
</ins><span class="cx">     bool m_isPlayingAudio;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (181422 => 181423)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2015-03-12 01:10:40 UTC (rev 181422)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2015-03-12 01:54:06 UTC (rev 181423)
</span><span class="lines">@@ -425,4 +425,11 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     HandleAutoFillButtonClick(WebKit::UserData userData);
</span><ins>+
+#if ENABLE(WIRELESS_PLAYBACK_TARGET) &amp;&amp; !PLATFORM(IOS)
+    ShowPlaybackTargetPicker(WebCore::FloatRect pickerLocation, bool hasVideo)
+    StartingMonitoringPlaybackTargets()
+    StopMonitoringPlaybackTargets()
+#endif
+
</ins><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>