/* * Copyright (C) 2019 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #import "config.h" #import "PlatformUtilities.h" #import "TestWKWebView.h" #import "WKWebViewConfigurationExtras.h" #import #import #import #import // We can enable the test for old iOS versions after is fixed. #if ENABLE(VIDEO_PRESENTATION_MODE) && (PLATFORM(MAC) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 140000)) static void loadPictureInPicture(RetainPtr webView) { [webView synchronouslyLoadHTMLString:@""]; [[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"WebCoreLogging": @"", @"WebKit2Logging": @"", }]; [webView objectByEvaluatingJavaScript:@"document.querySelector('video').addEventListener('webkitpresentationmodechanged', event => { window.webkit.messageHandlers.testHandler.postMessage('presentationmodechanged'); });"]; __block bool presentationModeChanged = false; [webView performAfterReceivingMessage:@"presentationmodechanged" action:^{ presentationModeChanged = true; }]; [webView objectByEvaluatingJavaScriptWithUserGesture:@"document.querySelector('video').webkitSetPresentationMode('picture-in-picture')"]; ASSERT_UNUSED(presentationModeChanged, TestWebKitAPI::Util::runFor(&presentationModeChanged, 10)); do { if (![webView stringByEvaluatingJavaScript:@"window.internals.isChangingPresentationMode(document.querySelector('video'))"].boolValue) break; TestWebKitAPI::Util::sleep(0.5); } while (true); } TEST(WKWebViewCloseAllMediaPresentations, PictureInPicture) { if (!WebCore::supportsPictureInPicture()) return; [[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"WebCoreLogging": @"Fullscreen=debug", @"WebKit2Logging": @"Fullscreen=debug", }]; auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES]; [[configuration preferences] _setAllowsPictureInPictureMediaPlayback:YES]; auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration addToWindow:YES]); loadPictureInPicture(webView); static bool isDone = false; [webView closeAllMediaPresentationsWithCompletionHandler:^{ isDone = true; }]; TestWebKitAPI::Util::run(&isDone); EXPECT_TRUE([webView _allMediaPresentationsClosed]); } TEST(WKWebViewCloseAllMediaPresentationsInternal, PictureInPicture) { if (!WebCore::supportsPictureInPicture()) return; [[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"WebCoreLogging": @"Fullscreen=debug", @"WebKit2Logging": @"Fullscreen=debug", }]; auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES]; [[configuration preferences] _setAllowsPictureInPictureMediaPlayback:YES]; auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration addToWindow:YES]); loadPictureInPicture(webView); [webView _closeAllMediaPresentations]; do { if (![webView stringByEvaluatingJavaScript:@"window.internals.isChangingPresentationMode(document.querySelector('video'))"].boolValue) break; TestWebKitAPI::Util::sleep(0.5); } while (true); EXPECT_TRUE([webView _allMediaPresentationsClosed]); } #endif #if ENABLE(FULLSCREEN_API) TEST(WKWebViewCloseAllMediaPresentations, VideoFullscreen) { auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES]; [[configuration preferences] _setFullScreenEnabled:YES]; auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration addToWindow:YES]); [webView synchronouslyLoadHTMLString:@""]; [webView objectByEvaluatingJavaScript:@"document.querySelector('video').addEventListener('webkitpresentationmodechanged', event => { window.webkit.messageHandlers.testHandler.postMessage('presentationmodechanged'); });"]; __block bool presentationModeChanged = false; [webView performAfterReceivingMessage:@"presentationmodechanged" action:^{ presentationModeChanged = true; }]; [webView objectByEvaluatingJavaScriptWithUserGesture:@"document.querySelector('video').webkitEnterFullscreen()"]; [webView objectByEvaluatingJavaScript:@"window.internals.setMockVideoPresentationModeEnabled(true)"]; TestWebKitAPI::Util::run(&presentationModeChanged); do { if (![webView stringByEvaluatingJavaScript:@"window.internals.isChangingPresentationMode(document.querySelector('video'))"].boolValue) break; TestWebKitAPI::Util::sleep(0.5); } while (true); static bool isDone = false; [webView closeAllMediaPresentationsWithCompletionHandler:^{ isDone = true; }]; TestWebKitAPI::Util::run(&isDone); EXPECT_TRUE([webView _allMediaPresentationsClosed]); } TEST(WKWebViewCloseAllMediaPresentations, ElementFullscreen) { auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES]; [[configuration preferences] _setFullScreenEnabled:YES]; auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration addToWindow:YES]); [webView synchronouslyLoadHTMLString:@"
"]; [webView objectByEvaluatingJavaScript:@"document.querySelector('#target').addEventListener('webkitfullscreenchange', event => { window.webkit.messageHandlers.testHandler.postMessage('fullscreenchange'); });"]; __block bool fullscreenModeChanged = false; [webView performAfterReceivingMessage:@"fullscreenchange" action:^{ fullscreenModeChanged = true; }]; [webView objectByEvaluatingJavaScriptWithUserGesture:@"document.querySelector('#target').webkitRequestFullscreen()"]; TestWebKitAPI::Util::run(&fullscreenModeChanged); fullscreenModeChanged = false; [webView performAfterReceivingMessage:@"fullscreenchange" action:^{ fullscreenModeChanged = true; }]; static bool isDone = false; [webView closeAllMediaPresentationsWithCompletionHandler:^{ isDone = true; }]; TestWebKitAPI::Util::run(&isDone); EXPECT_TRUE([webView _allMediaPresentationsClosed]); } TEST(WKWebViewCloseAllMediaPresentations, MultipleSequentialCloseAllMediaPresentations) { if (!WebCore::supportsPictureInPicture()) return; [[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"WebCoreLogging": @"Fullscreen=debug", @"WebKit2Logging": @"Fullscreen=debug", }]; auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES]; [[configuration preferences] _setAllowsPictureInPictureMediaPlayback:YES]; auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration addToWindow:YES]); loadPictureInPicture(webView); static bool firstIsDone = false; [webView closeAllMediaPresentationsWithCompletionHandler:^{ firstIsDone = true; }]; static bool secondIsDone = false; [webView closeAllMediaPresentationsWithCompletionHandler:^{ secondIsDone = true; }]; TestWebKitAPI::Util::run(&firstIsDone); TestWebKitAPI::Util::run(&secondIsDone); EXPECT_TRUE([webView _allMediaPresentationsClosed]); } TEST(WKWebViewCloseAllMediaPresentations, RemovedCloseAllMediaPresentationAPIs) { // In r271970, we renamed -closeAllMediaPresentations to -closeAllMediaPresentations:completionHandler, which broke // binary compatability of apps linked against older SDKs. Ensure calling the removed API does not crash. auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES]; auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration addToWindow:YES]); EXPECT_TRUE([webView respondsToSelector:@selector(closeAllMediaPresentations)]); RetainPtr exception; @try { [webView closeAllMediaPresentations]; } @catch(NSException *caught) { exception = caught; } EXPECT_FALSE(exception); } #endif