[iOS] When simultaneously exiting-and-entering fullscreen, WebVideoFullscreenManager...
[WebKit-https.git] / Source / WebKit2 / WebProcess / ios / WebVideoFullscreenManager.mm
index 45a3e29..9aaefc8 100644 (file)
@@ -60,6 +60,97 @@ static IntRect clientRectForElement(HTMLElement* element)
     return element->clientRect();
 }
 
+static uint64_t nextContextId()
+{
+    static uint64_t contextId = 0;
+    return ++contextId;
+}
+
+#pragma mark - WebVideoFullscreenInterfaceContext
+
+WebVideoFullscreenInterfaceContext::WebVideoFullscreenInterfaceContext(WebVideoFullscreenManager& manager, uint64_t contextId)
+    : m_manager(&manager)
+    , m_contextId(contextId)
+{
+}
+
+WebVideoFullscreenInterfaceContext::~WebVideoFullscreenInterfaceContext()
+{
+}
+
+void WebVideoFullscreenInterfaceContext::setLayerHostingContext(std::unique_ptr<LayerHostingContext>&& context)
+{
+    m_layerHostingContext = WTF::move(context);
+}
+
+void WebVideoFullscreenInterfaceContext::resetMediaState()
+{
+    if (m_manager)
+        m_manager->resetMediaState(m_contextId);
+}
+
+void WebVideoFullscreenInterfaceContext::setDuration(double duration)
+{
+    if (m_manager)
+        m_manager->setDuration(m_contextId, duration);
+}
+
+void WebVideoFullscreenInterfaceContext::setCurrentTime(double currentTime, double anchorTime)
+{
+    if (m_manager)
+        m_manager->setCurrentTime(m_contextId, currentTime, anchorTime);
+}
+
+void WebVideoFullscreenInterfaceContext::setBufferedTime(double bufferedTime)
+{
+    if (m_manager)
+        m_manager->setBufferedTime(m_contextId, bufferedTime);
+}
+
+void WebVideoFullscreenInterfaceContext::setRate(bool isPlaying, float playbackRate)
+{
+    if (m_manager)
+        m_manager->setRate(m_contextId, isPlaying, playbackRate);
+}
+
+void WebVideoFullscreenInterfaceContext::setVideoDimensions(bool hasVideo, float width, float height)
+{
+    if (m_manager)
+        m_manager->setVideoDimensions(m_contextId, hasVideo, width, height);
+}
+
+void WebVideoFullscreenInterfaceContext::setSeekableRanges(const WebCore::TimeRanges& ranges)
+{
+    if (m_manager)
+        m_manager->setSeekableRanges(m_contextId, ranges);
+}
+
+void WebVideoFullscreenInterfaceContext::setCanPlayFastReverse(bool value)
+{
+    if (m_manager)
+        m_manager->setCanPlayFastReverse(m_contextId, value);
+}
+
+void WebVideoFullscreenInterfaceContext::setAudioMediaSelectionOptions(const Vector<WTF::String>& options, uint64_t selectedIndex)
+{
+    if (m_manager)
+        m_manager->setAudioMediaSelectionOptions(m_contextId, options, selectedIndex);
+}
+
+void WebVideoFullscreenInterfaceContext::setLegibleMediaSelectionOptions(const Vector<WTF::String>& options, uint64_t selectedIndex)
+{
+    if (m_manager)
+        m_manager->setLegibleMediaSelectionOptions(m_contextId, options, selectedIndex);
+}
+
+void WebVideoFullscreenInterfaceContext::setExternalPlayback(bool enabled, ExternalPlaybackTargetType type, WTF::String localizedDeviceName)
+{
+    if (m_manager)
+        m_manager->setExternalPlayback(m_contextId, enabled, type, localizedDeviceName);
+}
+
+#pragma mark - WebVideoFullscreenManager
+
 PassRefPtr<WebVideoFullscreenManager> WebVideoFullscreenManager::create(PassRefPtr<WebPage> page)
 {
     return adoptRef(new WebVideoFullscreenManager(page));
@@ -67,20 +158,60 @@ PassRefPtr<WebVideoFullscreenManager> WebVideoFullscreenManager::create(PassRefP
 
 WebVideoFullscreenManager::WebVideoFullscreenManager(PassRefPtr<WebPage> page)
     : m_page(page.get())
-    , m_isAnimating(false)
-    , m_targetIsFullscreen(false)
-    , m_fullscreenMode(HTMLMediaElement::VideoFullscreenModeNone)
-    , m_isFullscreen(false)
 {
-    setWebVideoFullscreenInterface(this);
     WebProcess::singleton().addMessageReceiver(Messages::WebVideoFullscreenManager::messageReceiverName(), page->pageID(), *this);
 }
 
 WebVideoFullscreenManager::~WebVideoFullscreenManager()
 {
+    for (auto& tuple : m_contextMap.values()) {
+        RefPtr<WebVideoFullscreenModelVideoElement> model;
+        RefPtr<WebVideoFullscreenInterfaceContext> interface;
+        std::tie(model, interface) = tuple;
+
+        model->setWebVideoFullscreenInterface(nullptr);
+        model->setVideoElement(nullptr);
+
+        interface->invalidate();
+    }
+
+    m_contextMap.clear();
+    m_videoElements.clear();
+
     WebProcess::singleton().removeMessageReceiver(Messages::WebVideoFullscreenManager::messageReceiverName(), m_page->pageID());
 }
 
+WebVideoFullscreenManager::ModelInterfaceTuple WebVideoFullscreenManager::createModelAndInterface(uint64_t contextId)
+{
+    RefPtr<WebVideoFullscreenModelVideoElement> model = WebVideoFullscreenModelVideoElement::create();
+    RefPtr<WebVideoFullscreenInterfaceContext> interface = WebVideoFullscreenInterfaceContext::create(*this, contextId);
+
+    interface->setLayerHostingContext(LayerHostingContext::createForExternalHostingProcess());
+    model->setWebVideoFullscreenInterface(interface.get());
+
+    return std::make_tuple(WTF::move(model), WTF::move(interface));
+}
+
+WebVideoFullscreenManager::ModelInterfaceTuple& WebVideoFullscreenManager::ensureModelAndInterface(uint64_t contextId)
+{
+    auto addResult = m_contextMap.add(contextId, ModelInterfaceTuple());
+    if (addResult.isNewEntry)
+        addResult.iterator->value = createModelAndInterface(contextId);
+    return addResult.iterator->value;
+}
+
+WebCore::WebVideoFullscreenModelVideoElement& WebVideoFullscreenManager::ensureModel(uint64_t contextId)
+{
+    return *std::get<0>(ensureModelAndInterface(contextId));
+}
+
+WebVideoFullscreenInterfaceContext& WebVideoFullscreenManager::ensureInterface(uint64_t contextId)
+{
+    return *std::get<1>(ensureModelAndInterface(contextId));
+}
+
+#pragma mark Interface to ChromeClient:
+
 bool WebVideoFullscreenManager::supportsVideoFullscreen() const
 {
     return Settings::avKitEnabled();
@@ -90,66 +221,79 @@ void WebVideoFullscreenManager::enterVideoFullscreenForVideoElement(HTMLVideoEle
 {
     ASSERT(mode != HTMLMediaElement::VideoFullscreenModeNone);
 
-    m_videoElement = &videoElement;
+    uint64_t contextId;
 
-    m_targetIsFullscreen = true;
-    m_fullscreenMode = mode;
+    auto addResult = m_videoElements.add(&videoElement, 0);
+    if (addResult.isNewEntry)
+        addResult.iterator->value = nextContextId();
+    contextId = addResult.iterator->value;
 
-    if (m_isAnimating)
-        return;
+    RefPtr<WebVideoFullscreenModelVideoElement> model;
+    RefPtr<WebVideoFullscreenInterfaceContext> interface;
+    std::tie(model, interface) = ensureModelAndInterface(contextId);
 
-    m_isAnimating = true;
-    setVideoElement(&videoElement);
+    interface->setTargetIsFullscreen(true);
+    interface->setFullscreenMode(mode);
+    model->setVideoElement(&videoElement);
 
-    m_layerHostingContext = LayerHostingContext::createForExternalHostingProcess();
-    bool allowOptimizedFullscreen = m_videoElement->mediaSession().allowsAlternateFullscreen(*m_videoElement.get());
+    if (interface->isAnimating())
+        return;
+    interface->setIsAnimating(true);
+
+    bool allowOptimizedFullscreen = videoElement.mediaSession().allowsAlternateFullscreen(videoElement);
     
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetupFullscreenWithID(m_layerHostingContext->contextID(), clientRectForElement(&videoElement), m_page->deviceScaleFactor(), m_fullscreenMode, allowOptimizedFullscreen), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetupFullscreenWithID(contextId, interface->layerHostingContext()->contextID(), clientRectForElement(&videoElement), m_page->deviceScaleFactor(), interface->fullscreenMode(), allowOptimizedFullscreen), m_page->pageID());
 }
 
-void WebVideoFullscreenManager::exitVideoFullscreenForVideoElement(WebCore::HTMLVideoElement&)
+void WebVideoFullscreenManager::exitVideoFullscreenForVideoElement(WebCore::HTMLVideoElement& videoElement)
 {
-    RefPtr<HTMLVideoElement> videoElement = m_videoElement.release();
-    m_targetIsFullscreen = false;
+    ASSERT(m_videoElements.contains(&videoElement));
+
+    uint64_t contextId = m_videoElements.get(&videoElement);
+    auto& interface = ensureInterface(contextId);
 
-    if (m_isAnimating)
+    interface.setTargetIsFullscreen(false);
+
+    if (interface.isAnimating())
         return;
 
-    m_isAnimating = true;
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::ExitFullscreen(clientRectForElement(videoElement.get())), m_page->pageID());
+    interface.setIsAnimating(true);
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::ExitFullscreen(contextId, clientRectForElement(&videoElement)), m_page->pageID());
 }
 
-void WebVideoFullscreenManager::resetMediaState()
+#pragma mark Interface to WebVideoFullscreenInterfaceContext:
+
+void WebVideoFullscreenManager::resetMediaState(uint64_t contextId)
 {
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::ResetMediaState(), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::ResetMediaState(contextId), m_page->pageID());
 }
     
-void WebVideoFullscreenManager::setDuration(double duration)
+void WebVideoFullscreenManager::setDuration(uint64_t contextId, double duration)
 {
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetDuration(duration), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetDuration(contextId, duration), m_page->pageID());
 }
 
-void WebVideoFullscreenManager::setCurrentTime(double currentTime, double anchorTime)
+void WebVideoFullscreenManager::setCurrentTime(uint64_t contextId, double currentTime, double anchorTime)
 {
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetCurrentTime(currentTime, anchorTime), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetCurrentTime(contextId, currentTime, anchorTime), m_page->pageID());
 }
 
-void WebVideoFullscreenManager::setBufferedTime(double bufferedTime)
+void WebVideoFullscreenManager::setBufferedTime(uint64_t contextId, double bufferedTime)
 {
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetBufferedTime(bufferedTime), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetBufferedTime(contextId, bufferedTime), m_page->pageID());
 }
 
-void WebVideoFullscreenManager::setRate(bool isPlaying, float playbackRate)
+void WebVideoFullscreenManager::setRate(uint64_t contextId, bool isPlaying, float playbackRate)
 {
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetRate(isPlaying, playbackRate), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetRate(contextId, isPlaying, playbackRate), m_page->pageID());
 }
 
-void WebVideoFullscreenManager::setVideoDimensions(bool hasVideo, float width, float height)
+void WebVideoFullscreenManager::setVideoDimensions(uint64_t contextId, bool hasVideo, float width, float height)
 {
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetVideoDimensions(hasVideo, width, height), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetVideoDimensions(contextId, hasVideo, width, height), m_page->pageID());
 }
     
-void WebVideoFullscreenManager::setSeekableRanges(const WebCore::TimeRanges& timeRanges)
+void WebVideoFullscreenManager::setSeekableRanges(uint64_t contextId, const WebCore::TimeRanges& timeRanges)
 {
     Vector<std::pair<double, double>> rangesVector;
     
@@ -160,30 +304,104 @@ void WebVideoFullscreenManager::setSeekableRanges(const WebCore::TimeRanges& tim
         rangesVector.append(std::pair<double,double>(start, end));
     }
 
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetSeekableRangesVector(WTF::move(rangesVector)), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetSeekableRangesVector(contextId, WTF::move(rangesVector)), m_page->pageID());
 }
 
-void WebVideoFullscreenManager::setCanPlayFastReverse(bool value)
+void WebVideoFullscreenManager::setCanPlayFastReverse(uint64_t contextId, bool value)
 {
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetCanPlayFastReverse(value), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetCanPlayFastReverse(contextId, value), m_page->pageID());
 }
 
-void WebVideoFullscreenManager::setAudioMediaSelectionOptions(const Vector<String>& options, uint64_t selectedIndex)
+void WebVideoFullscreenManager::setAudioMediaSelectionOptions(uint64_t contextId, const Vector<String>& options, uint64_t selectedIndex)
 {
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetAudioMediaSelectionOptions(options, selectedIndex), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetAudioMediaSelectionOptions(contextId, options, selectedIndex), m_page->pageID());
 }
 
-void WebVideoFullscreenManager::setLegibleMediaSelectionOptions(const Vector<String>& options, uint64_t selectedIndex)
+void WebVideoFullscreenManager::setLegibleMediaSelectionOptions(uint64_t contextId, const Vector<String>& options, uint64_t selectedIndex)
 {
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetLegibleMediaSelectionOptions(options, selectedIndex), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetLegibleMediaSelectionOptions(contextId, options, selectedIndex), m_page->pageID());
 }
 
-void WebVideoFullscreenManager::setExternalPlayback(bool enabled, WebVideoFullscreenInterface::ExternalPlaybackTargetType targetType, String localizedDeviceName)
+void WebVideoFullscreenManager::setExternalPlayback(uint64_t contextId, bool enabled, WebVideoFullscreenInterface::ExternalPlaybackTargetType targetType, String localizedDeviceName)
 {
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetExternalPlaybackProperties(enabled, static_cast<uint32_t>(targetType), localizedDeviceName), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::SetExternalPlaybackProperties(contextId, enabled, static_cast<uint32_t>(targetType), localizedDeviceName), m_page->pageID());
 }
-    
-void WebVideoFullscreenManager::didSetupFullscreen()
+
+#pragma mark Messages from WebVideoFullscreenManagerProxy:
+
+void WebVideoFullscreenManager::play(uint64_t contextId)
+{
+    ensureModel(contextId).play();
+}
+
+void WebVideoFullscreenManager::pause(uint64_t contextId)
+{
+    ensureModel(contextId).pause();
+}
+
+void WebVideoFullscreenManager::togglePlayState(uint64_t contextId)
+{
+    ensureModel(contextId).togglePlayState();
+}
+
+void WebVideoFullscreenManager::beginScrubbing(uint64_t contextId)
+{
+    ensureModel(contextId).beginScrubbing();
+}
+
+void WebVideoFullscreenManager::endScrubbing(uint64_t contextId)
+{
+    ensureModel(contextId).endScrubbing();
+}
+
+void WebVideoFullscreenManager::seekToTime(uint64_t contextId, double time)
+{
+    ensureModel(contextId).seekToTime(time);
+}
+
+void WebVideoFullscreenManager::fastSeek(uint64_t contextId, double time)
+{
+    ensureModel(contextId).fastSeek(time);
+}
+
+void WebVideoFullscreenManager::beginScanningForward(uint64_t contextId)
+{
+    ensureModel(contextId).beginScanningForward();
+}
+
+void WebVideoFullscreenManager::beginScanningBackward(uint64_t contextId)
+{
+    ensureModel(contextId).beginScanningBackward();
+}
+
+void WebVideoFullscreenManager::endScanning(uint64_t contextId)
+{
+    ensureModel(contextId).endScanning();
+}
+
+void WebVideoFullscreenManager::requestExitFullscreen(uint64_t contextId)
+{
+    ensureModel(contextId).requestExitFullscreen();
+}
+
+void WebVideoFullscreenManager::selectAudioMediaOption(uint64_t contextId, uint64_t index)
+{
+    ensureModel(contextId).selectAudioMediaOption(index);
+}
+
+void WebVideoFullscreenManager::selectLegibleMediaOption(uint64_t contextId, uint64_t index)
+{
+    ensureModel(contextId).selectLegibleMediaOption(index);
+}
+
+void WebVideoFullscreenManager::fullscreenModeChanged(uint64_t contextId, WebCore::HTMLMediaElement::VideoFullscreenMode videoFullscreenMode)
+{
+    ensureModel(contextId).fullscreenModeChanged(videoFullscreenMode);
+}
+
+#pragma mark Messages from WebVideoFullscreenManager:
+
+void WebVideoFullscreenManager::didSetupFullscreen(uint64_t contextId)
 {
     PlatformLayer* videoLayer = [CALayer layer];
 #ifndef NDEBUG
@@ -200,83 +418,118 @@ void WebVideoFullscreenManager::didSetupFullscreen()
     // This scale factor is inverted in the hosting process.
     float hostingScaleFactor = m_page->deviceScaleFactor();
     [videoLayer setTransform:CATransform3DMakeScale(hostingScaleFactor, hostingScaleFactor, 1)];
-    m_layerHostingContext->setRootLayer(videoLayer);
 
-    setVideoFullscreenLayer(videoLayer);
+    RefPtr<WebVideoFullscreenModelVideoElement> model;
+    RefPtr<WebVideoFullscreenInterfaceContext> interface;
+    std::tie(model, interface) = ensureModelAndInterface(contextId);
+
+    interface->layerHostingContext()->setRootLayer(videoLayer);
+    model->setVideoFullscreenLayer(videoLayer);
+
     [CATransaction commit];
 
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::EnterFullscreen(), m_page->pageID());
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::EnterFullscreen(contextId), m_page->pageID());
 }
     
-void WebVideoFullscreenManager::didEnterFullscreen()
+void WebVideoFullscreenManager::didEnterFullscreen(uint64_t contextId)
 {
-    m_isAnimating = false;
-    m_isFullscreen = false;
+    RefPtr<WebVideoFullscreenModelVideoElement> model;
+    RefPtr<WebVideoFullscreenInterfaceContext> interface;
+    std::tie(model, interface) = ensureModelAndInterface(contextId);
+
+    interface->setIsAnimating(false);
+    interface->setIsFullscreen(false);
+
+    if (interface->targetIsFullscreen())
+        return;
 
-    if (m_targetIsFullscreen)
+    RefPtr<HTMLVideoElement> videoElement = model->videoElement();
+    if (!videoElement)
         return;
 
     // exit fullscreen now if it was previously requested during an animation.
-    __block RefPtr<WebVideoFullscreenModelVideoElement> protect(this);
-    WebThreadRun(^ {
-        exitVideoFullscreenForVideoElement(*m_videoElement);
-        protect.clear();
+    RefPtr<WebVideoFullscreenManager> strongThis(this);
+    WebThreadRun([strongThis, videoElement] {
+        strongThis->exitVideoFullscreenForVideoElement(*videoElement);
     });
 }
 
-void WebVideoFullscreenManager::didExitFullscreen()
+void WebVideoFullscreenManager::didExitFullscreen(uint64_t contextId)
 {
-    setVideoFullscreenLayer(nil);
-    __block RefPtr<WebVideoFullscreenModelVideoElement> protect(this);
+    RefPtr<WebVideoFullscreenModelVideoElement> model;
+    RefPtr<WebVideoFullscreenInterfaceContext> interface;
+    std::tie(model, interface) = ensureModelAndInterface(contextId);
+
+    model->setVideoFullscreenLayer(nil);
 
-    dispatch_async(dispatch_get_main_queue(), ^{
-        if (m_layerHostingContext) {
-            m_layerHostingContext->setRootLayer(nullptr);
-            m_layerHostingContext = nullptr;
+    RefPtr<WebVideoFullscreenManager> strongThis(this);
+    dispatch_async(dispatch_get_main_queue(), [strongThis, contextId, interface] {
+        if (interface->layerHostingContext()) {
+            interface->layerHostingContext()->setRootLayer(nullptr);
+            interface->setLayerHostingContext(nullptr);
         }
-        if (m_page)
-            m_page->send(Messages::WebVideoFullscreenManagerProxy::CleanupFullscreen(), m_page->pageID());
-        protect.clear();
+        if (strongThis->m_page)
+            strongThis->m_page->send(Messages::WebVideoFullscreenManagerProxy::CleanupFullscreen(contextId), strongThis->m_page->pageID());
     });
 }
     
-void WebVideoFullscreenManager::didCleanupFullscreen()
+void WebVideoFullscreenManager::didCleanupFullscreen(uint64_t contextId)
 {
-    m_isAnimating = false;
-    m_isFullscreen = false;
-    
-    setVideoElement(nullptr);
+    RefPtr<WebVideoFullscreenModelVideoElement> model;
+    RefPtr<WebVideoFullscreenInterfaceContext> interface;
+    std::tie(model, interface) = ensureModelAndInterface(contextId);
+
+    interface->setIsAnimating(false);
+    interface->setIsFullscreen(false);
+    HTMLMediaElement::VideoFullscreenMode mode = interface->fullscreenMode();
+
+    model->setVideoFullscreenLayer(nil);
+    RefPtr<HTMLVideoElement> videoElement = model->videoElement();
+
+    if (!interface->targetIsFullscreen()) {
+        model->setVideoElement(nullptr);
+        model->setWebVideoFullscreenInterface(nullptr);
+        interface->invalidate();
+        m_videoElements.remove(videoElement.get());
+        m_contextMap.remove(contextId);
+        return;
+    }
 
-    if (!m_targetIsFullscreen)
+    if (!videoElement)
         return;
 
-    // enter fullscreen now if it was previously requested during an animation.
-    __block RefPtr<WebVideoFullscreenModelVideoElement> protect(this);
-    WebThreadRun(^ {
-        enterVideoFullscreenForVideoElement(*m_videoElement, m_fullscreenMode);
-        protect.clear();
+    // exit fullscreen now if it was previously requested during an animation.
+    RefPtr<WebVideoFullscreenManager> strongThis(this);
+    WebThreadRun([strongThis, videoElement, mode] {
+        strongThis->enterVideoFullscreenForVideoElement(*videoElement, mode);
     });
 }
     
-void WebVideoFullscreenManager::setVideoLayerGravityEnum(unsigned gravity)
+void WebVideoFullscreenManager::setVideoLayerGravityEnum(uint64_t contextId, unsigned gravity)
 {
-    setVideoLayerGravity((WebVideoFullscreenModel::VideoGravity)gravity);
+    ensureModel(contextId).setVideoLayerGravity((WebVideoFullscreenModel::VideoGravity)gravity);
 }
     
-void WebVideoFullscreenManager::fullscreenMayReturnToInline(bool isPageVisible)
+void WebVideoFullscreenManager::fullscreenMayReturnToInline(uint64_t contextId, bool isPageVisible)
 {
+    auto& model = ensureModel(contextId);
+
     if (!isPageVisible)
-        m_videoElement->scrollIntoViewIfNotVisible(false);
-    m_page->send(Messages::WebVideoFullscreenManagerProxy::PreparedToReturnToInline(true, clientRectForElement(m_videoElement.get())), m_page->pageID());
+        model.videoElement()->scrollIntoViewIfNotVisible(false);
+    m_page->send(Messages::WebVideoFullscreenManagerProxy::PreparedToReturnToInline(contextId, true, clientRectForElement(model.videoElement())), m_page->pageID());
 }
     
-void WebVideoFullscreenManager::setVideoLayerFrameFenced(WebCore::FloatRect bounds, IPC::Attachment fencePort)
+void WebVideoFullscreenManager::setVideoLayerFrameFenced(uint64_t contextId, WebCore::FloatRect bounds, IPC::Attachment fencePort)
 {
+    RefPtr<WebVideoFullscreenModelVideoElement> model;
+    RefPtr<WebVideoFullscreenInterfaceContext> interface;
+    std::tie(model, interface) = ensureModelAndInterface(contextId);
+
     [CATransaction begin];
     [CATransaction setAnimationDuration:0];
-    if (m_layerHostingContext)
-        m_layerHostingContext->setFencePort(fencePort.port());
-    setVideoLayerFrame(bounds);
+    if (interface->layerHostingContext())
+        interface->layerHostingContext()->setFencePort(fencePort.port());
+    model->setVideoLayerFrame(bounds);
     mach_port_deallocate(mach_task_self(), fencePort.port());
     [CATransaction commit];
 }