Changeset 251745 in webkit


Ignore:
Timestamp:
Oct 29, 2019 5:21:19 PM (4 years ago)
Author:
commit-queue@webkit.org
Message:

[Picture-in-Picture Web API] Implement PictureInPictureWindow
https://bugs.webkit.org/show_bug.cgi?id=202615

Patch by Peng Liu <Peng Liu> on 2019-10-29
Reviewed by Eric Carlson.

Source/WebCore:

Tests: media/picture-in-picture-api-enter-pip-1.html

media/picture-in-picture-api-enter-pip-2.html
media/picture-in-picture-api-enter-pip-3.html
media/picture-in-picture-api-enter-pip-4.html
media/picture-in-picture-api-exit-pip-1.html
media/picture-in-picture-api-exit-pip-2.html
media/picture-in-picture-api-pip-events.html
media/picture-in-picture-api-pip-window.html

  • Modules/pictureinpicture/HTMLVideoElementPictureInPicture.cpp:

(WebCore::HTMLVideoElementPictureInPicture::HTMLVideoElementPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::requestPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::didEnterPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::didExitPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::pictureInPictureWindowResized):

  • Modules/pictureinpicture/HTMLVideoElementPictureInPicture.h:
  • Modules/pictureinpicture/PictureInPictureWindow.cpp:

(WebCore::PictureInPictureWindow::create):
(WebCore::PictureInPictureWindow::PictureInPictureWindow):
(WebCore::PictureInPictureWindow::setSize):
(WebCore::PictureInPictureWindow::close):

  • Modules/pictureinpicture/PictureInPictureWindow.h:
  • html/HTMLVideoElement.cpp:

(WebCore::HTMLVideoElement::fullscreenModeChanged):
(WebCore::HTMLVideoElement::didBecomeFullscreenElement):
(WebCore::HTMLVideoElement::setPictureInPictureObserver):
(WebCore::HTMLVideoElement::setVideoFullscreenFrame):

  • html/HTMLVideoElement.h:
  • platform/PictureInPictureObserver.h:

LayoutTests:

Add layout test cases for the Picture-in-Picture API.

  • TestExpectations:
  • media/picture-in-picture-api-enter-pip-1-expected.txt: Added.
  • media/picture-in-picture-api-enter-pip-1.html: Added.
  • media/picture-in-picture-api-enter-pip-2-expected.txt: Added.
  • media/picture-in-picture-api-enter-pip-2.html: Added.
  • media/picture-in-picture-api-enter-pip-3-expected.txt: Added.
  • media/picture-in-picture-api-enter-pip-3.html: Added.
  • media/picture-in-picture-api-enter-pip-4-expected.txt: Added.
  • media/picture-in-picture-api-enter-pip-4.html: Added.
  • media/picture-in-picture-api-exit-pip-1-expected.txt: Added.
  • media/picture-in-picture-api-exit-pip-1.html: Added.
  • media/picture-in-picture-api-exit-pip-2-expected.txt: Added.
  • media/picture-in-picture-api-exit-pip-2.html: Added.
  • media/picture-in-picture-api-pip-events-expected.txt: Added.
  • media/picture-in-picture-api-pip-events.html: Added.
  • media/picture-in-picture-api-pip-window-expected.txt: Added.
  • media/picture-in-picture-api-pip-window.html: Added.
  • platform/mac-wk2/TestExpectations:
Location:
trunk
Files:
16 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r251742 r251745  
     12019-10-29  Peng Liu  <peng.liu6@apple.com>
     2
     3        [Picture-in-Picture Web API] Implement PictureInPictureWindow
     4        https://bugs.webkit.org/show_bug.cgi?id=202615
     5
     6        Reviewed by Eric Carlson.
     7
     8        Add layout test cases for the Picture-in-Picture API.
     9
     10        * TestExpectations:
     11        * media/picture-in-picture-api-enter-pip-1-expected.txt: Added.
     12        * media/picture-in-picture-api-enter-pip-1.html: Added.
     13        * media/picture-in-picture-api-enter-pip-2-expected.txt: Added.
     14        * media/picture-in-picture-api-enter-pip-2.html: Added.
     15        * media/picture-in-picture-api-enter-pip-3-expected.txt: Added.
     16        * media/picture-in-picture-api-enter-pip-3.html: Added.
     17        * media/picture-in-picture-api-enter-pip-4-expected.txt: Added.
     18        * media/picture-in-picture-api-enter-pip-4.html: Added.
     19        * media/picture-in-picture-api-exit-pip-1-expected.txt: Added.
     20        * media/picture-in-picture-api-exit-pip-1.html: Added.
     21        * media/picture-in-picture-api-exit-pip-2-expected.txt: Added.
     22        * media/picture-in-picture-api-exit-pip-2.html: Added.
     23        * media/picture-in-picture-api-pip-events-expected.txt: Added.
     24        * media/picture-in-picture-api-pip-events.html: Added.
     25        * media/picture-in-picture-api-pip-window-expected.txt: Added.
     26        * media/picture-in-picture-api-pip-window.html: Added.
     27        * platform/mac-wk2/TestExpectations:
     28
    1292019-10-29  Antoine Quint  <graouts@apple.com>
    230
  • trunk/LayoutTests/TestExpectations

    r251731 r251745  
    196196# PiP API tests are only relevant on mac and iPad
    197197media/picture-in-picture-api-element-attributes.html [ Skip ]
     198media/picture-in-picture-api-enter-pip-1.html [ Skip ]
     199media/picture-in-picture-api-enter-pip-2.html [ Skip ]
     200media/picture-in-picture-api-enter-pip-3.html [ Skip ]
     201media/picture-in-picture-api-enter-pip-4.html [ Skip ]
     202media/picture-in-picture-api-exit-pip-1.html [ Skip ]
     203media/picture-in-picture-api-exit-pip-2.html [ Skip ]
     204media/picture-in-picture-api-pip-events.html [ Skip ]
     205media/picture-in-picture-api-pip-window.html [ Skip ]
    198206
    199207# Shared Workers are unsupported
  • trunk/LayoutTests/platform/mac-wk2/TestExpectations

    r251715 r251745  
    543543[ Sierra+ ] media/pip-video-going-into-fullscreen.html [ Pass ]
    544544[ Sierra+ ] media/picture-in-picture-api-element-attributes.html [ Pass ]
     545[ Sierra+ ] media/picture-in-picture-api-enter-pip-1.html [ Pass ]
     546[ Sierra+ ] media/picture-in-picture-api-enter-pip-2.html [ Pass ]
     547[ Sierra+ ] media/picture-in-picture-api-enter-pip-3.html [ Pass ]
     548[ Sierra+ ] media/picture-in-picture-api-enter-pip-4.html [ Pass ]
     549[ Sierra+ ] media/picture-in-picture-api-exit-pip-1.html [ Pass ]
     550[ Sierra+ ] media/picture-in-picture-api-exit-pip-2.html [ Pass ]
     551[ Sierra+ ] media/picture-in-picture-api-pip-events.html [ Pass ]
     552[ Sierra+ ] media/picture-in-picture-api-pip-window.html [ Pass ]
    545553
    546554# RTL Scrollbars are enabled on Sierra WebKit2.
  • trunk/Source/WebCore/ChangeLog

    r251742 r251745  
     12019-10-29  Peng Liu  <peng.liu6@apple.com>
     2
     3        [Picture-in-Picture Web API] Implement PictureInPictureWindow
     4        https://bugs.webkit.org/show_bug.cgi?id=202615
     5
     6        Reviewed by Eric Carlson.
     7
     8        Tests: media/picture-in-picture-api-enter-pip-1.html
     9               media/picture-in-picture-api-enter-pip-2.html
     10               media/picture-in-picture-api-enter-pip-3.html
     11               media/picture-in-picture-api-enter-pip-4.html
     12               media/picture-in-picture-api-exit-pip-1.html
     13               media/picture-in-picture-api-exit-pip-2.html
     14               media/picture-in-picture-api-pip-events.html
     15               media/picture-in-picture-api-pip-window.html
     16
     17        * Modules/pictureinpicture/HTMLVideoElementPictureInPicture.cpp:
     18        (WebCore::HTMLVideoElementPictureInPicture::HTMLVideoElementPictureInPicture):
     19        (WebCore::HTMLVideoElementPictureInPicture::requestPictureInPicture):
     20        (WebCore::HTMLVideoElementPictureInPicture::didEnterPictureInPicture):
     21        (WebCore::HTMLVideoElementPictureInPicture::didExitPictureInPicture):
     22        (WebCore::HTMLVideoElementPictureInPicture::pictureInPictureWindowResized):
     23        * Modules/pictureinpicture/HTMLVideoElementPictureInPicture.h:
     24        * Modules/pictureinpicture/PictureInPictureWindow.cpp:
     25        (WebCore::PictureInPictureWindow::create):
     26        (WebCore::PictureInPictureWindow::PictureInPictureWindow):
     27        (WebCore::PictureInPictureWindow::setSize):
     28        (WebCore::PictureInPictureWindow::close):
     29        * Modules/pictureinpicture/PictureInPictureWindow.h:
     30        * html/HTMLVideoElement.cpp:
     31        (WebCore::HTMLVideoElement::fullscreenModeChanged):
     32        (WebCore::HTMLVideoElement::didBecomeFullscreenElement):
     33        (WebCore::HTMLVideoElement::setPictureInPictureObserver):
     34        (WebCore::HTMLVideoElement::setVideoFullscreenFrame):
     35        * html/HTMLVideoElement.h:
     36        * platform/PictureInPictureObserver.h:
     37
    1382019-10-29  Antoine Quint  <graouts@apple.com>
    239
  • trunk/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.cpp

    r251530 r251745  
    3232#include "HTMLVideoElement.h"
    3333#include "JSDOMPromiseDeferred.h"
     34#include "JSPictureInPictureWindow.h"
    3435#include "Logging.h"
    3536#include "PictureInPictureWindow.h"
     
    4344HTMLVideoElementPictureInPicture::HTMLVideoElementPictureInPicture(HTMLVideoElement& videoElement)
    4445    : m_videoElement(videoElement)
     46    , m_pictureInPictureWindow(PictureInPictureWindow::create(videoElement.document()))
    4547#if !RELEASE_LOG_DISABLED
    4648    , m_logger(videoElement.document().logger())
     
    7173void HTMLVideoElementPictureInPicture::requestPictureInPicture(HTMLVideoElement& videoElement, Ref<DeferredPromise>&& promise)
    7274{
    73     if (!videoElement.player() || !videoElement.player()->supportsPictureInPicture()) {
    74         promise->reject(NotSupportedError, "The video element does not support the Picture-in-Picture mode.");
    75         return;
    76     }
    77 
    7875    if (videoElement.readyState() == HTMLMediaElementEnums::HAVE_NOTHING) {
    7976        promise->reject(InvalidStateError, "The video element is not ready to enter the Picture-in-Picture mode.");
     
    9491    }
    9592
     93    auto videoElementPictureInPicture = HTMLVideoElementPictureInPicture::from(videoElement);
    9694    if (videoElement.document().pictureInPictureElement() == &videoElement) {
    97         promise->reject(NotAllowedError, "The video element is already in the Picture-in-Picture mode.");
     95        promise->resolve<IDLInterface<PictureInPictureWindow>>(*(videoElementPictureInPicture->m_pictureInPictureWindow));
    9896        return;
    9997    }
    10098
    101     auto videoElementPictureInPicture = HTMLVideoElementPictureInPicture::from(videoElement);
    10299    if (videoElementPictureInPicture->m_enterPictureInPicturePromise || videoElementPictureInPicture->m_exitPictureInPicturePromise) {
    103100        promise->reject(NotAllowedError, "The video element is processing a Picture-in-Picture request.");
     
    144141}
    145142
    146 void HTMLVideoElementPictureInPicture::didEnterPictureInPicture(IntSize windowSize)
     143void HTMLVideoElementPictureInPicture::didEnterPictureInPicture(const IntSize& windowSize)
    147144{
    148145    INFO_LOG(LOGIDENTIFIER);
    149146    m_videoElement.document().setPictureInPictureElement(&m_videoElement);
     147    m_pictureInPictureWindow->setSize(windowSize);
     148
    150149    if (m_enterPictureInPicturePromise) {
    151150        EnterPictureInPictureEvent::Init initializer;
    152151        initializer.bubbles = true;
    153         initializer.pictureInPictureWindow = PictureInPictureWindow::create(m_videoElement.document(), windowSize.width(), windowSize.height());
     152        initializer.pictureInPictureWindow = m_pictureInPictureWindow;
    154153        m_videoElement.scheduleEvent(EnterPictureInPictureEvent::create(eventNames().enterpictureinpictureEvent, WTFMove(initializer)));
    155 
    156         m_enterPictureInPicturePromise->resolve();
     154        m_enterPictureInPicturePromise->resolve<IDLInterface<PictureInPictureWindow>>(*m_pictureInPictureWindow);
    157155        m_enterPictureInPicturePromise = nullptr;
    158156    }
     
    162160{
    163161    INFO_LOG(LOGIDENTIFIER);
     162    m_pictureInPictureWindow->close();
    164163    m_videoElement.document().setPictureInPictureElement(nullptr);
     164
    165165    if (m_exitPictureInPicturePromise) {
    166166        m_videoElement.scheduleEvent(Event::create(eventNames().leavepictureinpictureEvent, Event::CanBubble::Yes, Event::IsCancelable::No));
    167 
    168167        m_exitPictureInPicturePromise->resolve();
    169168        m_exitPictureInPicturePromise = nullptr;
    170169    }
     170}
     171
     172void HTMLVideoElementPictureInPicture::pictureInPictureWindowResized(const IntSize& windowSize)
     173{
     174    if (m_pictureInPictureWindow->width() == windowSize.width() && m_pictureInPictureWindow->height() == windowSize.height())
     175        return;
     176
     177    m_pictureInPictureWindow->setSize(windowSize);
     178    auto resizeEvent = Event::create(eventNames().resizeEvent, Event::CanBubble::Yes, Event::IsCancelable::No);
     179    resizeEvent->setTarget(m_pictureInPictureWindow);
     180    m_videoElement.scheduleEvent(WTFMove(resizeEvent));
    171181}
    172182
     
    178188#endif
    179189
    180 void HTMLVideoElementPictureInPicture::pictureInPictureWindowResized(IntSize)
    181 {
    182 }
    183 
    184190} // namespace WebCore
    185191
  • trunk/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.h

    r251530 r251745  
    6161    void exitPictureInPicture(Ref<DeferredPromise>&&);
    6262
    63     void didEnterPictureInPicture(IntSize);
     63    void didEnterPictureInPicture(const IntSize&);
    6464    void didExitPictureInPicture();
    65     void pictureInPictureWindowResized(IntSize);
     65    void pictureInPictureWindowResized(const IntSize&);
    6666
    6767#if !RELEASE_LOG_DISABLED
     
    7979
    8080    HTMLVideoElement& m_videoElement;
     81    RefPtr<PictureInPictureWindow> m_pictureInPictureWindow;
    8182    RefPtr<DeferredPromise> m_enterPictureInPicturePromise;
    8283    RefPtr<DeferredPromise> m_exitPictureInPicturePromise;
  • trunk/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.cpp

    r251530 r251745  
    3636WTF_MAKE_ISO_ALLOCATED_IMPL(PictureInPictureWindow);
    3737
    38 Ref<PictureInPictureWindow> PictureInPictureWindow::create(ScriptExecutionContext& scriptExecutionContext, int width, int height)
     38Ref<PictureInPictureWindow> PictureInPictureWindow::create(ScriptExecutionContext& scriptExecutionContext)
    3939{
    40     return adoptRef(*new PictureInPictureWindow(scriptExecutionContext, width, height));
     40    return adoptRef(*new PictureInPictureWindow(scriptExecutionContext));
    4141}
    4242
    43 PictureInPictureWindow::PictureInPictureWindow(ScriptExecutionContext& scriptExecutionContext, int width, int height)
     43PictureInPictureWindow::PictureInPictureWindow(ScriptExecutionContext& scriptExecutionContext)
    4444    : m_scriptExecutionContext(scriptExecutionContext)
    45     , m_width(width)
    46     , m_height(height)
    4745{
    4846}
     
    5048PictureInPictureWindow::~PictureInPictureWindow() = default;
    5149
     50void PictureInPictureWindow::setSize(const IntSize& size)
     51{
     52    m_size = size;
     53}
     54
     55void PictureInPictureWindow::close()
     56{
     57    m_size = { 0, 0 };
     58}
     59
    5260} // namespace WebCore
    5361
  • trunk/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.h

    r251530 r251745  
    3939    WTF_MAKE_ISO_ALLOCATED(PictureInPictureWindow);
    4040public:
    41     static Ref<PictureInPictureWindow> create(ScriptExecutionContext&, int, int);
     41    static Ref<PictureInPictureWindow> create(ScriptExecutionContext&);
    4242    virtual ~PictureInPictureWindow();
    4343
    44     int width() const { return m_width; }
    45     int height() const { return m_height; }
     44    int width() const { return m_size.width(); }
     45    int height() const { return m_size.height(); }
     46    void setSize(const IntSize&);
     47    void close();
    4648
    4749    using RefCounted<PictureInPictureWindow>::ref;
     
    4951
    5052private:
    51     PictureInPictureWindow(ScriptExecutionContext&, int, int);
     53    PictureInPictureWindow(ScriptExecutionContext&);
    5254
    5355    // EventTarget
     
    5860
    5961    ScriptExecutionContext& m_scriptExecutionContext;
    60     int m_width;
    61     int m_height;
     62    IntSize m_size;
    6263};
    6364
  • trunk/Source/WebCore/html/HTMLVideoElement.cpp

    r251530 r251745  
    493493            HTMLVideoElement::VideoPresentationMode sourceVideoPresentationMode = toPresentationMode(fullscreenMode());
    494494
    495             if (targetVideoPresentationMode != HTMLVideoElement::VideoPresentationMode::PictureInPicture && sourceVideoPresentationMode == HTMLVideoElement::VideoPresentationMode::PictureInPicture)
     495            if (targetVideoPresentationMode != HTMLVideoElement::VideoPresentationMode::PictureInPicture && sourceVideoPresentationMode == HTMLVideoElement::VideoPresentationMode::PictureInPicture) {
    496496                m_pictureInPictureObserver->didExitPictureInPicture();
     497                m_isFullscreen = false;
     498            }
    497499        }
    498500#endif
     
    508510void HTMLVideoElement::didBecomeFullscreenElement()
    509511{
     512    m_isFullscreen = true;
    510513    m_waitingForPictureInPictureWindowFrame = true;
    511514    HTMLMediaElement::didBecomeFullscreenElement();
     
    516519    m_pictureInPictureObserver = observer;
    517520}
    518 
    519521#endif
    520522
     
    527529
    528530#if ENABLE(PICTURE_IN_PICTURE_API)
     531    // fullscreenMode() does not always provide the correct fullscreen mode
     532    // when mode changing is happening (webkit.org/b/203443)
     533    if (!m_isFullscreen)
     534        return;
     535
    529536    if (toPresentationMode(fullscreenMode()) != VideoPresentationMode::PictureInPicture)
    530537        return;
  • trunk/Source/WebCore/html/HTMLVideoElement.h

    r251530 r251745  
    138138#if ENABLE(PICTURE_IN_PICTURE_API)
    139139    bool m_waitingForPictureInPictureWindowFrame { false };
     140    bool m_isFullscreen { false };
    140141    PictureInPictureObserver* m_pictureInPictureObserver { nullptr };
    141142#endif
  • trunk/Source/WebCore/platform/PictureInPictureObserver.h

    r251530 r251745  
    3333public:
    3434    virtual ~PictureInPictureObserver() { };
    35     virtual void didEnterPictureInPicture(IntSize) = 0;
     35    virtual void didEnterPictureInPicture(const IntSize&) = 0;
    3636    virtual void didExitPictureInPicture() = 0;
    37     virtual void pictureInPictureWindowResized(IntSize) = 0;
     37    virtual void pictureInPictureWindowResized(const IntSize&) = 0;
    3838};
    3939
Note: See TracChangeset for help on using the changeset viewer.