Changeset 203690 in webkit


Ignore:
Timestamp:
Jul 25, 2016 10:49:17 AM (8 years ago)
Author:
Wenson Hsieh
Message:

Media controls on apple.com don't disappear when movie finishes playing
https://bugs.webkit.org/show_bug.cgi?id=160068
<rdar://problem/26668526>

Reviewed by Darin Adler.

Source/WebCore:

When a video ends, it should cause media controls to hide. While current logic
mostly accounts for this, it does not account for programmatic seeks causing
the video to lose its 'ended' status before querying for whether or not to
show media controls.

Three new API tests: large-video-seek-after-ending.html
large-video-hides-controls-after-seek-to-end.html
large-video-seek-to-beginning-and-play-after-ending.html

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
(WebCore::HTMLMediaElement::setPlaying):

  • html/MediaElementSession.cpp:

(WebCore::MediaElementSession::canControlControlsManager):

  • html/MediaElementSession.h:

Tools:

Adds new API tests. Please see WebCore ChangeLog for more details.

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm:

(-[MediaPlaybackMessageHandler initWithWKWebView:finalMessageString:]):
(-[MediaPlaybackMessageHandler userContentController:didReceiveScriptMessage:]):
(TestWebKitAPI::TEST):
(-[DidPlayMessageHandler initWithWKWebView:]): Deleted.
(-[DidPlayMessageHandler userContentController:didReceiveScriptMessage:]): Deleted.

  • TestWebKitAPI/Tests/WebKit2Cocoa/large-video-hides-controls-after-seek-to-end.html: Added.
  • TestWebKitAPI/Tests/WebKit2Cocoa/large-video-seek-after-ending.html: Added.
  • TestWebKitAPI/Tests/WebKit2Cocoa/large-video-seek-to-beginning-and-play-after-ending.html: Added.
Location:
trunk
Files:
3 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r203688 r203690  
     12016-07-25  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Media controls on apple.com don't disappear when movie finishes playing
     4        https://bugs.webkit.org/show_bug.cgi?id=160068
     5        <rdar://problem/26668526>
     6
     7        Reviewed by Darin Adler.
     8
     9        When a video ends, it should cause media controls to hide. While current logic
     10        mostly accounts for this, it does not account for programmatic seeks causing
     11        the video to lose its 'ended' status before querying for whether or not to
     12        show media controls.
     13
     14        Three new API tests: large-video-seek-after-ending.html
     15        large-video-hides-controls-after-seek-to-end.html
     16        large-video-seek-to-beginning-and-play-after-ending.html
     17
     18        * html/HTMLMediaElement.cpp:
     19        (WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
     20        (WebCore::HTMLMediaElement::setPlaying):
     21        * html/MediaElementSession.cpp:
     22        (WebCore::MediaElementSession::canControlControlsManager):
     23        * html/MediaElementSession.h:
     24
    1252016-07-25  Frederic Wang  <fwang@igalia.com>
    226
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r203473 r203690  
    44124412                m_sentEndEvent = true;
    44134413                scheduleEvent(eventNames().endedEvent);
     4414                m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureToControlControlsManager | MediaElementSession::RequirePlaybackToControlControlsManager);
    44144415            }
    44154416            // If the media element has a current media controller, then report the controller state
     
    44324433                m_sentEndEvent = true;
    44334434                scheduleEvent(eventNames().endedEvent);
     4435                m_mediaSession->addBehaviorRestriction(MediaElementSession::RequireUserGestureToControlControlsManager | MediaElementSession::RequirePlaybackToControlControlsManager);
    44344436                m_paused = true;
    44354437                setPlaying(false);
     
    49374939void HTMLMediaElement::setPlaying(bool playing)
    49384940{
     4941    if (playing && m_mediaSession)
     4942        m_mediaSession->removeBehaviorRestriction(MediaElementSession::RequirePlaybackToControlControlsManager);
     4943
    49394944    if (m_playing == playing)
    49404945        return;
  • trunk/Source/WebCore/html/MediaElementSession.cpp

    r203629 r203690  
    244244    }
    245245
     246    if (hasBehaviorRestriction(RequirePlaybackToControlControlsManager) && !m_element.isPlaying()) {
     247        LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: Needs to be playing");
     248        return false;
     249    }
     250
    246251    if (m_element.muted()) {
    247252        LOG(Media, "MediaElementSession::canControlControlsManager - returning FALSE: Muted");
  • trunk/Source/WebCore/html/MediaElementSession.h

    r202425 r203690  
    9696        OverrideUserGestureRequirementForMainContent = 1 << 12,
    9797        RequireUserGestureToControlControlsManager = 1 << 13,
     98        RequirePlaybackToControlControlsManager = 1 << 14,
    9899        AllRestrictions = ~NoRestrictions,
    99100    };
  • trunk/Tools/ChangeLog

    r203685 r203690  
     12016-07-25  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Media controls on apple.com don't disappear when movie finishes playing
     4        https://bugs.webkit.org/show_bug.cgi?id=160068
     5        <rdar://problem/26668526>
     6
     7        Reviewed by Darin Adler.
     8
     9        Adds new API tests. Please see WebCore ChangeLog for more details.
     10
     11        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     12        * TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm:
     13        (-[MediaPlaybackMessageHandler initWithWKWebView:finalMessageString:]):
     14        (-[MediaPlaybackMessageHandler userContentController:didReceiveScriptMessage:]):
     15        (TestWebKitAPI::TEST):
     16        (-[DidPlayMessageHandler initWithWKWebView:]): Deleted.
     17        (-[DidPlayMessageHandler userContentController:didReceiveScriptMessage:]): Deleted.
     18        * TestWebKitAPI/Tests/WebKit2Cocoa/large-video-hides-controls-after-seek-to-end.html: Added.
     19        * TestWebKitAPI/Tests/WebKit2Cocoa/large-video-seek-after-ending.html: Added.
     20        * TestWebKitAPI/Tests/WebKit2Cocoa/large-video-seek-to-beginning-and-play-after-ending.html: Added.
     21
    1222016-07-25  Philippe Normand  <pnormand@igalia.com>
    223
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r203622 r203690  
    5454                2DD7D3AF178227B30026E1E3 /* lots-of-text-vertical-lr.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */; };
    5555                2E14A5291D3FE96B0010F35B /* autoplaying-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */; };
     56                2E1B7B001D41ABA7007558B4 /* large-video-seek-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */; };
     57                2E1B7B021D41B1B9007558B4 /* large-video-hides-controls-after-seek-to-end.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */; };
     58                2E1DFDF11D42E1E400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */; };
    5659                2E7765CD16C4D80A00BA2BB1 /* mainIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */; };
    5760                2E7765CF16C4D81100BA2BB1 /* mainMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2E7765CE16C4D81100BA2BB1 /* mainMac.mm */; };
     
    499502                        files = (
    500503                                515BE16F1D428BB100DD7C68 /* StoreBlobToBeDeleted.html in Copy Resources */,
     504                                2E1DFDF11D42E1E400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html in Copy Resources */,
     505                                2E1B7B021D41B1B9007558B4 /* large-video-hides-controls-after-seek-to-end.html in Copy Resources */,
     506                                2E1B7B001D41ABA7007558B4 /* large-video-seek-after-ending.html in Copy Resources */,
    501507                                5C9E59411D3EB5AC00E3C62E /* ApplicationCache.db in Copy Resources */,
    502508                                5C9E59421D3EB5AC00E3C62E /* ApplicationCache.db-shm in Copy Resources */,
     
    699705                2DD7D3AE178227AC0026E1E3 /* lots-of-text-vertical-lr.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "lots-of-text-vertical-lr.html"; sourceTree = "<group>"; };
    700706                2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autoplaying-video-with-audio.html"; sourceTree = "<group>"; };
     707                2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-seek-after-ending.html"; sourceTree = "<group>"; };
     708                2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-hides-controls-after-seek-to-end.html"; sourceTree = "<group>"; };
     709                2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-seek-to-beginning-and-play-after-ending.html"; sourceTree = "<group>"; };
    701710                2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = mainIOS.mm; sourceTree = "<group>"; };
    702711                2E7765CE16C4D81100BA2BB1 /* mainMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = mainMac.mm; sourceTree = "<group>"; };
     
    13361345                        isa = PBXGroup;
    13371346                        children = (
     1347                                2E1DFDF01D42E14400714A00 /* large-video-seek-to-beginning-and-play-after-ending.html */,
     1348                                2E1B7B011D41B1B3007558B4 /* large-video-hides-controls-after-seek-to-end.html */,
    13381349                                5C9E593E1D3EB1DE00E3C62E /* ApplicationCache.db */,
    13391350                                5C9E593F1D3EB1DE00E3C62E /* ApplicationCache.db-shm */,
     
    13701381                                51714EB21CF8C761004723C4 /* WebProcessKillIDBCleanup-1.html */,
    13711382                                51714EB31CF8C761004723C4 /* WebProcessKillIDBCleanup-2.html */,
     1383                                2E1B7AFF1D41A95F007558B4 /* large-video-seek-after-ending.html */,
    13721384                        );
    13731385                        name = Resources;
  • trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/VideoControlsManager.mm

    r203629 r203690  
    5555@end
    5656
    57 @interface DidPlayMessageHandler : NSObject <WKScriptMessageHandler> {
     57@interface MediaPlaybackMessageHandler : NSObject <WKScriptMessageHandler> {
    5858    RetainPtr<WKWebView> _webView;
    5959}
    6060
    6161@property (nonatomic) BOOL expectedToHaveControlsManager;
    62 
    63 - (instancetype)initWithWKWebView:(WKWebView*)webView;
    64 @end
    65 
    66 @implementation DidPlayMessageHandler
    67 
    68 - (instancetype)initWithWKWebView:(WKWebView*)webView
     62@property (nonatomic, retain) NSString *finalMessageString;
     63
     64- (instancetype)initWithWKWebView:(WKWebView*)webView finalMessageString:(NSString *)finalMessageString;
     65@end
     66
     67@implementation MediaPlaybackMessageHandler
     68
     69- (instancetype)initWithWKWebView:(WKWebView*)webView finalMessageString:(NSString *)finalMessageString
    6970{
    7071    if (!(self = [super init]))
     
    7273
    7374    _webView = webView;
     75    _finalMessageString = finalMessageString;
    7476
    7577    return self;
     
    8183
    8284    NSString *bodyString = (NSString *)[message body];
    83     if ([bodyString isEqualToString:@"playing"] || [bodyString isEqualToString:@"paused"]) {
     85    if ([bodyString isEqualToString:self.finalMessageString]) {
    8486        BOOL hasControlsManager = [_webView _hasActiveVideoForControlsManager];
    8587        if (self.expectedToHaveControlsManager)
     
    133135    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
    134136    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
    135     RetainPtr<DidPlayMessageHandler> handler = adoptNS([[DidPlayMessageHandler alloc] initWithWKWebView:webView.get()]);
     137    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"playing"]);
    136138    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
    137139
     
    154156    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
    155157    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
    156     RetainPtr<DidPlayMessageHandler> handler = adoptNS([[DidPlayMessageHandler alloc] initWithWKWebView:webView.get()]);
     158    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"playing"]);
    157159    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
    158160
     
    175177    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
    176178    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
    177     RetainPtr<DidPlayMessageHandler> playbackHandler = adoptNS([[DidPlayMessageHandler alloc] initWithWKWebView:webView.get()]);
     179    RetainPtr<MediaPlaybackMessageHandler> playbackHandler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"paused"]);
    178180    [[configuration userContentController] addScriptMessageHandler:playbackHandler.get() name:@"playingHandler"];
    179181
     
    195197}
    196198
     199TEST(VideoControlsManager, VideoControlsManagerLargeAutoplayingVideoSeeksAfterEnding)
     200{
     201    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     202    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
     203    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
     204    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"ended"]);
     205    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
     206
     207    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
     208    [[window contentView] addSubview:webView.get()];
     209
     210    // Since the video has ended, the expectation is NO even if the page programmatically seeks to the beginning.
     211    [handler setExpectedToHaveControlsManager:NO];
     212    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"large-video-seek-after-ending" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
     213    [webView loadRequest:request];
     214
     215    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
     216    TestWebKitAPI::Util::run(&receivedScriptMessage);
     217}
     218
     219TEST(VideoControlsManager, VideoControlsManagerLargeAutoplayingVideoSeeksAndPlaysAfterEnding)
     220{
     221    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     222    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
     223    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
     224    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"replaying"]);
     225    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
     226
     227    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
     228    [[window contentView] addSubview:webView.get()];
     229
     230    // Since the video is still playing, the expectation is YES even if the video has ended once.
     231    [handler setExpectedToHaveControlsManager:YES];
     232    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"large-video-seek-to-beginning-and-play-after-ending" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
     233    [webView loadRequest:request];
     234
     235    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
     236    TestWebKitAPI::Util::run(&receivedScriptMessage);
     237}
     238
     239TEST(VideoControlsManager, VideoControlsManagerLargeAutoplayingVideoHidesControlsAfterSeekingToEnd)
     240{
     241    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     242    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
     243    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
     244    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"ended"]);
     245    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
     246
     247    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]);
     248    [[window contentView] addSubview:webView.get()];
     249
     250    RetainPtr<OnLoadMessageHandler> onloadHandler = adoptNS([[OnLoadMessageHandler alloc] initWithWKWebView:webView.get() handler:^() {
     251        [webView mouseDownAtPoint:NSMakePoint(50, 50)];
     252    }]);
     253    [[configuration userContentController] addScriptMessageHandler:onloadHandler.get() name:@"onloadHandler"];
     254
     255    // Since the video has ended, the expectation is NO.
     256    [handler setExpectedToHaveControlsManager:NO];
     257    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"large-video-hides-controls-after-seek-to-end" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
     258    [webView loadRequest:request];
     259
     260    TestWebKitAPI::Util::run(&testedControlsManagerAfterPlaying);
     261    TestWebKitAPI::Util::run(&receivedScriptMessage);
     262}
     263
    197264TEST(VideoControlsManager, VideoControlsManagerSingleLargeVideoWithoutAudio)
    198265{
     
    200267    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
    201268    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
    202     RetainPtr<DidPlayMessageHandler> handler = adoptNS([[DidPlayMessageHandler alloc] initWithWKWebView:webView.get()]);
     269    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"playing"]);
    203270    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
    204271
     
    221288    configuration.get().mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
    222289    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) configuration:configuration.get()]);
    223     RetainPtr<DidPlayMessageHandler> handler = adoptNS([[DidPlayMessageHandler alloc] initWithWKWebView:webView.get()]);
     290    RetainPtr<MediaPlaybackMessageHandler> handler = adoptNS([[MediaPlaybackMessageHandler alloc] initWithWKWebView:webView.get() finalMessageString:@"playing"]);
    224291    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"playingHandler"];
    225292
Note: See TracChangeset for help on using the changeset viewer.