Changeset 280920 in webkit


Ignore:
Timestamp:
Aug 11, 2021 11:08:49 AM (11 months ago)
Author:
youenn@apple.com
Message:

Media element is not always autoplaying when going from background to foreground if it is initially not in viewport
https://bugs.webkit.org/show_bug.cgi?id=228955
Source/WebCore:

Reviewed by Eric Carlson.

In case video element is autoplayable but is paused, we should try to autoplay even if we are not interrupted due to invisible autoplay.
Covered by API test.

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::updateShouldAutoplay):

Tools:

rdar://81751653

Reviewed by Eric Carlson.

  • TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r280916 r280920  
     12021-08-11  Youenn Fablet  <youenn@apple.com>
     2
     3        Media element is not always autoplaying when going from background to foreground if it is initially not in viewport
     4        https://bugs.webkit.org/show_bug.cgi?id=228955
     5
     6        Reviewed by Eric Carlson.
     7
     8        In case video element is autoplayable but is paused, we should try to autoplay even if we are not interrupted due to invisible autoplay.
     9        Covered by API test.
     10
     11        * html/HTMLMediaElement.cpp:
     12        (WebCore::HTMLMediaElement::updateShouldAutoplay):
     13
    1142021-08-11  Youenn Fablet  <youenn@apple.com>
    215
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r280881 r280920  
    80938093
    80948094    bool canAutoplay = mediaSession().autoplayPermitted();
    8095     if (canAutoplay
    8096         && mediaSession().state() == PlatformMediaSession::Interrupted
    8097         && mediaSession().interruptionType() == PlatformMediaSession::InvisibleAutoplay)
    8098         mediaSession().endInterruption(PlatformMediaSession::MayResumePlaying);
    8099     else if (!canAutoplay
    8100         && mediaSession().state() != PlatformMediaSession::Interrupted)
     8095
     8096    if (canAutoplay) {
     8097        if (mediaSession().state() == PlatformMediaSession::Interrupted) {
     8098            if (mediaSession().interruptionType() == PlatformMediaSession::InvisibleAutoplay)
     8099                mediaSession().endInterruption(PlatformMediaSession::MayResumePlaying);
     8100        } else if (!isPlaying())
     8101            resumeAutoplaying();
     8102        return;
     8103    }
     8104    if (mediaSession().state() != PlatformMediaSession::Interrupted)
    81018105        mediaSession().beginInterruption(PlatformMediaSession::InvisibleAutoplay);
    81028106}
  • trunk/Tools/ChangeLog

    r280888 r280920  
     12021-08-11  Youenn Fablet  <youenn@apple.com>
     2
     3        Media element is not always autoplaying when going from background to foreground if it is initially not in viewport
     4        https://bugs.webkit.org/show_bug.cgi?id=228955
     5        rdar://81751653
     6
     7        Reviewed by Eric Carlson.
     8
     9        * TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
     10
    1112021-08-11  Lauro Moura  <lmoura@igalia.com>
    212
  • trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm

    r280732 r280920  
    801801#endif // ENABLE(GPU_PROCESS)
    802802
     803#if PLATFORM(MAC)
     804static const char* visibilityTestText = R"DOCDOCDOC(
     805<html><body>
     806<div id='log'></div>
     807<video id='localVideo' autoplay muted playsInline width=160></video>
     808<script>
     809let string = '';
     810onload = () => {
     811    for (let i = 0; i < 1000; ++i)
     812        string += '<br>test';
     813    if (window.internals)
     814        internals.setMediaElementRestrictions(localVideo, "invisibleautoplaynotpermitted");
     815    document.onvisibilitychange = () => window.webkit.messageHandlers.gum.postMessage("PASS");
     816    window.webkit.messageHandlers.gum.postMessage("PASS");
     817}
     818
     819function capture()
     820{
     821    navigator.mediaDevices.getUserMedia({video : true}).then(stream => {
     822        log.innerHTML = string;
     823        localVideo.srcObject = stream;
     824        window.webkit.messageHandlers.gum.postMessage("PASS");
     825    });
     826}
     827
     828async function checkLocalVideoPlaying()
     829{
     830    let counter = 0;
     831    while (++counter < 200) {
     832        if (!localVideo.paused)
     833            return "PASS";
     834        await new Promise(resolve => setTimeout(resolve, 50));
     835    }
     836    return "FAIL";
     837}
     838
     839function doTest()
     840{
     841    log.innerHTML = '';
     842    checkLocalVideoPlaying().then(result => {
     843        window.webkit.messageHandlers.gum.postMessage(result);
     844    });
     845}
     846
     847</script>
     848</body></html>
     849)DOCDOCDOC";
     850
     851TEST(WebKit, AutoplayOnVisibilityChange)
     852{
     853    TestWebKitAPI::HTTPServer server({
     854        { "/", { visibilityTestText } }
     855    }, TestWebKitAPI::HTTPServer::Protocol::Http, nullptr, nullptr, 9090);
     856
     857    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     858
     859    auto context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
     860    configuration.get().processPool = (WKProcessPool *)context.get();
     861
     862    auto messageHandler = adoptNS([[GUMMessageHandler alloc] init]);
     863    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"gum"];
     864
     865    auto preferences = [configuration preferences];
     866    preferences._mediaCaptureRequiresSecureConnection = NO;
     867    configuration.get()._mediaCaptureEnabled = YES;
     868    preferences._mockCaptureDevicesEnabled = YES;
     869
     870    done = false;
     871    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
     872
     873    auto delegate = adoptNS([[UserMediaCaptureUIDelegate alloc] init]);
     874    webView.get().UIDelegate = delegate.get();
     875
     876    [webView loadRequest:server.request()];
     877    TestWebKitAPI::Util::run(&done);
     878
     879    done = false;
     880    auto *hostWindow = [webView hostWindow];
     881    [hostWindow miniaturize:hostWindow];
     882    TestWebKitAPI::Util::run(&done);
     883
     884    done = false;
     885    [webView stringByEvaluatingJavaScript:@"capture()"];
     886    TestWebKitAPI::Util::run(&done);
     887
     888    done = false;
     889    [hostWindow deminiaturize:hostWindow];
     890    TestWebKitAPI::Util::run(&done);
     891
     892    done = false;
     893    [webView stringByEvaluatingJavaScript:@"doTest()"];
     894    TestWebKitAPI::Util::run(&done);
     895}
     896#endif // PLATFORM(MAC)
     897
    803898} // namespace TestWebKitAPI
    804899
Note: See TracChangeset for help on using the changeset viewer.