Changeset 190434 in webkit


Ignore:
Timestamp:
Oct 1, 2015 3:32:56 PM (9 years ago)
Author:
Brent Fulgham
Message:

[iOS] AirPlay should not stop when the screen locks
https://bugs.webkit.org/show_bug.cgi?id=148315
<rdar://problem/22770703>

Patch by Eric Carlson <eric.carlson@apple.com> on 2015-10-01
Reviewed by Jer Noble.

Source/WebCore:

Tested by media/video-interruption-with-resume-allowing-play.html

media/video-interruption-with-resume-not-allowing-play.html

  • Modules/webaudio/AudioContext.h: overrideBackgroundPlaybackRestriction -> shouldOverrideBackgroundPlaybackRestriction.
  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::suspendPlayback): Fix a typo in the logging.
(WebCore::HTMLMediaElement::mayResumePlayback): Ditto.
(WebCore::HTMLMediaElement::shouldOverrideBackgroundPlaybackRestriction): Renamed from

overrideBackgroundPlaybackRestriction.

(WebCore::HTMLMediaElement::overrideBackgroundPlaybackRestriction): Deleted.

  • html/HTMLMediaElement.h:
  • platform/audio/PlatformMediaSession.cpp:

(WebCore::stateName):
(WebCore::interruptionName): New, log the name of the interruption.
(WebCore::PlatformMediaSession::beginInterruption): Log the interruption type. Don't

increment the interruption counter if we are going to ignore it. Incorporate logic
from doInterruption.

(WebCore::PlatformMediaSession::doInterruption): Deleted.
(WebCore::PlatformMediaSession::shouldDoInterruption): Deleted.
(WebCore::PlatformMediaSession::forceInterruption): Deleted.

  • platform/audio/PlatformMediaSession.h: Add SuspendedUnderLock interruption type.
  • platform/audio/PlatformMediaSessionManager.cpp:

(WebCore::PlatformMediaSessionManager::applicationDidEnterBackground): Deleted.

  • platform/audio/PlatformMediaSessionManager.h:
  • platform/audio/ios/MediaSessionManagerIOS.h:
  • platform/audio/ios/MediaSessionManagerIOS.mm:

(WebCore::MediaSessionManageriOS::applicationDidEnterBackground): Call beginInterruption

when appropriate.

LayoutTests:

  • media/video-interruption-with-resume-allowing-play.html:
  • media/video-interruption-with-resume-not-allowing-play.html:
Location:
trunk
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r190430 r190434  
     12015-10-01  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [iOS] AirPlay should not stop when the screen locks
     4        https://bugs.webkit.org/show_bug.cgi?id=148315
     5        <rdar://problem/22770703>
     6
     7        Reviewed by Jer Noble.
     8
     9        * media/video-interruption-with-resume-allowing-play.html:
     10        * media/video-interruption-with-resume-not-allowing-play.html:
     11
    1122015-10-01  Ryosuke Niwa  <rniwa@webkit.org>
    213
  • trunk/LayoutTests/media/video-interruption-with-resume-allowing-play-expected.txt

    r179869 r190434  
    77EVENT(playing)
    88EXPECTED (video.paused == 'false') OK
    9 RUN(internals.beginMediaSessionInterruption())
     9RUN(internals.beginMediaSessionInterruption('System'))
    1010
    1111100ms timer fired...
     
    1717
    1818EXPECTED (video.paused == 'false') OK
    19 RUN(internals.beginMediaSessionInterruption())
     19RUN(internals.beginMediaSessionInterruption('System'))
    2020
    2121100ms timer fired...
  • trunk/LayoutTests/media/video-interruption-with-resume-allowing-play.html

    r179869 r190434  
    1313                    testExpected("video.paused", false);
    1414                    state = "interrupted";
    15                     run("internals.beginMediaSessionInterruption()");;
     15                    run("internals.beginMediaSessionInterruption('System')");;
    1616                    setTimeout(checkState, 100);
    1717                    consoleWrite("");
  • trunk/LayoutTests/media/video-interruption-with-resume-not-allowing-play-expected.txt

    r163390 r190434  
    66
    77EVENT(playing)
    8 RUN(internals.beginMediaSessionInterruption())
     8RUN(internals.beginMediaSessionInterruption('System'))
    99
    1010100ms timer fired...
  • trunk/LayoutTests/media/video-interruption-with-resume-not-allowing-play.html

    r163390 r190434  
    88            function playing()
    99            {
    10                 run("internals.beginMediaSessionInterruption()");;
     10                run("internals.beginMediaSessionInterruption('System')");;
    1111                setTimeout(checkState, 100);
    1212            }
  • trunk/Source/WebCore/ChangeLog

    r190430 r190434  
     12015-10-01  Eric Carlson  <eric.carlson@apple.com>
     2
     3        [iOS] AirPlay should not stop when the screen locks
     4        https://bugs.webkit.org/show_bug.cgi?id=148315
     5        <rdar://problem/22770703>
     6
     7        Reviewed by Jer Noble.
     8
     9        Tested by media/video-interruption-with-resume-allowing-play.html
     10                  media/video-interruption-with-resume-not-allowing-play.html
     11
     12        * Modules/webaudio/AudioContext.h: overrideBackgroundPlaybackRestriction ->
     13          shouldOverrideBackgroundPlaybackRestriction.
     14
     15        * html/HTMLMediaElement.cpp:
     16        (WebCore::HTMLMediaElement::suspendPlayback): Fix a typo in the logging.
     17        (WebCore::HTMLMediaElement::mayResumePlayback): Ditto.
     18        (WebCore::HTMLMediaElement::shouldOverrideBackgroundPlaybackRestriction): Renamed from
     19          overrideBackgroundPlaybackRestriction.
     20        (WebCore::HTMLMediaElement::overrideBackgroundPlaybackRestriction): Deleted.
     21        * html/HTMLMediaElement.h:
     22
     23        * platform/audio/PlatformMediaSession.cpp:
     24        (WebCore::stateName):
     25        (WebCore::interruptionName): New, log the name of the interruption.
     26        (WebCore::PlatformMediaSession::beginInterruption): Log the interruption type. Don't
     27          increment the interruption counter if we are going to ignore it. Incorporate logic
     28          from doInterruption.
     29        (WebCore::PlatformMediaSession::doInterruption): Deleted.
     30        (WebCore::PlatformMediaSession::shouldDoInterruption): Deleted.
     31        (WebCore::PlatformMediaSession::forceInterruption): Deleted.
     32
     33        * platform/audio/PlatformMediaSession.h: Add SuspendedUnderLock interruption type.
     34        * platform/audio/PlatformMediaSessionManager.cpp:
     35        (WebCore::PlatformMediaSessionManager::applicationDidEnterBackground): Deleted.
     36        * platform/audio/PlatformMediaSessionManager.h:
     37
     38        * platform/audio/ios/MediaSessionManagerIOS.h:
     39        * platform/audio/ios/MediaSessionManagerIOS.mm:
     40        (WebCore::MediaSessionManageriOS::applicationDidEnterBackground): Call beginInterruption
     41          when appropriate.
     42
    1432015-10-01  Ryosuke Niwa  <rniwa@webkit.org>
    244
  • trunk/Source/WebCore/Modules/webaudio/AudioContext.h

    r188594 r190434  
    323323    virtual bool canReceiveRemoteControlCommands() const override { return false; }
    324324    virtual void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType) override { }
    325     virtual bool overrideBackgroundPlaybackRestriction() const override { return false; }
     325    bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override { return false; }
    326326
    327327    // EventTarget
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r190020 r190434  
    63766376void HTMLMediaElement::suspendPlayback()
    63776377{
    6378     LOG(Media, "HTMLMediaElement::pausePlayback(%p) - paused = %s", this, boolString(paused()));
     6378    LOG(Media, "HTMLMediaElement::suspendPlayback(%p) - paused = %s", this, boolString(paused()));
    63796379    if (!paused())
    63806380        pause();
     
    63836383void HTMLMediaElement::mayResumePlayback(bool shouldResume)
    63846384{
    6385     LOG(Media, "HTMLMediaElement::resumePlayback(%p) - paused = %s", this, boolString(paused()));
     6385    LOG(Media, "HTMLMediaElement::mayResumePlayback(%p) - paused = %s", this, boolString(paused()));
    63866386    if (paused() && shouldResume)
    63876387        play();
     
    64256425}
    64266426
    6427 bool HTMLMediaElement::overrideBackgroundPlaybackRestriction() const
    6428 {
     6427bool HTMLMediaElement::shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType type) const
     6428{
     6429    if (type != PlatformMediaSession::EnteringBackground)
     6430        return false;
     6431
    64296432#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    64306433    if (m_player && m_player->isCurrentPlaybackTargetWireless())
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r189841 r190434  
    736736    virtual bool canReceiveRemoteControlCommands() const override { return true; }
    737737    virtual void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType) override;
    738     virtual bool overrideBackgroundPlaybackRestriction() const override;
     738    bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override;
    739739
    740740    virtual void pageMutedStateDidChange() override;
  • trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp

    r189322 r190434  
    4040static const char* stateName(PlatformMediaSession::State state)
    4141{
    42 #define CASE(state) case PlatformMediaSession::state: return #state
     42#define STATE_CASE(state) case PlatformMediaSession::state: return #state
    4343    switch (state) {
    44     CASE(Idle);
    45     CASE(Playing);
    46     CASE(Paused);
    47     CASE(Interrupted);
    48     }
    49 
     44    STATE_CASE(Idle);
     45    STATE_CASE(Playing);
     46    STATE_CASE(Paused);
     47    STATE_CASE(Interrupted);
     48    }
     49
     50    ASSERT_NOT_REACHED();
     51    return "";
     52}
     53
     54static const char* interruptionName(PlatformMediaSession::InterruptionType type)
     55{
     56#define INTERRUPTION_CASE(type) case PlatformMediaSession::type: return #type
     57    switch (type) {
     58    INTERRUPTION_CASE(SystemSleep);
     59    INTERRUPTION_CASE(EnteringBackground);
     60    INTERRUPTION_CASE(SystemInterruption);
     61    INTERRUPTION_CASE(SuspendedUnderLock);
     62    }
     63   
    5064    ASSERT_NOT_REACHED();
    5165    return "";
     
    8094}
    8195
    82 void PlatformMediaSession::doInterruption()
    83 {
     96void PlatformMediaSession::beginInterruption(InterruptionType type)
     97{
     98    LOG(Media, "PlatformMediaSession::beginInterruption(%p), state = %s, interruption type = %s, interruption count = %i", this, stateName(m_state), interruptionName(type), m_interruptionCount);
     99
     100    if (++m_interruptionCount > 1)
     101        return;
     102
     103    if (client().shouldOverrideBackgroundPlaybackRestriction(type))
     104        return;
     105
    84106    m_stateToRestore = state();
    85107    m_notifyingClient = true;
     
    87109    client().suspendPlayback();
    88110    m_notifyingClient = false;
    89 }
    90 
    91 bool PlatformMediaSession::shouldDoInterruption(InterruptionType type)
    92 {
    93     return type != EnteringBackground || !client().overrideBackgroundPlaybackRestriction();
    94 }
    95 
    96 void PlatformMediaSession::beginInterruption(InterruptionType type)
    97 {
    98     LOG(Media, "PlatformMediaSession::beginInterruption(%p), state = %s, interruption count = %i", this, stateName(m_state), m_interruptionCount);
    99 
    100     if (++m_interruptionCount > 1 || !shouldDoInterruption(type))
    101         return;
    102 
    103     doInterruption();
    104 }
    105 
    106 void PlatformMediaSession::forceInterruption(InterruptionType type)
    107 {
    108     LOG(Media, "PlatformMediaSession::forceInterruption(%p), state = %s, interruption count = %i", this, stateName(m_state), m_interruptionCount);
    109 
    110     // beginInterruption() must have been called before calling this function.
    111     if (!m_interruptionCount) {
    112         ASSERT_NOT_REACHED();
    113         return;
    114     }
    115 
    116     // The purpose of this function is to override the decision which was made by
    117     // beginInterruption(). If it was decided to interrupt the media session there,
    118     // then nothing should be done here.
    119     if (shouldDoInterruption(type))
    120         return;
    121 
    122     doInterruption();
    123111}
    124112
  • trunk/Source/WebCore/platform/audio/PlatformMediaSession.h

    r189322 r190434  
    7575        EnteringBackground,
    7676        SystemInterruption,
     77        SuspendedUnderLock,
    7778    };
    7879    enum EndInterruptionFlags {
     
    8182    };
    8283
    83     void doInterruption();
    84     bool shouldDoInterruption(InterruptionType);
    8584    void beginInterruption(InterruptionType);
    86     void forceInterruption(InterruptionType);
    8785    void endInterruption(EndInterruptionFlags);
    8886
     
    180178    virtual bool elementIsHidden() const { return false; }
    181179
    182     virtual bool overrideBackgroundPlaybackRestriction() const = 0;
     180    virtual bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const = 0;
    183181
    184182    virtual void wirelessRoutesAvailableDidChange() { }
  • trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp

    r189322 r190434  
    289289}
    290290
    291 void PlatformMediaSessionManager::applicationDidEnterBackground(bool isSuspendedUnderLock) const
    292 {
    293     LOG(Media, "PlatformMediaSessionManager::applicationDidEnterBackground");
    294 
    295     if (!isSuspendedUnderLock)
    296         return;
    297 
    298     Vector<PlatformMediaSession*> sessions = m_sessions;
    299     for (auto* session : sessions) {
    300         if (m_restrictions[session->mediaType()] & BackgroundProcessPlaybackRestricted)
    301             session->forceInterruption(PlatformMediaSession::EnteringBackground);
    302     }
    303 }
    304 
    305291void PlatformMediaSessionManager::applicationWillEnterForeground() const
    306292{
     
    324310        return;
    325311
    326     if (session.state() != PlatformMediaSession::Interrupted && session.shouldDoInterruption(PlatformMediaSession::EnteringBackground))
    327         session.doInterruption();
     312    if (session.state() != PlatformMediaSession::Interrupted)
     313        session.beginInterruption(PlatformMediaSession::EnteringBackground);
    328314}
    329315
  • trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h

    r189369 r190434  
    6161    WEBCORE_EXPORT void applicationWillEnterForeground() const;
    6262    WEBCORE_EXPORT void applicationWillEnterBackground() const;
    63     WEBCORE_EXPORT void applicationDidEnterBackground(bool isSuspendedUnderLock) const;
    6463
    6564    void stopAllMediaPlaybackForDocument(const Document*);
  • trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h

    r187522 r190434  
    4949    void externalOutputDeviceAvailableDidChange();
    5050    virtual bool hasWirelessTargetsAvailable() override;
     51    void applicationDidEnterBackground(bool isSuspendedUnderLock);
    5152
    5253private:
  • trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm

    r189369 r190434  
    249249}
    250250
     251void MediaSessionManageriOS::applicationDidEnterBackground(bool isSuspendedUnderLock)
     252{
     253    LOG(Media, "MediaSessionManageriOS::applicationDidEnterBackground");
     254
     255    if (!isSuspendedUnderLock)
     256        return;
     257
     258    Vector<PlatformMediaSession*> sessions = this->sessions();
     259    for (auto* session : sessions) {
     260        if (restrictions(session->mediaType()) & BackgroundProcessPlaybackRestricted)
     261            session->beginInterruption(PlatformMediaSession::SuspendedUnderLock);
     262    }
     263}
     264
     265
    251266} // namespace WebCore
    252267
  • trunk/Source/WebCore/testing/Internals.cpp

    r190363 r190434  
    27032703
    27042704#if ENABLE(VIDEO)
    2705 void Internals::beginMediaSessionInterruption()
    2706 {
     2705void Internals::beginMediaSessionInterruption(const String& interruptionString, ExceptionCode& ec)
     2706{
     2707    PlatformMediaSession::InterruptionType interruption = PlatformMediaSession::SystemInterruption;
     2708
     2709    if (equalIgnoringCase(interruptionString, "System"))
     2710        interruption = PlatformMediaSession::SystemInterruption;
     2711    else if (equalIgnoringCase(interruptionString, "SystemSleep"))
     2712        interruption = PlatformMediaSession::SystemSleep;
     2713    else if (equalIgnoringCase(interruptionString, "EnteringBackground"))
     2714        interruption = PlatformMediaSession::EnteringBackground;
     2715    else {
     2716        ec = INVALID_ACCESS_ERR;
     2717        return;
     2718    }
     2719
    27072720    PlatformMediaSessionManager::sharedManager().beginInterruption(PlatformMediaSession::SystemInterruption);
    27082721}
  • trunk/Source/WebCore/testing/Internals.h

    r190363 r190434  
    387387
    388388#if ENABLE(VIDEO)
    389     void beginMediaSessionInterruption();
     389    void beginMediaSessionInterruption(const String&, ExceptionCode&);
    390390    void endMediaSessionInterruption(const String&);
    391391    void applicationWillEnterForeground() const;
  • trunk/Source/WebCore/testing/Internals.idl

    r190363 r190434  
    366366    [Conditional=MEDIA_SOURCE] void setShouldGenerateTimestamps(SourceBuffer buffer, boolean flag);
    367367
    368     [Conditional=VIDEO] void beginMediaSessionInterruption();
     368    [Conditional=VIDEO, RaisesException] void beginMediaSessionInterruption(DOMString interruptionType);
    369369    [Conditional=VIDEO] void endMediaSessionInterruption(DOMString flags);
    370370    [Conditional=MEDIA_SESSION] void sendMediaSessionStartOfInterruptionNotification(MediaSessionInterruptingCategory category);
Note: See TracChangeset for help on using the changeset viewer.