⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 235752 in webkit


Ignore:
Timestamp:
Sep 6, 2018, 12:59:33 PM (8 years ago)
Author:
jer.noble@apple.com
Message:

Don't pause playback when locking screen if video is being displayed on second screen.
​https://bugs.webkit.org/show_bug.cgi?id=189321

Reviewed by Eric Carlson.

Source/WebCore:

Expand the existing behavior when AirPlaying to an external device to playing to a local
external screen. Don't pause when the screen locks, and don't stop buffering in that mode either.

Add a KVO-observer to the WebAVPlayerController's playingOnSecondScreen property, and pass
that observed value on to the media element.

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::setShouldPlayToPlaybackTarget):
(WebCore::HTMLMediaElement::setPlayingOnSecondScreen):
(WebCore::HTMLMediaElement::shouldOverrideBackgroundPlaybackRestriction const):
(WebCore::HTMLMediaElement::processingUserGestureForMedia const):
(WebCore::HTMLMediaElement::mediaState const):
(WebCore::HTMLMediaElement::purgeBufferedDataIfPossible):
(WebCore::HTMLMediaElement::shouldOverrideBackgroundLoadingRestriction const):
(WebCore::HTMLMediaElement::webkitCurrentPlaybackTargetIsWireless const): Deleted.
(WebCore::HTMLMediaElement::canPlayToWirelessPlaybackTarget const): Deleted.
(WebCore::HTMLMediaElement::isPlayingToWirelessPlaybackTarget const): Deleted.

  • html/HTMLMediaElement.h:

(WebCore::HTMLMediaElement::webkitCurrentPlaybackTargetIsWireless const):
(WebCore::HTMLMediaElement::isPlayingToExternalTarget const):

  • html/MediaElementSession.cpp:

(WebCore::MediaElementSession::canPlayToWirelessPlaybackTarget const): Deleted.

  • html/MediaElementSession.h:
  • platform/audio/PlatformMediaSession.h:

(WebCore::PlatformMediaSessionClient::setWirelessPlaybackTarget):
(WebCore::PlatformMediaSessionClient::isPlayingOnSecondScreen const):
(WebCore::PlatformMediaSession::canPlayToWirelessPlaybackTarget const): Deleted.
(WebCore::PlatformMediaSessionClient::canPlayToWirelessPlaybackTarget const): Deleted.

  • platform/cocoa/PlaybackSessionModel.h:
  • platform/cocoa/PlaybackSessionModelMediaElement.h:
  • platform/cocoa/PlaybackSessionModelMediaElement.mm:

(WebCore::PlaybackSessionModelMediaElement::setPlayingOnSecondScreen):

  • platform/ios/WebAVPlayerController.mm:

(-[WebAVPlayerController init]):
(-[WebAVPlayerController dealloc]):
(-[WebAVPlayerController observeValueForKeyPath:ofObject:change:context:]):

  • platform/ios/WebVideoFullscreenControllerAVKit.mm:

(VideoFullscreenControllerContext::setPlayingOnSecondScreen):

Source/WebKit:

Pass the "isPlayingOnSecondScreen" value across the process boundary.

  • UIProcess/Cocoa/PlaybackSessionManagerProxy.h:
  • UIProcess/Cocoa/PlaybackSessionManagerProxy.mm:

(WebKit::PlaybackSessionModelContext::setPlayingOnSecondScreen):
(WebKit::PlaybackSessionManagerProxy::setPlayingOnSecondScreen):

  • WebProcess/cocoa/PlaybackSessionManager.h:
  • WebProcess/cocoa/PlaybackSessionManager.messages.in:
  • WebProcess/cocoa/PlaybackSessionManager.mm:

(WebKit::PlaybackSessionManager::setPlayingOnSecondScreen):

Location:
trunk/Source
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r235749 r235752  
     12018-09-06  Jer Noble  <jer.noble@apple.com>
     2
     3        Don't pause playback when locking screen if video is being displayed on second screen.
     4        https://bugs.webkit.org/show_bug.cgi?id=189321
     5
     6        Reviewed by Eric Carlson.
     7
     8        Expand the existing behavior when AirPlaying to an external device to playing to a local
     9        external screen. Don't pause when the screen locks, and don't stop buffering in that mode either.
     10
     11        Add a KVO-observer to the WebAVPlayerController's playingOnSecondScreen property, and pass
     12        that observed value on to the media element.
     13
     14        * html/HTMLMediaElement.cpp:
     15        (WebCore::HTMLMediaElement::setShouldPlayToPlaybackTarget):
     16        (WebCore::HTMLMediaElement::setPlayingOnSecondScreen):
     17        (WebCore::HTMLMediaElement::shouldOverrideBackgroundPlaybackRestriction const):
     18        (WebCore::HTMLMediaElement::processingUserGestureForMedia const):
     19        (WebCore::HTMLMediaElement::mediaState const):
     20        (WebCore::HTMLMediaElement::purgeBufferedDataIfPossible):
     21        (WebCore::HTMLMediaElement::shouldOverrideBackgroundLoadingRestriction const):
     22        (WebCore::HTMLMediaElement::webkitCurrentPlaybackTargetIsWireless const): Deleted.
     23        (WebCore::HTMLMediaElement::canPlayToWirelessPlaybackTarget const): Deleted.
     24        (WebCore::HTMLMediaElement::isPlayingToWirelessPlaybackTarget const): Deleted.
     25        * html/HTMLMediaElement.h:
     26        (WebCore::HTMLMediaElement::webkitCurrentPlaybackTargetIsWireless const):
     27        (WebCore::HTMLMediaElement::isPlayingToExternalTarget const):
     28        * html/MediaElementSession.cpp:
     29        (WebCore::MediaElementSession::canPlayToWirelessPlaybackTarget const): Deleted.
     30        * html/MediaElementSession.h:
     31        * platform/audio/PlatformMediaSession.h:
     32        (WebCore::PlatformMediaSessionClient::setWirelessPlaybackTarget):
     33        (WebCore::PlatformMediaSessionClient::isPlayingOnSecondScreen const):
     34        (WebCore::PlatformMediaSession::canPlayToWirelessPlaybackTarget const): Deleted.
     35        (WebCore::PlatformMediaSessionClient::canPlayToWirelessPlaybackTarget const): Deleted.
     36        * platform/cocoa/PlaybackSessionModel.h:
     37        * platform/cocoa/PlaybackSessionModelMediaElement.h:
     38        * platform/cocoa/PlaybackSessionModelMediaElement.mm:
     39        (WebCore::PlaybackSessionModelMediaElement::setPlayingOnSecondScreen):
     40        * platform/ios/WebAVPlayerController.mm:
     41        (-[WebAVPlayerController init]):
     42        (-[WebAVPlayerController dealloc]):
     43        (-[WebAVPlayerController observeValueForKeyPath:ofObject:change:context:]):
     44        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
     45        (VideoFullscreenControllerContext::setPlayingOnSecondScreen):
     46
    1472018-09-06  Frederic Wang  <fwang@igalia.com>
    248
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r235197 r235752  
    57455745}
    57465746
    5747 bool HTMLMediaElement::webkitCurrentPlaybackTargetIsWireless() const
    5748 {
    5749     return m_isPlayingToWirelessTarget;
    5750 }
    5751 
    57525747void HTMLMediaElement::wirelessRoutesAvailableDidChange()
    57535748{
    … …  
    58375832}
    58385833
    5839 bool HTMLMediaElement::canPlayToWirelessPlaybackTarget() const
    5840 {
    5841     bool canPlay = m_player && m_player->canPlayToWirelessPlaybackTarget();
    5842 
    5843     INFO_LOG(LOGIDENTIFIER, "returning ", canPlay);
    5844 
    5845     return canPlay;
    5846 }
    5847 
    5848 bool HTMLMediaElement::isPlayingToWirelessPlaybackTarget() const
    5849 {
    5850     return m_isPlayingToWirelessTarget;
    5851 }
    5852 
    58535834void HTMLMediaElement::setShouldPlayToPlaybackTarget(bool shouldPlay)
    58545835{
    … …  
    58585839        m_player->setShouldPlayToPlaybackTarget(shouldPlay);
    58595840}
    5860 #else // ENABLE(WIRELESS_PLAYBACK_TARGET)
    5861 
    5862 bool HTMLMediaElement::webkitCurrentPlaybackTargetIsWireless() const
    5863 {
    5864     return false;
    5865 }
    58665841
    58675842#endif // ENABLE(WIRELESS_PLAYBACK_TARGET)
     5843
     5844void HTMLMediaElement::setPlayingOnSecondScreen(bool value)
     5845{
     5846    if (value == m_playingOnSecondScreen)
     5847        return;
     5848
     5849    m_playingOnSecondScreen = value;
     5850
     5851#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     5852    updateMediaState(UpdateState::Asynchronously);
     5853#endif
     5854}
    58685855
    58695856double HTMLMediaElement::minFastReverseRate() const
    … …  
    75737560{
    75747561    if (type == PlatformMediaSession::EnteringBackground) {
    7575 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
    7576         if (m_isPlayingToWirelessTarget) {
    7577             INFO_LOG(LOGIDENTIFIER, "returning true because m_isPlayingToWirelessTarget is true");
     7562        if (isPlayingToExternalTarget()) {
     7563            INFO_LOG(LOGIDENTIFIER, "returning true because isPlayingToExternalTarget() is true");
    75787564            return true;
    75797565        }
    7580 #endif
    75817566        if (m_videoFullscreenMode & VideoFullscreenModePictureInPicture)
    75827567            return true;
    … …  
    75867571#endif
    75877572    } else if (type == PlatformMediaSession::SuspendedUnderLock) {
    7588 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
    7589         if (m_isPlayingToWirelessTarget) {
    7590             INFO_LOG(LOGIDENTIFIER, "returning true because m_isPlayingToWirelessTarget is true");
     7573        if (isPlayingToExternalTarget()) {
     7574            INFO_LOG(LOGIDENTIFIER, "returning true because isPlayingToExternalTarget() is true");
    75917575            return true;
    75927576        }
    7593 #endif
    75947577    }
    75957578    return false;
    … …  
    76007583    return document().processingUserGestureForMedia();
    76017584}
    7602 
    76037585#if ENABLE(WIRELESS_PLAYBACK_TARGET)
     7586
    76047587void HTMLMediaElement::updateMediaState(UpdateState updateState)
    76057588{
    … …  
    76297612    bool hasActiveVideo = isVideo() && hasVideo();
    76307613    bool hasAudio = this->hasAudio();
     7614    if (isPlayingToExternalTarget())
     7615        state |= IsPlayingToExternalDevice;
     7616
    76317617#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    7632     if (m_isPlayingToWirelessTarget)
    7633         state |= IsPlayingToExternalDevice;
    7634 
    76357618    if (m_hasPlaybackTargetAvailabilityListeners) {
    76367619        state |= HasPlaybackTargetAvailabilityListener;
    … …  
    77557738        return;
    77567739
    7757     if (m_isPlayingToWirelessTarget) {
     7740    if (isPlayingToExternalTarget()) {
    77587741        INFO_LOG(LOGIDENTIFIER, "early return because playing to wireless target");
    77597742        return;
    … …  
    79347917bool HTMLMediaElement::shouldOverrideBackgroundLoadingRestriction() const
    79357918{
    7936 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
    7937     if (isPlayingToWirelessPlaybackTarget())
     7919    if (isPlayingToExternalTarget())
    79387920        return true;
    7939 #endif
    79407921
    79417922    return m_videoFullscreenMode == VideoFullscreenModePictureInPicture;
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r234501 r235752  
    405405
    406406    void wirelessRoutesAvailableDidChange() override;
    407     bool canPlayToWirelessPlaybackTarget() const override;
    408     bool isPlayingToWirelessPlaybackTarget() const override;
    409407    void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
    410408    void setShouldPlayToPlaybackTarget(bool) override;
    411409#endif
    412     bool webkitCurrentPlaybackTargetIsWireless() const;
     410    bool isPlayingToWirelessPlaybackTarget() const override { return m_isPlayingToWirelessTarget; };
     411    bool webkitCurrentPlaybackTargetIsWireless() const { return m_isPlayingToWirelessTarget; }
     412
     413    void setPlayingOnSecondScreen(bool value);
     414    bool isPlayingOnSecondScreen() const override { return m_playingOnSecondScreen; }
     415
     416    bool isPlayingToExternalTarget() const { return isPlayingToWirelessPlaybackTarget() || isPlayingOnSecondScreen(); }
    413417
    414418    // EventTarget function.
    … …  
    11711175    bool m_hasPlaybackTargetAvailabilityListeners { false };
    11721176    bool m_failedToPlayToWirelessTarget { false };
     1177#endif
     1178
    11731179    bool m_isPlayingToWirelessTarget { false };
    1174 #endif
     1180    bool m_playingOnSecondScreen { false };
    11751181};
    11761182
  • trunk/Source/WebCore/html/MediaElementSession.cpp

    r233485 r235752  
    652652}
    653653
    654 bool MediaElementSession::canPlayToWirelessPlaybackTarget() const
    655 {
    656 #if !PLATFORM(IOS)
    657     if (!m_playbackTarget || !m_playbackTarget->hasActiveRoute())
    658         return false;
    659 #endif
    660 
    661     return client().canPlayToWirelessPlaybackTarget();
    662 }
    663 
    664654bool MediaElementSession::isPlayingToWirelessPlaybackTarget() const
    665655{
  • trunk/Source/WebCore/html/MediaElementSession.h

    r233485 r235752  
    8888    void setHasPlaybackTargetAvailabilityListeners(bool);
    8989
    90     bool canPlayToWirelessPlaybackTarget() const override;
    9190    bool isPlayingToWirelessPlaybackTarget() const override;
    9291
  • trunk/Source/WebCore/platform/audio/PlatformMediaSession.h

    r234703 r235752  
    153153    bool shouldOverrideBackgroundLoadingRestriction() const;
    154154
    155     virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
    156155    virtual bool isPlayingToWirelessPlaybackTarget() const { return m_isPlayingToWirelessPlaybackTarget; }
    157156    void isPlayingToWirelessPlaybackTargetChanged(bool);
    … …  
    241240    virtual void wirelessRoutesAvailableDidChange() { }
    242241    virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) { }
    243     virtual bool canPlayToWirelessPlaybackTarget() const { return false; }
    244242    virtual bool isPlayingToWirelessPlaybackTarget() const { return false; }
    245243    virtual void setShouldPlayToPlaybackTarget(bool) { }
     244
     245    virtual bool isPlayingOnSecondScreen() const { return false; }
    246246
    247247    virtual Document* hostingDocument() const = 0;
  • trunk/Source/WebCore/platform/cocoa/PlaybackSessionModel.h

    r231231 r235752  
    6060    virtual void setMuted(bool) = 0;
    6161    virtual void setVolume(double) = 0;
     62    virtual void setPlayingOnSecondScreen(bool) = 0;
    6263
    6364    enum ExternalPlaybackTargetType { TargetTypeNone, TargetTypeAirPlay, TargetTypeTVOut };
  • trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h

    r231231 r235752  
    7474    WEBCORE_EXPORT void setMuted(bool) final;
    7575    WEBCORE_EXPORT void setVolume(double) final;
     76    WEBCORE_EXPORT void setPlayingOnSecondScreen(bool) final;
    7677
    7778    double duration() const final;
  • trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm

    r234312 r235752  
    326326}
    327327
     328void PlaybackSessionModelMediaElement::setPlayingOnSecondScreen(bool value)
     329{
     330    if (m_mediaElement)
     331        m_mediaElement->setPlayingOnSecondScreen(value);
     332}
     333
    328334void PlaybackSessionModelMediaElement::updateMediaSelectionOptions()
    329335{
  • trunk/Source/WebCore/platform/ios/WebAVPlayerController.mm

    r232187 r235752  
    4949static void * WebAVPlayerControllerSeekableTimeRangesObserverContext = &WebAVPlayerControllerSeekableTimeRangesObserverContext;
    5050static void * WebAVPlayerControllerHasLiveStreamingContentObserverContext = &WebAVPlayerControllerHasLiveStreamingContentObserverContext;
     51static void * WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext = &WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext;
    5152
    5253static double WebAVPlayerControllerLiveStreamSeekableTimeRangeDurationHysteresisDelta = 3.0; // Minimum delta of time required to change the duration of the seekable time range.
    … …  
    7273    [self addObserver:self forKeyPath:@"seekableTimeRanges" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial) context:WebAVPlayerControllerSeekableTimeRangesObserverContext];
    7374    [self addObserver:self forKeyPath:@"hasLiveStreamingContent" options:NSKeyValueObservingOptionInitial context:WebAVPlayerControllerHasLiveStreamingContentObserverContext];
    74 
     75    [self addObserver:self forKeyPath:@"playingOnSecondScreen" options:NSKeyValueObservingOptionNew context:WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext];
    7576
    7677    return self;
    … …  
    8182    [self removeObserver:self forKeyPath:@"seekableTimeRanges" context:WebAVPlayerControllerSeekableTimeRangesObserverContext];
    8283    [self removeObserver:self forKeyPath:@"hasLiveStreamingContent" context:WebAVPlayerControllerHasLiveStreamingContentObserverContext];
     84    [self removeObserver:self forKeyPath:@"playingOnSecondScreen" context:WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext];
    8385
    8486    [_playerControllerProxy release];
    … …  
    554556    } else if (WebAVPlayerControllerHasLiveStreamingContentObserverContext == context)
    555557        [self updateMinMaxTiming];
     558    else if (WebAVPlayerControllerIsPlayingOnSecondScreenObserverContext == context) {
     559        if (auto* delegate = self.delegate)
     560            delegate->setPlayingOnSecondScreen(_playingOnSecondScreen);
     561    }
    556562}
    557563
  • trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm

    r235087 r235752  
    175175    void setMuted(bool) final;
    176176    void setVolume(double) final;
     177    void setPlayingOnSecondScreen(bool) final;
    177178
    178179    // PlaybackSessionModelClient
    … …  
    743744}
    744745
     746void VideoFullscreenControllerContext::setPlayingOnSecondScreen(bool value)
     747{
     748    ASSERT(isUIThread());
     749    WebThreadRun([protectedThis = makeRefPtr(this), this, value] {
     750        if (m_playbackModel)
     751            m_playbackModel->setPlayingOnSecondScreen(value);
     752    });
     753}
     754
    745755void VideoFullscreenControllerContext::beginScrubbing()
    746756{
  • trunk/Source/WebKit/ChangeLog

    r235748 r235752  
     12018-09-06  Jer Noble  <jer.noble@apple.com>
     2
     3        Don't pause playback when locking screen if video is being displayed on second screen.
     4        https://bugs.webkit.org/show_bug.cgi?id=189321
     5
     6        Reviewed by Eric Carlson.
     7
     8        Pass the "isPlayingOnSecondScreen" value across the process boundary.
     9
     10        * UIProcess/Cocoa/PlaybackSessionManagerProxy.h:
     11        * UIProcess/Cocoa/PlaybackSessionManagerProxy.mm:
     12        (WebKit::PlaybackSessionModelContext::setPlayingOnSecondScreen):
     13        (WebKit::PlaybackSessionManagerProxy::setPlayingOnSecondScreen):
     14        * WebProcess/cocoa/PlaybackSessionManager.h:
     15        * WebProcess/cocoa/PlaybackSessionManager.messages.in:
     16        * WebProcess/cocoa/PlaybackSessionManager.mm:
     17        (WebKit::PlaybackSessionManager::setPlayingOnSecondScreen):
     18
    1192018-09-06  Wenson Hsieh  <wenson_hsieh@apple.com>
    220
  • trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h

    r233926 r235752  
    114114    void setMuted(bool) final;
    115115    void setVolume(double) final;
     116    void setPlayingOnSecondScreen(bool) final;
    116117
    117118    double playbackStartedTime() const final { return m_playbackStartedTime; }
    … …  
    232233    void setMuted(uint64_t contextId, bool);
    233234    void setVolume(uint64_t contextId, double);
     235    void setPlayingOnSecondScreen(uint64_t contextId, bool);
    234236
    235237    WebPageProxy* m_page;
  • trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm

    r235265 r235752  
    152152}
    153153
     154void PlaybackSessionModelContext::setPlayingOnSecondScreen(bool value)
     155{
     156    if (m_manager)
     157        m_manager->setPlayingOnSecondScreen(m_contextId, value);
     158}
     159
    154160void PlaybackSessionModelContext::playbackStartedTimeChanged(double playbackStartedTime)
    155161{
    … …  
    572578}
    573579
     580void PlaybackSessionManagerProxy::setPlayingOnSecondScreen(uint64_t contextId, bool value)
     581{
     582    if (m_page)
     583        m_page->send(Messages::PlaybackSessionManager::SetPlayingOnSecondScreen(contextId, value), m_page->pageID());
     584}
     585
    574586void PlaybackSessionManagerProxy::requestControlledElementID()
    575587{
  • trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h

    r232301 r235752  
    163163    void setMuted(uint64_t contextId, bool muted);
    164164    void setVolume(uint64_t contextId, double volume);
     165    void setPlayingOnSecondScreen(uint64_t contextId, bool value);
    165166
    166167    WebPage* m_page;
  • trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.messages.in

    r231231 r235752  
    4141    SetMuted(uint64_t contextId, bool muted)
    4242    SetVolume(uint64_t contextId, double volume)
     43    SetPlayingOnSecondScreen(uint64_t contextId, bool value)
    4344}
    4445#endif
  • trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm

    r235205 r235752  
    508508}
    509509
     510void PlaybackSessionManager::setPlayingOnSecondScreen(uint64_t contextId, bool value)
     511{
     512    UserGestureIndicator indicator(ProcessingUserGesture);
     513    ensureModel(contextId).setPlayingOnSecondScreen(value);
     514}
     515
    510516} // namespace WebKit
    511517
Note: See TracChangeset for help on using the changeset viewer.