Changeset 201119 in webkit


Ignore:
Timestamp:
May 18, 2016, 5:20:26 PM (9 years ago)
Author:
eric.carlson@apple.com
Message:

[iOS] Fullscreen video playback broken in WK1 apps
https://bugs.webkit.org/show_bug.cgi?id=157847
<rdar://problem/25879521>

Reviewed by Jer Noble.

  • platform/cocoa/WebVideoFullscreenModelVideoElement.h:

(WebCore::WebVideoFullscreenModelVideoElement::playbackSessionModel): New, model accessor.

  • platform/cocoa/WebVideoFullscreenModelVideoElement.mm:

(WebVideoFullscreenModelVideoElement::setWebVideoFullscreenInterface): Set model's playback interface.
(WebVideoFullscreenModelVideoElement::setVideoElement): Set model's video element.

  • platform/ios/WebVideoFullscreenControllerAVKit.mm:

(WebVideoFullscreenControllerContext::didCleanupFullscreen): Clear m_sessionModel.
(WebVideoFullscreenControllerContext::setVideoDimensions): This is called from both the UI and

Web threads, so dispatch to the UI thread when necessary.

(WebVideoFullscreenControllerContext::play): Call the model's playback session on the Web thread.
(WebVideoFullscreenControllerContext::pause): Ditto.
(WebVideoFullscreenControllerContext::togglePlayState): Ditto.
(WebVideoFullscreenControllerContext::beginScrubbing): Ditto.
(WebVideoFullscreenControllerContext::endScrubbing): Ditto.
(WebVideoFullscreenControllerContext::seekToTime): Ditto.
(WebVideoFullscreenControllerContext::fastSeek): Ditto.
(WebVideoFullscreenControllerContext::beginScanningForward): Ditto.
(WebVideoFullscreenControllerContext::beginScanningBackward): Ditto.
(WebVideoFullscreenControllerContext::endScanning): Ditto.
(WebVideoFullscreenControllerContext::selectAudioMediaOption): Ditto.
(WebVideoFullscreenControllerContext::selectLegibleMediaOption): Ditto.
(WebVideoFullscreenControllerContext::setUpFullscreen): Create and configure a session model.
(WebVideoFullscreenSessionModel::play): Pass call back to the controller.
(WebVideoFullscreenSessionModel::pause): Ditto.
(WebVideoFullscreenSessionModel::togglePlayState): Ditto.
(WebVideoFullscreenSessionModel::beginScrubbing): Ditto.
(WebVideoFullscreenSessionModel::endScrubbing): Ditto.
(WebVideoFullscreenSessionModel::seekToTime): Ditto.
(WebVideoFullscreenSessionModel::fastSeek): Ditto.
(WebVideoFullscreenSessionModel::beginScanningForward): Ditto.
(WebVideoFullscreenSessionModel::beginScanningBackward): Ditto.
(WebVideoFullscreenSessionModel::endScanning): Ditto.
(WebVideoFullscreenSessionModel::selectAudioMediaOption): Ditto.
(WebVideoFullscreenSessionModel::selectLegibleMediaOption): Ditto.

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r201114 r201119  
     12016-05-18  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [iOS] Fullscreen video playback broken in WK1 apps
     4        https://bugs.webkit.org/show_bug.cgi?id=157847
     5        <rdar://problem/25879521>
     6
     7        Reviewed by Jer Noble.
     8
     9        * platform/cocoa/WebVideoFullscreenModelVideoElement.h:
     10        (WebCore::WebVideoFullscreenModelVideoElement::playbackSessionModel): New, model accessor.
     11        * platform/cocoa/WebVideoFullscreenModelVideoElement.mm:
     12        (WebVideoFullscreenModelVideoElement::setWebVideoFullscreenInterface): Set model's playback interface.
     13        (WebVideoFullscreenModelVideoElement::setVideoElement): Set model's video element.
     14
     15        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
     16        (WebVideoFullscreenControllerContext::didCleanupFullscreen): Clear m_sessionModel.
     17        (WebVideoFullscreenControllerContext::setVideoDimensions): This is called from both the UI and
     18          Web threads, so dispatch to the UI thread when necessary.
     19        (WebVideoFullscreenControllerContext::play): Call the model's playback session on the Web thread.
     20        (WebVideoFullscreenControllerContext::pause): Ditto.
     21        (WebVideoFullscreenControllerContext::togglePlayState): Ditto.
     22        (WebVideoFullscreenControllerContext::beginScrubbing): Ditto.
     23        (WebVideoFullscreenControllerContext::endScrubbing): Ditto.
     24        (WebVideoFullscreenControllerContext::seekToTime): Ditto.
     25        (WebVideoFullscreenControllerContext::fastSeek): Ditto.
     26        (WebVideoFullscreenControllerContext::beginScanningForward): Ditto.
     27        (WebVideoFullscreenControllerContext::beginScanningBackward): Ditto.
     28        (WebVideoFullscreenControllerContext::endScanning): Ditto.
     29        (WebVideoFullscreenControllerContext::selectAudioMediaOption): Ditto.
     30        (WebVideoFullscreenControllerContext::selectLegibleMediaOption): Ditto.
     31        (WebVideoFullscreenControllerContext::setUpFullscreen): Create and configure a session model.
     32        (WebVideoFullscreenSessionModel::play): Pass call back to the controller.
     33        (WebVideoFullscreenSessionModel::pause): Ditto.
     34        (WebVideoFullscreenSessionModel::togglePlayState): Ditto.
     35        (WebVideoFullscreenSessionModel::beginScrubbing): Ditto.
     36        (WebVideoFullscreenSessionModel::endScrubbing): Ditto.
     37        (WebVideoFullscreenSessionModel::seekToTime): Ditto.
     38        (WebVideoFullscreenSessionModel::fastSeek): Ditto.
     39        (WebVideoFullscreenSessionModel::beginScanningForward): Ditto.
     40        (WebVideoFullscreenSessionModel::beginScanningBackward): Ditto.
     41        (WebVideoFullscreenSessionModel::endScanning): Ditto.
     42        (WebVideoFullscreenSessionModel::selectAudioMediaOption): Ditto.
     43        (WebVideoFullscreenSessionModel::selectLegibleMediaOption): Ditto.
     44
    1452016-05-18  Zalan Bujtas  <zalan@apple.com>
    246
  • trunk/Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.h

    r200490 r201119  
    5757    WEBCORE_EXPORT HTMLVideoElement* videoElement() const { return m_videoElement.get(); }
    5858    WEBCORE_EXPORT void setVideoFullscreenLayer(PlatformLayer*);
     59    WebPlaybackSessionModelMediaElement& playbackSessionModel() { return m_playbackSessionModel; }
    5960   
    6061    WEBCORE_EXPORT void handleEvent(WebCore::ScriptExecutionContext*, WebCore::Event*) override;
  • trunk/Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.mm

    r200490 r201119  
    6868
    6969    m_videoFullscreenInterface = interface;
     70    m_playbackSessionModel->setWebPlaybackSessionInterface(interface);
    7071
    7172    if (m_videoFullscreenInterface && m_videoElement)
     
    8889
    8990    m_videoElement = videoElement;
     91    m_playbackSessionModel->setMediaElement(videoElement);
    9092
    9193    if (!m_videoElement)
  • trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm

    r200895 r201119  
    8989
    9090class WebVideoFullscreenControllerContext;
     91class WebVideoFullscreenSessionModel;
    9192
    9293@interface WebVideoFullscreenController (delegate)
     
    105106        return adoptRef(*new WebVideoFullscreenControllerContext);
    106107    }
    107    
     108
    108109    void setController(WebVideoFullscreenController* controller) { m_controller = controller; }
    109110    void setUpFullscreen(HTMLVideoElement&, UIView *, HTMLMediaElementEnums::VideoFullscreenMode);
     
    111112    void requestHideAndExitFullscreen();
    112113    void invalidate();
     114
     115    void play();
     116    void pause();
     117    void togglePlayState();
     118    void beginScrubbing();
     119    void endScrubbing();
     120    void seekToTime(double);
     121    void fastSeek(double time);
     122    void beginScanningForward();
     123    void beginScanningBackward();
     124    void endScanning();
     125    void selectAudioMediaOption(uint64_t);
     126    void selectLegibleMediaOption(uint64_t);
    113127
    114128private:
     
    121135    void didCleanupFullscreen() override;
    122136    void fullscreenMayReturnToInline() override;
    123    
     137
    124138    // WebVideoFullscreenInterface
    125139    void resetMediaState() override;
     
    148162    RetainPtr<UIView> m_videoFullscreenView;
    149163    RetainPtr<WebVideoFullscreenController> m_controller;
     164    RefPtr<WebVideoFullscreenSessionModel> m_sessionModel;
     165};
     166
     167
     168class WebVideoFullscreenSessionModel final: public RefCounted<WebVideoFullscreenSessionModel>, public WebCore::WebPlaybackSessionModel  {
     169public:
     170    static Ref<WebVideoFullscreenSessionModel> create(WebVideoFullscreenControllerContext& controller)
     171    {
     172        return adoptRef(*new WebVideoFullscreenSessionModel(controller));
     173    }
     174    virtual ~WebVideoFullscreenSessionModel() { }
     175
     176    void invalidate() { m_controller = nullptr; }
     177
     178    void setDuration(double duration) { m_duration = duration; }
     179    void setCurrentTime(double currentTime) { m_currentTime = currentTime; }
     180    void setBufferedTime(double bufferedTime) { m_bufferedTime = bufferedTime; }
     181    void setIsPlaying(bool isPlaying) { m_isPlaying = isPlaying; }
     182    void setPlaybackRate(float playbackRate) { m_playbackRate = playbackRate; }
     183    void setSeekableRanges(WebCore::TimeRanges& seekableRanges) { m_seekableRanges = seekableRanges; }
     184    void setCanPlayFastReverse(bool canPlayFastReverse) { m_canPlayFastReverse = canPlayFastReverse; }
     185    void setAudioMediaSelectionOptions(const Vector<WTF::String>& audioMediaSelectionOptions) { m_audioMediaSelectionOptions = audioMediaSelectionOptions; }
     186    void setAudioMediaSelectedIndex(uint64_t audioMediaSelectedIndex) { m_audioMediaSelectedIndex = audioMediaSelectedIndex; }
     187    void setLegibleMediaSelectionOptions(const Vector<WTF::String>& legibleMediaSelectionOptions) { m_legibleMediaSelectionOptions = legibleMediaSelectionOptions; }
     188    void setLegibleMediaSelectedIndex(uint64_t legibleMediaSelectedIndex) { m_legibleMediaSelectedIndex = legibleMediaSelectedIndex; }
     189    void setExternalPlaybackEnabled(bool externalPlaybackEnabled) { m_externalPlaybackEnabled = externalPlaybackEnabled; }
     190    void setWirelessVideoPlaybackDisabled(bool wirelessVideoPlaybackDisabled) { m_wirelessVideoPlaybackDisabled = wirelessVideoPlaybackDisabled; }
     191
     192private:
     193    WebVideoFullscreenSessionModel(WebVideoFullscreenControllerContext& controller)
     194        : m_controller(&controller)
     195    {
     196    }
     197
     198    void play() final;
     199    void pause() final;
     200    void togglePlayState() final;
     201    void beginScrubbing() final;
     202    void endScrubbing() final;
     203    void seekToTime(double) final;
     204    void fastSeek(double time) final;
     205    void beginScanningForward() final;
     206    void beginScanningBackward() final;
     207    void endScanning() final;
     208    void selectAudioMediaOption(uint64_t) final;
     209    void selectLegibleMediaOption(uint64_t) final;
     210
     211    double duration() const final { return m_duration; }
     212    double currentTime() const final { return m_currentTime; }
     213    double bufferedTime() const final { return m_bufferedTime; }
     214    bool isPlaying() const final { return m_isPlaying; }
     215    float playbackRate() const final { return m_playbackRate; }
     216    Ref<WebCore::TimeRanges> seekableRanges() const final { return m_seekableRanges.copyRef(); }
     217    bool canPlayFastReverse() const final { return m_canPlayFastReverse; }
     218    Vector<WTF::String> audioMediaSelectionOptions() const final { return m_audioMediaSelectionOptions; }
     219    uint64_t audioMediaSelectedIndex() const final { return m_audioMediaSelectedIndex; }
     220    Vector<WTF::String> legibleMediaSelectionOptions() const final { return m_legibleMediaSelectionOptions; }
     221    uint64_t legibleMediaSelectedIndex() const final { return m_legibleMediaSelectedIndex; }
     222    bool externalPlaybackEnabled() const final { return m_externalPlaybackEnabled; }
     223    bool wirelessVideoPlaybackDisabled() const final { return m_wirelessVideoPlaybackDisabled; }
     224
     225    WebVideoFullscreenControllerContext* m_controller;
     226    double m_duration { 0 };
     227    double m_currentTime { 0 };
     228    double m_bufferedTime { 0 };
     229    bool m_isPlaying { false };
     230    float m_playbackRate { 0 };
     231    Ref<WebCore::TimeRanges> m_seekableRanges { WebCore::TimeRanges::create() };
     232    bool m_canPlayFastReverse { false };
     233    Vector<WTF::String> m_audioMediaSelectionOptions;
     234    uint64_t m_audioMediaSelectedIndex { 0 };
     235    Vector<WTF::String> m_legibleMediaSelectionOptions;
     236    uint64_t m_legibleMediaSelectedIndex { 0 };
     237    bool m_externalPlaybackEnabled { false };
     238    bool m_wirelessVideoPlaybackDisabled { false };
    150239};
    151240
     
    185274    m_interface = nullptr;
    186275    m_videoFullscreenView = nil;
    187    
     276    m_sessionModel->invalidate();
     277    m_sessionModel = nullptr;
     278
    188279    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
    189280    WebThreadRun([protectedThis, this] {
     
    193284        m_model = nullptr;
    194285        m_videoElement = nullptr;
    195        
     286
    196287        [m_controller didFinishFullscreen:this];
    197288    });
     
    264355void WebVideoFullscreenControllerContext::setVideoDimensions(bool hasVideo, float width, float height)
    265356{
    266     ASSERT(WebThreadIsCurrent());
    267     RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
    268     dispatch_async(dispatch_get_main_queue(), [protectedThis, this, hasVideo, width, height] {
    269         if (m_interface)
    270             m_interface->setVideoDimensions(hasVideo, width, height);
    271     });
     357    if (WebThreadIsCurrent()) {
     358        RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     359        dispatch_async(dispatch_get_main_queue(), [protectedThis, this, hasVideo, width, height] {
     360            if (m_interface)
     361                m_interface->setVideoDimensions(hasVideo, width, height);
     362        });
     363        return;
     364    }
     365
     366    if (m_interface)
     367        m_interface->setVideoDimensions(hasVideo, width, height);
    272368}
    273369
     
    413509}
    414510
     511#pragma mark - WebPlaybackSessionModelContext
     512
     513void WebVideoFullscreenControllerContext::play()
     514{
     515    ASSERT(isUIThread());
     516    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     517    WebThreadRun([protectedThis, this] {
     518        if (m_model)
     519            m_model->playbackSessionModel().play();
     520    });
     521}
     522
     523void WebVideoFullscreenControllerContext::pause()
     524{
     525    ASSERT(isUIThread());
     526    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     527    WebThreadRun([protectedThis, this] {
     528        if (m_model)
     529            m_model->playbackSessionModel().pause();
     530    });
     531}
     532
     533void WebVideoFullscreenControllerContext::togglePlayState()
     534{
     535    ASSERT(isUIThread());
     536    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     537    WebThreadRun([protectedThis, this] {
     538        if (m_model)
     539            m_model->playbackSessionModel().togglePlayState();
     540    });
     541}
     542
     543void WebVideoFullscreenControllerContext::beginScrubbing()
     544{
     545    ASSERT(isUIThread());
     546    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     547    WebThreadRun([protectedThis, this] {
     548        if (m_model)
     549            m_model->playbackSessionModel().beginScrubbing();
     550    });
     551}
     552
     553void WebVideoFullscreenControllerContext::endScrubbing()
     554{
     555    ASSERT(isUIThread());
     556    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     557    WebThreadRun([protectedThis, this] {
     558        if (m_model)
     559            m_model->playbackSessionModel().endScrubbing();
     560    });
     561}
     562
     563void WebVideoFullscreenControllerContext::seekToTime(double time)
     564{
     565    ASSERT(isUIThread());
     566    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     567    WebThreadRun([protectedThis, this, time] {
     568        if (m_model)
     569            m_model->playbackSessionModel().seekToTime(time);
     570    });
     571}
     572
     573void WebVideoFullscreenControllerContext::fastSeek(double time)
     574{
     575    ASSERT(isUIThread());
     576    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     577    WebThreadRun([protectedThis, this, time] {
     578        if (m_model)
     579            m_model->playbackSessionModel().fastSeek(time);
     580    });
     581}
     582
     583void WebVideoFullscreenControllerContext::beginScanningForward()
     584{
     585    ASSERT(isUIThread());
     586    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     587    WebThreadRun([protectedThis, this] {
     588        if (m_model)
     589            m_model->playbackSessionModel().beginScanningForward();
     590    });
     591}
     592
     593void WebVideoFullscreenControllerContext::beginScanningBackward()
     594{
     595    ASSERT(isUIThread());
     596    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     597    WebThreadRun([protectedThis, this] {
     598        if (m_model)
     599            m_model->playbackSessionModel().beginScanningBackward();
     600    });
     601}
     602
     603void WebVideoFullscreenControllerContext::endScanning()
     604{
     605    ASSERT(isUIThread());
     606    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     607    WebThreadRun([protectedThis, this] {
     608        if (m_model)
     609            m_model->playbackSessionModel().endScanning();
     610    });
     611}
     612
     613void WebVideoFullscreenControllerContext::selectAudioMediaOption(uint64_t index)
     614{
     615    ASSERT(isUIThread());
     616    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     617    WebThreadRun([protectedThis, this, index] {
     618        if (m_model)
     619            m_model->playbackSessionModel().selectAudioMediaOption(index);
     620    });
     621}
     622
     623void WebVideoFullscreenControllerContext::selectLegibleMediaOption(uint64_t index)
     624{
     625    ASSERT(isUIThread());
     626    RefPtr<WebVideoFullscreenControllerContext> protectedThis(this);
     627    WebThreadRun([protectedThis, this, index] {
     628        if (m_model)
     629            m_model->playbackSessionModel().selectLegibleMediaOption(index);
     630    });
     631}
     632
    415633#pragma mark Other
    416634
     
    425643        ASSERT(isUIThread());
    426644
    427         m_interface = WebVideoFullscreenInterfaceAVKit::create(WebPlaybackSessionInterfaceAVKit::create().get());
     645        Ref<WebPlaybackSessionInterfaceAVKit> sessionInterface = WebPlaybackSessionInterfaceAVKit::create();
     646        m_interface = WebVideoFullscreenInterfaceAVKit::create(sessionInterface.get());
     647
     648        m_sessionModel = WebVideoFullscreenSessionModel::create(*this);
     649        sessionInterface->setWebPlaybackSessionModel(m_sessionModel.get());
     650
     651        m_interface->setWebVideoFullscreenModel(this);
    428652        m_interface->setWebVideoFullscreenChangeObserver(this);
    429         m_interface->setWebVideoFullscreenModel(this);
     653
    430654        m_videoFullscreenView = adoptNS([[getUIViewClass() alloc] init]);
    431655       
     
    435659            m_model->setWebVideoFullscreenInterface(this);
    436660            m_model->setVideoElement(m_videoElement.get());
    437            
    438             bool allowsPictureInPicture = m_videoElement->mediaSession().allowsPictureInPicture(*m_videoElement.get());
    439661
    440662            IntRect videoElementClientRect = elementRectInWindow(m_videoElement.get());
     
    442664            m_model->setVideoLayerFrame(videoLayerFrame);
    443665           
     666            bool allowsPictureInPicture = m_videoElement->mediaSession().allowsPictureInPicture(*m_videoElement.get());
    444667            dispatch_async(dispatch_get_main_queue(), [protectedThis, this, videoElementClientRect, viewRef, mode, allowsPictureInPicture] {
    445668                m_interface->setupFullscreen(*m_videoFullscreenView.get(), videoElementClientRect, viewRef.get(), mode, allowsPictureInPicture);
     
    465688    m_interface->requestHideAndExitFullscreen();
    466689}
     690
     691#pragma mark WebPlaybackSessionModel
     692
     693void WebVideoFullscreenSessionModel::play()
     694{
     695    if (m_controller)
     696        m_controller->play();
     697}
     698
     699void WebVideoFullscreenSessionModel::pause()
     700{
     701    if (m_controller)
     702        m_controller->pause();
     703}
     704
     705void WebVideoFullscreenSessionModel::togglePlayState()
     706{
     707    if (m_controller)
     708        m_controller->togglePlayState();
     709}
     710
     711void WebVideoFullscreenSessionModel::beginScrubbing()
     712{
     713    if (m_controller)
     714        m_controller->beginScrubbing();
     715}
     716
     717void WebVideoFullscreenSessionModel::endScrubbing()
     718{
     719    if (m_controller)
     720        m_controller->endScrubbing();
     721}
     722
     723void WebVideoFullscreenSessionModel::seekToTime(double time)
     724{
     725    if (m_controller)
     726        m_controller->seekToTime(time);
     727}
     728
     729void WebVideoFullscreenSessionModel::fastSeek(double time)
     730{
     731    if (m_controller)
     732        m_controller->fastSeek(time);
     733}
     734
     735void WebVideoFullscreenSessionModel::beginScanningForward()
     736{
     737    if (m_controller)
     738        m_controller->beginScanningForward();
     739}
     740
     741void WebVideoFullscreenSessionModel::beginScanningBackward()
     742{
     743    if (m_controller)
     744        m_controller->beginScanningBackward();
     745}
     746
     747void WebVideoFullscreenSessionModel::endScanning()
     748{
     749    if (m_controller)
     750        m_controller->endScanning();
     751}
     752
     753void WebVideoFullscreenSessionModel::selectAudioMediaOption(uint64_t optionId)
     754{
     755    if (m_controller)
     756        m_controller->selectAudioMediaOption(optionId);
     757}
     758
     759void WebVideoFullscreenSessionModel::selectLegibleMediaOption(uint64_t optionId)
     760{
     761    if (m_controller)
     762        m_controller->selectLegibleMediaOption(optionId);
     763}
     764
    467765
    468766@implementation WebVideoFullscreenController {
Note: See TracChangeset for help on using the changeset viewer.