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

Changeset 245887 in webkit


Ignore:
Timestamp:
May 30, 2019, 9:29:38 AM (7 years ago)
Author:
jer.noble@apple.com
Message:

Video playback in Safari should continue when CarPlay is plugged in
https://bugs.webkit.org/show_bug.cgi?id=198345
<rdar://problem/45505750>

Reviewed by Eric Carlson.

Source/WebCore:

Test: media/video-isplayingtoautomotiveheadunit.html

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::shouldOverrideBackgroundPlaybackRestriction const):

  • platform/audio/PlatformMediaSessionManager.cpp:

(WebCore::PlatformMediaSessionManager::setIsPlayingToAutomotiveHeadUnit):

  • platform/audio/PlatformMediaSessionManager.h:

(WebCore::PlatformMediaSessionManager::isPlayingToAutomotiveHeadUnit const):

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

(WebCore::MediaSessionManageriOS::MediaSessionManageriOS):
(WebCore::MediaSessionManageriOS::carPlayServerDied):
(WebCore::MediaSessionManageriOS::updateCarPlayIsConnected):
(-[WebMediaSessionHelper initWithCallback:]):
(-[WebMediaSessionHelper startMonitoringAirPlayRoutes]):
(-[WebMediaSessionHelper interruption:]):
(-[WebMediaSessionHelper applicationWillEnterForeground:]):
(-[WebMediaSessionHelper applicationDidBecomeActive:]):
(-[WebMediaSessionHelper applicationWillResignActive:]):
(-[WebMediaSessionHelper wirelessRoutesAvailableDidChange:]):
(-[WebMediaSessionHelper applicationDidEnterBackground:]):
(-[WebMediaSessionHelper carPlayServerDied:]):
(-[WebMediaSessionHelper carPlayIsConnectedDidChange:]):

  • testing/Internals.cpp:

(WebCore::Internals::resetToConsistentState):
(WebCore::Internals::setIsPlayingToAutomotiveHeadUnit):

  • testing/Internals.h:
  • testing/Internals.idl:

LayoutTests:

  • media/video-isplayingtoautomotiveheadunit-expected.txt: Added.
  • media/video-isplayingtoautomotiveheadunit.html: Added.
Location:
trunk
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r245877 r245887  
     12019-05-30  Jer Noble  <jer.noble@apple.com>
     2
     3        Video playback in Safari should continue when CarPlay is plugged in
     4        https://bugs.webkit.org/show_bug.cgi?id=198345
     5        <rdar://problem/45505750>
     6
     7        Reviewed by Eric Carlson.
     8
     9        * media/video-isplayingtoautomotiveheadunit-expected.txt: Added.
     10        * media/video-isplayingtoautomotiveheadunit.html: Added.
     11
    1122019-05-29  Said Abou-Hallawa  <sabouhallawa@apple.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r245883 r245887  
     12019-05-30  Jer Noble  <jer.noble@apple.com>
     2
     3        Video playback in Safari should continue when CarPlay is plugged in
     4        https://bugs.webkit.org/show_bug.cgi?id=198345
     5        <rdar://problem/45505750>
     6
     7        Reviewed by Eric Carlson.
     8
     9        Test: media/video-isplayingtoautomotiveheadunit.html
     10
     11        * html/HTMLMediaElement.cpp:
     12        (WebCore::HTMLMediaElement::shouldOverrideBackgroundPlaybackRestriction const):
     13        * platform/audio/PlatformMediaSessionManager.cpp:
     14        (WebCore::PlatformMediaSessionManager::setIsPlayingToAutomotiveHeadUnit):
     15        * platform/audio/PlatformMediaSessionManager.h:
     16        (WebCore::PlatformMediaSessionManager::isPlayingToAutomotiveHeadUnit const):
     17        * platform/audio/ios/MediaSessionManagerIOS.h:
     18        * platform/audio/ios/MediaSessionManagerIOS.mm:
     19        (WebCore::MediaSessionManageriOS::MediaSessionManageriOS):
     20        (WebCore::MediaSessionManageriOS::carPlayServerDied):
     21        (WebCore::MediaSessionManageriOS::updateCarPlayIsConnected):
     22        (-[WebMediaSessionHelper initWithCallback:]):
     23        (-[WebMediaSessionHelper startMonitoringAirPlayRoutes]):
     24        (-[WebMediaSessionHelper interruption:]):
     25        (-[WebMediaSessionHelper applicationWillEnterForeground:]):
     26        (-[WebMediaSessionHelper applicationDidBecomeActive:]):
     27        (-[WebMediaSessionHelper applicationWillResignActive:]):
     28        (-[WebMediaSessionHelper wirelessRoutesAvailableDidChange:]):
     29        (-[WebMediaSessionHelper applicationDidEnterBackground:]):
     30        (-[WebMediaSessionHelper carPlayServerDied:]):
     31        (-[WebMediaSessionHelper carPlayIsConnectedDidChange:]):
     32        * testing/Internals.cpp:
     33        (WebCore::Internals::resetToConsistentState):
     34        (WebCore::Internals::setIsPlayingToAutomotiveHeadUnit):
     35        * testing/Internals.h:
     36        * testing/Internals.idl:
     37
    1382019-05-29  Robin Morisset  <rmorisset@apple.com>
    239
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r245712 r245887  
    77167716            return true;
    77177717        }
     7718        if (PlatformMediaSessionManager::sharedManager().isPlayingToAutomotiveHeadUnit()) {
     7719            INFO_LOG(LOGIDENTIFIER, "returning true because isPlayingToAutomotiveHeadUnit() is true");
     7720            return true;
     7721        }
    77187722        if (m_videoFullscreenMode & VideoFullscreenModePictureInPicture)
    77197723            return true;
     
    77257729        if (isPlayingToExternalTarget()) {
    77267730            INFO_LOG(LOGIDENTIFIER, "returning true because isPlayingToExternalTarget() is true");
     7731            return true;
     7732        }
     7733        if (PlatformMediaSessionManager::sharedManager().isPlayingToAutomotiveHeadUnit()) {
     7734            INFO_LOG(LOGIDENTIFIER, "returning true because isPlayingToAutomotiveHeadUnit() is true");
    77277735            return true;
    77287736        }
  • trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp

    r245773 r245887  
    392392}
    393393
     394void PlatformMediaSessionManager::setIsPlayingToAutomotiveHeadUnit(bool isPlayingToAutomotiveHeadUnit)
     395{
     396    if (isPlayingToAutomotiveHeadUnit == m_isPlayingToAutomotiveHeadUnit)
     397        return;
     398
     399    ALWAYS_LOG(LOGIDENTIFIER, isPlayingToAutomotiveHeadUnit);
     400    m_isPlayingToAutomotiveHeadUnit = isPlayingToAutomotiveHeadUnit;
     401}
    394402
    395403void PlatformMediaSessionManager::sessionIsPlayingToWirelessPlaybackTargetChanged(PlatformMediaSession& session)
  • trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h

    r245712 r245887  
    130130    void sessionIsPlayingToWirelessPlaybackTargetChanged(PlatformMediaSession&);
    131131
     132    WEBCORE_EXPORT void setIsPlayingToAutomotiveHeadUnit(bool);
     133    bool isPlayingToAutomotiveHeadUnit() const { return m_isPlayingToAutomotiveHeadUnit; }
     134
    132135    void forEachMatchingSession(const Function<bool(const PlatformMediaSession&)>& predicate, const Function<void(PlatformMediaSession&)>& matchingCallback);
    133136
     
    189192    bool m_willIgnoreSystemInterruptions { false };
    190193    bool m_processIsSuspended { false };
     194    bool m_isPlayingToAutomotiveHeadUnit { false };
    191195
    192196#if USE(AUDIO_SESSION)
  • trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.h

    r242901 r245887  
    4848    void externalOutputDeviceAvailableDidChange();
    4949    bool hasWirelessTargetsAvailable() override;
     50    void carPlayServerDied();
     51    void updateCarPlayIsConnected(Optional<bool>&&);
    5052
    5153private:
  • trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm

    r245712 r245887  
    5757SOFT_LINK_CLASS_OPTIONAL(Celestial, AVSystemController)
    5858SOFT_LINK_CONSTANT_MAY_FAIL(Celestial, AVSystemController_PIDToInheritApplicationStateFrom, NSString *)
     59SOFT_LINK_CONSTANT_MAY_FAIL(Celestial, AVSystemController_CarPlayIsConnectedAttribute, NSString *)
     60SOFT_LINK_CONSTANT_MAY_FAIL(Celestial, AVSystemController_CarPlayIsConnectedDidChangeNotification, NSString *)
     61SOFT_LINK_CONSTANT_MAY_FAIL(Celestial, AVSystemController_CarPlayIsConnectedNotificationParameter, NSString *)
     62SOFT_LINK_CONSTANT_MAY_FAIL(Celestial, AVSystemController_ServerConnectionDiedNotification, NSString *)
    5963#endif
    6064
     
    110114    END_BLOCK_OBJC_EXCEPTIONS
    111115    resetRestrictions();
     116
     117    updateCarPlayIsConnected(WTF::nullopt);
    112118}
    113119
     
    193199
    194200    END_BLOCK_OBJC_EXCEPTIONS
     201}
     202
     203void MediaSessionManageriOS::carPlayServerDied()
     204{
     205    ALWAYS_LOG(LOGIDENTIFIER);
     206    updateCarPlayIsConnected(WTF::nullopt);
     207}
     208
     209void MediaSessionManageriOS::updateCarPlayIsConnected(Optional<bool>&& carPlayIsConnected)
     210{
     211    if (carPlayIsConnected) {
     212        setIsPlayingToAutomotiveHeadUnit(carPlayIsConnected.value());
     213        return;
     214    }
     215
     216    if (!canLoadAVSystemController_CarPlayIsConnectedAttribute()) {
     217        setIsPlayingToAutomotiveHeadUnit(false)
     218        return;
     219    }
     220
     221    setIsPlayingToAutomotiveHeadUnit([[[getAVSystemControllerClass() sharedAVSystemController] attributeForKey:getAVSystemController_CarPlayIsConnectedAttribute()] boolValue]);
    195222}
    196223
     
    219246    [center addObserver:self selector:@selector(applicationDidEnterBackground:) name:PAL::get_UIKit_UIApplicationDidEnterBackgroundNotification() object:nil];
    220247    [center addObserver:self selector:@selector(applicationDidEnterBackground:) name:WebUIApplicationDidEnterBackgroundNotification object:nil];
     248    if (canLoadAVSystemController_ServerConnectionDiedNotification())
     249        [center addObserver:self selector:@selector(carPlayServerDied:) name:getAVSystemController_ServerConnectionDiedNotification() object:nil];
     250    if (canLoadAVSystemController_CarPlayIsConnectedDidChangeNotification())
     251        [center addObserver:self selector:@selector(carPlayIsConnectedDidChange:) name:getAVSystemController_CarPlayIsConnectedDidChangeNotification() object:nil];
    221252
    222253    // Now playing won't work unless we turn on the delivery of remote control events.
     
    287318    LOG(Media, "-[WebMediaSessionHelper startMonitoringAirPlayRoutes]");
    288319
    289     callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = WTFMove(self)]() mutable {
     320    callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = retainPtr(self)]() mutable {
    290321        ASSERT(!protectedSelf->_routeDetector);
    291322
     
    294325            protectedSelf->_routeDetector = adoptNS([PAL::allocAVRouteDetectorInstance() init]);
    295326            protectedSelf->_routeDetector.get().routeDetectionEnabled = protectedSelf->_monitoringAirPlayRoutes;
    296             [[NSNotificationCenter defaultCenter] addObserver:protectedSelf selector:@selector(wirelessRoutesAvailableDidChange:) name:AVRouteDetectorMultipleRoutesDetectedDidChangeNotification object:protectedSelf->_routeDetector.get()];
     327            [[NSNotificationCenter defaultCenter] addObserver:protectedSelf.get() selector:@selector(wirelessRoutesAvailableDidChange:) name:AVRouteDetectorMultipleRoutesDetectedDidChangeNotification object:protectedSelf->_routeDetector.get()];
    297328
    298329            protectedSelf->_callback->externalOutputDeviceAvailableDidChange();
     
    329360        flags = PlatformMediaSession::MayResumePlaying;
    330361
    331     callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = WTFMove(self), type, flags]() mutable {
     362    callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = retainPtr(self), type, flags]() mutable {
    332363        auto* callback = protectedSelf->_callback;
    333364        if (!callback)
     
    352383
    353384    BOOL isSuspendedUnderLock = [[[notification userInfo] objectForKey:@"isSuspendedUnderLock"] boolValue];
    354     callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = WTFMove(self), isSuspendedUnderLock]() mutable {
     385    callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = retainPtr(self), isSuspendedUnderLock]() mutable {
    355386        if (auto* callback = protectedSelf->_callback)
    356387            callback->applicationWillEnterForeground(isSuspendedUnderLock);
     
    367398    LOG(Media, "-[WebMediaSessionHelper applicationDidBecomeActive]");
    368399
    369     callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = WTFMove(self)]() mutable {
     400    callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = retainPtr(self)]() mutable {
    370401        if (auto* callback = protectedSelf->_callback)
    371402            callback->applicationDidBecomeActive();
     
    382413    LOG(Media, "-[WebMediaSessionHelper applicationWillResignActive]");
    383414
    384     callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = WTFMove(self)]() mutable {
     415    callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = retainPtr(self)]() mutable {
    385416        if (auto* callback = protectedSelf->_callback)
    386417            callback->applicationWillBecomeInactive();
     
    397428    LOG(Media, "-[WebMediaSessionHelper wirelessRoutesAvailableDidChange]");
    398429
    399     callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = WTFMove(self)]() mutable {
     430    callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = retainPtr(self)]() mutable {
    400431        if (auto* callback = protectedSelf->_callback)
    401432            callback->externalOutputDeviceAvailableDidChange();
     
    411442
    412443    BOOL isSuspendedUnderLock = [[[notification userInfo] objectForKey:@"isSuspendedUnderLock"] boolValue];
    413     callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = WTFMove(self), isSuspendedUnderLock]() mutable {
     444    callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = retainPtr(self), isSuspendedUnderLock]() mutable {
    414445        if (auto* callback = protectedSelf->_callback)
    415446            callback->applicationDidEnterBackground(isSuspendedUnderLock);
    416447    });
    417448}
     449
     450- (void)carPlayServerDied:(NSNotification *)notification
     451{
     452    if (!_callback)
     453        return;
     454
     455    LOG(Media, "-[WebMediaSessionHelper carPlayServerDied:]");
     456    UNUSED_PARAM(notification);
     457    callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = retainPtr(self)]() mutable {
     458        if (auto* callback = protectedSelf->_callback)
     459            callback->carPlayServerDied();
     460    });
     461}
     462
     463- (void)carPlayIsConnectedDidChange:(NSNotification *)notification
     464{
     465    if (!_callback)
     466        return;
     467
     468    Optional<bool> carPlayIsConnected;
     469    if (notification && canLoadAVSystemController_CarPlayIsConnectedNotificationParameter()) {
     470        NSNumber *nsCarPlayIsConnected = [[notification userInfo] valueForKey:getAVSystemController_CarPlayIsConnectedNotificationParameter()];
     471        if (nsCarPlayIsConnected)
     472            carPlayIsConnected = [nsCarPlayIsConnected boolValue];
     473    }
     474
     475    callOnWebThreadOrDispatchAsyncOnMainThread([protectedSelf = retainPtr(self), carPlayIsConnected = WTFMove(carPlayIsConnected)]() mutable {
     476        if (auto* callback = protectedSelf->_callback)
     477            callback->updateCarPlayIsConnected(WTFMove(carPlayIsConnected));
     478    });
     479}
    418480@end
    419481
  • trunk/Source/WebCore/testing/Internals.cpp

    r245716 r245887  
    493493    PlatformMediaSessionManager::sharedManager().setWillIgnoreSystemInterruptions(true);
    494494#endif
     495    PlatformMediaSessionManager::sharedManager().setIsPlayingToAutomotiveHeadUnit(false);
    495496#if HAVE(ACCESSIBILITY)
    496497    AXObjectCache::setEnhancedUserInterfaceAccessibility(false);
     
    50685069}
    50695070
     5071void Internals::setIsPlayingToAutomotiveHeadUnit(bool isPlaying)
     5072{
     5073    PlatformMediaSessionManager::sharedManager().setIsPlayingToAutomotiveHeadUnit(isPlaying);
     5074}
     5075
    50705076} // namespace WebCore
  • trunk/Source/WebCore/testing/Internals.h

    r245366 r245887  
    824824    void setXHRMaximumIntervalForUserGestureForwarding(XMLHttpRequest&, double);
    825825
     826    void setIsPlayingToAutomotiveHeadUnit(bool);
     827
    826828private:
    827829    explicit Internals(Document&);
  • trunk/Source/WebCore/testing/Internals.idl

    r245366 r245887  
    754754
    755755    void setXHRMaximumIntervalForUserGestureForwarding(XMLHttpRequest xhr, double interval);
    756 };
     756
     757    void setIsPlayingToAutomotiveHeadUnit(boolean value);
     758};
Note: See TracChangeset for help on using the changeset viewer.