Diff
Modified: trunk/Source/WebCore/ChangeLog (217446 => 217447)
--- trunk/Source/WebCore/ChangeLog 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Source/WebCore/ChangeLog 2017-05-25 21:05:26 UTC (rev 217447)
@@ -1,3 +1,37 @@
+2017-05-25 Jer Noble <jer.no...@apple.com>
+
+ System sleeps while playing to wireless target, ending stream.
+ https://bugs.webkit.org/show_bug.cgi?id=172541
+
+ Reviewed by Eric Carlson.
+
+ API test: Tests/mac/MediaPlaybackSleepAssertion.mm
+
+ Keep the system from sleeping (but allow the display to sleep) while playing media to a wireless target.
+
+ Give the SleepDisabler a Type, either System or Display, which indicates what kind of sleep to disable.
+ Update HTMLMediaElement::shouldDisableSleep() to differentiate between a video which is playing locally,
+ one that is playing but not visible, and one that is playing remotely.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged):
+ (WebCore::HTMLMediaElement::updateSleepDisabling):
+ (WebCore::HTMLMediaElement::shouldDisableSleep):
+ * html/HTMLMediaElement.h:
+ * platform/SleepDisabler.cpp:
+ (WebCore::SleepDisabler::create):
+ (WebCore::SleepDisabler::SleepDisabler):
+ * platform/SleepDisabler.h:
+ (WebCore::SleepDisabler::type):
+ * platform/cocoa/SleepDisablerCocoa.cpp:
+ (WebCore::SleepDisabler::create):
+ (WebCore::SleepDisablerCocoa::SleepDisablerCocoa):
+ (WebCore::SleepDisablerCocoa::~SleepDisablerCocoa):
+ * platform/cocoa/SleepDisablerCocoa.h:
+ * platform/mac/WebVideoFullscreenController.mm:
+ (-[WebVideoFullscreenController updatePowerAssertions]):
+ * platform/spi/cocoa/IOPMLibSPI.h:
+
2017-05-25 Chris Dumez <cdu...@apple.com>
DocumentThreadableLoader::redirectReceived() should not rely on the resource's loader
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (217446 => 217447)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2017-05-25 21:05:26 UTC (rev 217447)
@@ -5422,6 +5422,7 @@
m_mediaSession->isPlayingToWirelessPlaybackTargetChanged(m_isPlayingToWirelessTarget);
m_mediaSession->canProduceAudioChanged();
updateMediaState(UpdateState::Asynchronously);
+ updateSleepDisabling();
}
bool HTMLMediaElement::dispatchEvent(Event& event)
@@ -6347,26 +6348,40 @@
void HTMLMediaElement::updateSleepDisabling()
{
- bool shouldDisableSleep = this->shouldDisableSleep();
- if (!shouldDisableSleep && m_sleepDisabler)
+ SleepType shouldDisableSleep = this->shouldDisableSleep();
+ if (shouldDisableSleep == SleepType::None && m_sleepDisabler)
m_sleepDisabler = nullptr;
- else if (shouldDisableSleep && !m_sleepDisabler)
- m_sleepDisabler = SleepDisabler::create("com.apple.WebCore: HTMLMediaElement playback");
+ else if (shouldDisableSleep != SleepType::None) {
+ auto type = shouldDisableSleep == SleepType::Display ? SleepDisabler::Type::Display : SleepDisabler::Type::System;
+ if (!m_sleepDisabler || m_sleepDisabler->type() != type)
+ m_sleepDisabler = SleepDisabler::create("com.apple.WebCore: HTMLMediaElement playback", type);
+ }
if (m_player)
- m_player->setShouldDisableSleep(shouldDisableSleep);
+ m_player->setShouldDisableSleep(shouldDisableSleep == SleepType::Display);
}
-bool HTMLMediaElement::shouldDisableSleep() const
+HTMLMediaElement::SleepType HTMLMediaElement::shouldDisableSleep() const
{
#if !PLATFORM(COCOA)
- return false;
+ return SleepType::None;
#endif
+ if (!m_player || m_player->paused() || loop())
+ return SleepType::None;
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ // If the media is playing remotely, we can't know definitively whether it has audio or video tracks.
+ if (m_isPlayingToWirelessTarget)
+ return SleepType::System;
+#endif
+
+ if (!hasVideo() || !hasAudio())
+ return SleepType::None;
+
if (m_elementIsHidden)
- return false;
+ return SleepType::System;
- return m_player && !m_player->paused() && hasVideo() && hasAudio() && !loop();
+ return SleepType::Display;
}
String HTMLMediaElement::mediaPlayerReferrer() const
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (217446 => 217447)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2017-05-25 21:05:26 UTC (rev 217447)
@@ -679,7 +679,7 @@
double mediaPlayerRequestedPlaybackRate() const final;
VideoFullscreenMode mediaPlayerFullscreenMode() const final { return fullscreenMode(); }
- bool mediaPlayerShouldDisableSleep() const final { return shouldDisableSleep(); }
+ bool mediaPlayerShouldDisableSleep() const final { return shouldDisableSleep() == SleepType::Display; }
#if USE(GSTREAMER)
void requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback&) final;
@@ -791,7 +791,12 @@
bool isLiveStream() const override { return movieLoadType() == MediaPlayerEnums::LiveStream; }
void updateSleepDisabling();
- bool shouldDisableSleep() const;
+ enum class SleepType {
+ None,
+ Display,
+ System,
+ };
+ SleepType shouldDisableSleep() const;
#if ENABLE(MEDIA_CONTROLS_SCRIPT)
void didAddUserAgentShadowRoot(ShadowRoot*) override;
Modified: trunk/Source/WebCore/platform/SleepDisabler.cpp (217446 => 217447)
--- trunk/Source/WebCore/platform/SleepDisabler.cpp 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Source/WebCore/platform/SleepDisabler.cpp 2017-05-25 21:05:26 UTC (rev 217447)
@@ -29,13 +29,14 @@
namespace WebCore {
#if !PLATFORM(COCOA)
-std::unique_ptr<SleepDisabler> SleepDisabler::create(const char* reason)
+std::unique_ptr<SleepDisabler> SleepDisabler::create(const char* reason, Type type)
{
- return std::unique_ptr<SleepDisabler>(new SleepDisabler(reason));
+ return std::unique_ptr<SleepDisabler>(new SleepDisabler(reason, type));
}
#endif // !PLATFORM(COCOA)
-SleepDisabler::SleepDisabler(const char*)
+SleepDisabler::SleepDisabler(const char*, Type type)
+ : m_type(type)
{
}
Modified: trunk/Source/WebCore/platform/SleepDisabler.h (217446 => 217447)
--- trunk/Source/WebCore/platform/SleepDisabler.h 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Source/WebCore/platform/SleepDisabler.h 2017-05-25 21:05:26 UTC (rev 217447)
@@ -29,11 +29,18 @@
class SleepDisabler {
public:
- static std::unique_ptr<SleepDisabler> create(const char*);
+ enum class Type {
+ System,
+ Display,
+ };
+ static std::unique_ptr<SleepDisabler> create(const char*, Type);
WEBCORE_EXPORT virtual ~SleepDisabler();
+ Type type() const { return m_type; }
+
protected:
- WEBCORE_EXPORT SleepDisabler(const char*);
+ WEBCORE_EXPORT SleepDisabler(const char*, Type);
+ Type m_type;
};
}
Modified: trunk/Source/WebCore/platform/cocoa/SleepDisablerCocoa.cpp (217446 => 217447)
--- trunk/Source/WebCore/platform/cocoa/SleepDisablerCocoa.cpp 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Source/WebCore/platform/cocoa/SleepDisablerCocoa.cpp 2017-05-25 21:05:26 UTC (rev 217447)
@@ -33,22 +33,36 @@
namespace WebCore {
-std::unique_ptr<SleepDisabler> SleepDisabler::create(const char* reason)
+std::unique_ptr<SleepDisabler> SleepDisabler::create(const char* reason, Type type)
{
- return std::unique_ptr<SleepDisabler>(new SleepDisablerCocoa(reason));
+ return std::unique_ptr<SleepDisabler>(new SleepDisablerCocoa(reason, type));
}
-SleepDisablerCocoa::SleepDisablerCocoa(const char* reason)
- : SleepDisabler(reason)
- , m_disableDisplaySleepAssertion(0)
+SleepDisablerCocoa::SleepDisablerCocoa(const char* reason, Type type)
+ : SleepDisabler(reason, type)
+ , m_sleepAssertion(0)
{
RetainPtr<CFStringRef> reasonCF = adoptCF(CFStringCreateWithCString(kCFAllocatorDefault, reason, kCFStringEncodingUTF8));
- IOPMAssertionCreateWithDescription(kIOPMAssertionTypePreventUserIdleDisplaySleep, reasonCF.get(), nullptr, nullptr, nullptr, 0, nullptr, &m_disableDisplaySleepAssertion);
+
+ CFStringRef assertionType;
+ switch (type) {
+ case Type::Display:
+ assertionType = kIOPMAssertionTypePreventUserIdleDisplaySleep;
+ break;
+ case Type::System:
+ assertionType = kIOPMAssertionTypePreventUserIdleSystemSleep;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ assertionType = nullptr;
+ break;
+ }
+ IOPMAssertionCreateWithDescription(assertionType, reasonCF.get(), nullptr, nullptr, nullptr, 0, nullptr, &m_sleepAssertion);
}
SleepDisablerCocoa::~SleepDisablerCocoa()
{
- IOPMAssertionRelease(m_disableDisplaySleepAssertion);
+ IOPMAssertionRelease(m_sleepAssertion);
}
}
Modified: trunk/Source/WebCore/platform/cocoa/SleepDisablerCocoa.h (217446 => 217447)
--- trunk/Source/WebCore/platform/cocoa/SleepDisablerCocoa.h 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Source/WebCore/platform/cocoa/SleepDisablerCocoa.h 2017-05-25 21:05:26 UTC (rev 217447)
@@ -33,11 +33,11 @@
class SleepDisablerCocoa : public SleepDisabler {
public:
- SleepDisablerCocoa(const char*);
+ SleepDisablerCocoa(const char*, Type);
virtual ~SleepDisablerCocoa();
private:
- uint32_t m_disableDisplaySleepAssertion;
+ uint32_t m_sleepAssertion;
};
}
Modified: trunk/Source/WebCore/platform/mac/WebVideoFullscreenController.mm (217446 => 217447)
--- trunk/Source/WebCore/platform/mac/WebVideoFullscreenController.mm 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Source/WebCore/platform/mac/WebVideoFullscreenController.mm 2017-05-25 21:05:26 UTC (rev 217447)
@@ -362,7 +362,7 @@
if (rate && !_isEndingFullscreen) {
if (!_displaySleepDisabler)
- _displaySleepDisabler = SleepDisabler::create("com.apple.WebCore - Fullscreen video");
+ _displaySleepDisabler = SleepDisabler::create("com.apple.WebCore - Fullscreen video", SleepDisabler::Type::Display);
} else
#endif
_displaySleepDisabler = nullptr;
Modified: trunk/Source/WebCore/platform/spi/cocoa/IOPMLibSPI.h (217446 => 217447)
--- trunk/Source/WebCore/platform/spi/cocoa/IOPMLibSPI.h 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Source/WebCore/platform/spi/cocoa/IOPMLibSPI.h 2017-05-25 21:05:26 UTC (rev 217447)
@@ -41,6 +41,7 @@
WTF_EXTERN_C_BEGIN
const CFStringRef kIOPMAssertionTypePreventUserIdleDisplaySleep = CFSTR("PreventUserIdleDisplaySleep");
+const CFStringRef kIOPMAssertionTypePreventUserIdleSystemSleep = CFSTR("PreventUserIdleSystemSleep");
WTF_EXTERN_C_END
Modified: trunk/Tools/ChangeLog (217446 => 217447)
--- trunk/Tools/ChangeLog 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Tools/ChangeLog 2017-05-25 21:05:26 UTC (rev 217447)
@@ -1,3 +1,19 @@
+2017-05-25 Jer Noble <jer.no...@apple.com>
+
+ System sleeps while playing to wireless target, ending stream.
+ https://bugs.webkit.org/show_bug.cgi?id=172541
+
+ Reviewed by Eric Carlson.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/mac/MediaPlaybackSleepAssertion.html: Added.
+ * TestWebKitAPI/Tests/mac/MediaPlaybackSleepAssertion.mm: Added.
+ (-[MediaPlaybackSleepAssertionLoadDelegate webView:didCreateJavaScriptContext:forFrame:]):
+ (-[MediaPlaybackSleepAssertionPolicyDelegate webView:decidePolicyForNavigationAction:request:frame:decisionListener:]):
+ (TestWebKitAPI::simulateKeyDown):
+ (TestWebKitAPI::hasAssertionType):
+ (TestWebKitAPI::TEST):
+
2017-05-25 Commit Queue <commit-qu...@webkit.org>
Unreviewed, rolling out r217423 and r217424.
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (217446 => 217447)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-05-25 20:58:34 UTC (rev 217446)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-05-25 21:05:26 UTC (rev 217447)
@@ -583,6 +583,9 @@
CD78E11D1DB7EA660014A2DE /* FullscreenDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD78E11A1DB7EA360014A2DE /* FullscreenDelegate.mm */; };
CD78E11E1DB7EE2A0014A2DE /* FullscreenDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD78E11B1DB7EA360014A2DE /* FullscreenDelegate.html */; };
CD9E292E1C90C33F000BB800 /* audio-only.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD9E292D1C90C1BA000BB800 /* audio-only.html */; };
+ CDA315981ED53651009F60D3 /* MediaPlaybackSleepAssertion.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDA315961ED53651009F60D3 /* MediaPlaybackSleepAssertion.mm */; };
+ CDA3159A1ED548F1009F60D3 /* MediaPlaybackSleepAssertion.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDA315991ED540A5009F60D3 /* MediaPlaybackSleepAssertion.html */; };
+ CDA3159D1ED5643F009F60D3 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDA3159C1ED5643F009F60D3 /* IOKit.framework */; };
CDB4115A1E0B00DB00EAD352 /* video-with-muted-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDB411591E09DA8E00EAD352 /* video-with-muted-audio.html */; };
CDBFCC451A9FF45300A7B691 /* FullscreenZoomInitialFrame.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDBFCC431A9FF44800A7B691 /* FullscreenZoomInitialFrame.mm */; };
CDBFCC461A9FF49E00A7B691 /* FullscreenZoomInitialFrame.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CDBFCC421A9FF44800A7B691 /* FullscreenZoomInitialFrame.html */; };
@@ -697,8 +700,7 @@
dstPath = TestWebKitAPI.resources;
dstSubfolderSpec = 7;
files = (
- F47D30EE1ED28E7D000482E1 /* gif-and-file-input.html in Copy Resources */,
- F47D30EC1ED28631000482E1 /* apple.gif in Copy Resources */,
+ CDA3159A1ED548F1009F60D3 /* MediaPlaybackSleepAssertion.html in Copy Resources */,
C9B1043E1ECF9848000520FA /* autoplay-inherits-gesture-from-document.html in Copy Resources */,
3FCC4FE81EC4E8CA0076E37C /* PictureInPictureDelegate.html in Copy Resources */,
C9B4AD2C1ECA6F7F00F5FEA0 /* js-autoplay-audio.html in Copy Resources */,
@@ -1489,6 +1491,9 @@
CD89D0381C4EDB2A00040A04 /* WebCoreNSURLSession.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreNSURLSession.mm; sourceTree = "<group>"; };
CD9E292B1C90A71F000BB800 /* RequiresUserActionForPlayback.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RequiresUserActionForPlayback.mm; sourceTree = "<group>"; };
CD9E292D1C90C1BA000BB800 /* audio-only.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "audio-only.html"; sourceTree = "<group>"; };
+ CDA315961ED53651009F60D3 /* MediaPlaybackSleepAssertion.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaPlaybackSleepAssertion.mm; sourceTree = "<group>"; };
+ CDA315991ED540A5009F60D3 /* MediaPlaybackSleepAssertion.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = MediaPlaybackSleepAssertion.html; sourceTree = "<group>"; };
+ CDA3159C1ED5643F009F60D3 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
CDB411591E09DA8E00EAD352 /* video-with-muted-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "video-with-muted-audio.html"; sourceTree = "<group>"; };
CDBFCC421A9FF44800A7B691 /* FullscreenZoomInitialFrame.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = FullscreenZoomInitialFrame.html; sourceTree = "<group>"; };
CDBFCC431A9FF44800A7B691 /* FullscreenZoomInitialFrame.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FullscreenZoomInitialFrame.mm; sourceTree = "<group>"; };
@@ -1592,6 +1597,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ CDA3159D1ED5643F009F60D3 /* IOKit.framework in Frameworks */,
634910E01E9D3FF300880309 /* CoreLocation.framework in Frameworks */,
7A010BCB1D877C0500EDE72A /* CoreGraphics.framework in Frameworks */,
7C83E03F1D0A61A000FEBCF3 /* libicucore.dylib in Frameworks */,
@@ -1886,6 +1892,7 @@
isa = PBXGroup;
children = (
0F4FFAA01ED3D0DE00F7111F /* ImageIO.framework */,
+ CDA3159C1ED5643F009F60D3 /* IOKit.framework */,
634910DF1E9D3FF300880309 /* CoreLocation.framework */,
7A010BCA1D877C0500EDE72A /* CoreGraphics.framework */,
7C83E0331D0A5F2700FEBCF3 /* libicucore.dylib */,
@@ -2434,6 +2441,7 @@
A5E2027215B2181900C13E14 /* WindowlessWebViewWithMedia.mm */,
F4FA917F1E61849B007B8C1D /* WKWebViewSelectionTests.mm */,
764322D51B61CCA40024F801 /* WordBoundaryTypingAttributes.mm */,
+ CDA315961ED53651009F60D3 /* MediaPlaybackSleepAssertion.mm */,
);
path = mac;
sourceTree = "<group>";
@@ -2471,6 +2479,7 @@
536770351CC812F900D425B1 /* WebScriptObjectDescription.html */,
CE14F1A2181873B0001C2705 /* WillPerformClientRedirectToURLCrash.html */,
A5E2027015B2180600C13E14 /* WindowlessWebViewWithMedia.html */,
+ CDA315991ED540A5009F60D3 /* MediaPlaybackSleepAssertion.html */,
);
name = Resources;
sourceTree = "<group>";
@@ -2981,6 +2990,7 @@
7CCE7EB21A411A5100447C4C /* MemoryCacheAddImageToCacheIOS.mm in Sources */,
7CCE7EC51A411A7E00447C4C /* MemoryCacheDisableWithinResourceLoadDelegate.mm in Sources */,
7CCE7EC61A411A7E00447C4C /* MemoryCachePruneWithinResourceLoadDelegate.mm in Sources */,
+ CDA315981ED53651009F60D3 /* MediaPlaybackSleepAssertion.mm in Sources */,
5C0BF88D1DD5964D00B00328 /* MemoryPressureHandler.mm in Sources */,
7C83E0B71D0A64B800FEBCF3 /* MenuTypesForMouseEvents.cpp in Sources */,
5C0BF8941DD599C900B00328 /* MenuTypesForMouseEvents.mm in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/mac/MediaPlaybackSleepAssertion.html (0 => 217447)
--- trunk/Tools/TestWebKitAPI/Tests/mac/MediaPlaybackSleepAssertion.html (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/MediaPlaybackSleepAssertion.html 2017-05-25 21:05:26 UTC (rev 217447)
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script>
+ if (window.internals)
+ internals.setMockMediaPlaybackTargetPickerEnabled(true);
+
+ document.addEventListener('keydown', nextstep);
+
+ function startTest() {
+ var video = document.querySelector('video');
+ video.addEventListener('playing', onplaying);
+ video.addEventListener('pause', onpause);
+ video.addEventListener('webkitcurrentplaybacktargetiswirelesschanged', oncurrentplaybacktargetiswirelesschanged);
+ window.location = 'callback:loaded';
+ }
+
+ function onplaying(event) {
+ var video = event.target;
+ window.location = 'callback:playing';
+ }
+
+ function onpause(event) {
+ var video = event.target;
+ window.location = 'callback:paused';
+ }
+
+ function oncurrentplaybacktargetiswirelesschanged(event) {
+ var video = event.target;
+ window.location = video.webkitCurrentPlaybackTargetIsWireless ? 'callback:remote-start' : 'callback:remote-end';
+ }
+
+ function nextstep() {
+ var video = document.querySelector('video');
+ if (!video.webkitCurrentPlaybackTargetIsWireless) {
+ if (video.paused)
+ video.play();
+ else {
+ video.webkitShowPlaybackTargetPicker();
+ if (window.internals)
+ internals.setMockMediaPlaybackTargetPickerState('Sleepy TV', 'DeviceAvailable');
+ }
+ } else {
+ if (!video.paused)
+ video.pause();
+ else {
+ video.webkitShowPlaybackTargetPicker();
+ if (window.internals)
+ internals.setMockMediaPlaybackTargetPickerState('Sleepy TV', 'DeviceUnavailable');
+ }
+ }
+ }
+
+ window.addEventListener('load', startTest);
+ </script>
+</head>
+<body>
+ <video src=""
+</body>
+</html>
Added: trunk/Tools/TestWebKitAPI/Tests/mac/MediaPlaybackSleepAssertion.mm (0 => 217447)
--- trunk/Tools/TestWebKitAPI/Tests/mac/MediaPlaybackSleepAssertion.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/MediaPlaybackSleepAssertion.mm 2017-05-25 21:05:26 UTC (rev 217447)
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2017 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 "WebCoreTestSupport.h"
+#import <HIToolbox/CarbonEvents.h>
+#import <IOKit/pwr_mgt/IOPMLib.h>
+#import <_javascript_Core/JSContext.h>
+#import <WebCore/Settings.h>
+#import <WebKit/WebKitLegacy.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/mac/AppKitCompatibilityDeclarations.h>
+
+static bool didFinishLoad = false;
+static bool didBeginPlaying = false;
+static bool didStopPlaying = false;
+static bool didBeginRemotePlayback = false;
+static bool didEndRemotePlayback = false;
+
+@interface MediaPlaybackSleepAssertionLoadDelegate : NSObject <WebFrameLoadDelegate>
+@end
+
+@implementation MediaPlaybackSleepAssertionLoadDelegate
+- (void)webView:(WebView *)webView didCreateJavaScriptContext:(JSContext *)context forFrame:(WebFrame *)frame
+{
+ WebCoreTestSupport::injectInternalsObject(context.JSGlobalContextRef);
+}
+@end
+
+@interface MediaPlaybackSleepAssertionPolicyDelegate : NSObject<WebPolicyDelegate>
+@end
+
+@implementation MediaPlaybackSleepAssertionPolicyDelegate
+- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener
+{
+ NSURL* URL = ""
+ if ([URL.scheme isEqualToString:@"callback"]) {
+ if ([URL.resourceSpecifier isEqualToString:@"loaded"])
+ didFinishLoad = true;
+ else if ([URL.resourceSpecifier isEqualToString:@"playing"]) {
+ didBeginPlaying = true;
+ didStopPlaying = false;
+ } else if ([URL.resourceSpecifier isEqualToString:@"paused"]) {
+ didBeginPlaying = false;
+ didStopPlaying = true;
+ } else if ([URL.resourceSpecifier isEqualToString:@"remote-start"]) {
+ didBeginRemotePlayback = true;
+ didEndRemotePlayback = false;
+ } else if ([URL.resourceSpecifier isEqualToString:@"remote-end"]) {
+ didBeginRemotePlayback = false;
+ didEndRemotePlayback = true;
+ }
+
+ [listener ignore];
+ return;
+ }
+
+ [listener use];
+}
+@end
+
+namespace TestWebKitAPI {
+
+static void simulateKeyDown(NSWindow *window)
+{
+ NSEvent *event = [NSEvent keyEventWithType:NSEventTypeKeyDown
+ location:NSMakePoint(5, 5)
+ modifierFlags:0
+ timestamp:GetCurrentEventTime()
+ windowNumber:window.windowNumber
+ context:[NSGraphicsContext currentContext]
+ characters:@" "
+ charactersIgnoringModifiers:@" "
+ isARepeat:NO
+ keyCode:0x31];
+
+ [window sendEvent:event];
+
+ event = [NSEvent keyEventWithType:NSEventTypeKeyUp
+ location:NSMakePoint(5, 5)
+ modifierFlags:0
+ timestamp:GetCurrentEventTime()
+ windowNumber:window.windowNumber
+ context:[NSGraphicsContext currentContext]
+ characters:@" "
+ charactersIgnoringModifiers:@" "
+ isARepeat:NO
+ keyCode:0x31];
+
+ [window sendEvent:event];
+}
+
+static bool hasAssertionType(CFStringRef type)
+{
+ int32_t pid = getpid();
+ auto cfPid = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pid));
+ CFDictionaryRef bareAssertionsByPID = nullptr;
+
+ IOPMCopyAssertionsByProcess(&bareAssertionsByPID);
+ if (!bareAssertionsByPID)
+ return false;
+
+ auto assertionsByPID = adoptCF(bareAssertionsByPID);
+
+ CFArrayRef assertions = (CFArrayRef)CFDictionaryGetValue(assertionsByPID.get(), cfPid.get());
+ if (!assertions)
+ return false;
+
+ for (CFIndex i = 0, count = CFArrayGetCount(assertions); i < count; ++i) {
+ CFDictionaryRef assertion = (CFDictionaryRef)CFArrayGetValueAtIndex(assertions, i);
+ CFStringRef assertionType = (CFStringRef)CFDictionaryGetValue(assertion, kIOPMAssertionTypeKey);
+ if (CFEqual(type, assertionType))
+ return true;
+ }
+ return false;
+}
+
+TEST(WebKit1, MediaPlaybackSleepAssertion)
+{
+ didFinishLoad = false;
+ didBeginPlaying = false;
+ didStopPlaying = false;
+ didBeginRemotePlayback = false;
+ didEndRemotePlayback = false;
+
+ @autoreleasepool {
+ auto webView = adoptNS([[WebView alloc] initWithFrame:NSMakeRect(0, 0, 120, 200) frameName:nil groupName:nil]);
+ auto frameLoadDelegate = adoptNS([[MediaPlaybackSleepAssertionLoadDelegate alloc] init]);
+ auto policyDelegate = adoptNS([[MediaPlaybackSleepAssertionPolicyDelegate alloc] init]);
+
+ auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
+ [[window contentView] addSubview:webView.get()];
+ [window makeKeyAndOrderFront:nil];
+
+ webView.get().policyDelegate = policyDelegate.get();
+ webView.get().frameLoadDelegate = frameLoadDelegate.get();
+ WebFrame *mainFrame = webView.get().mainFrame;
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"MediaPlaybackSleepAssertion" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+ [mainFrame loadRequest:request];
+
+ Util::run(&didFinishLoad);
+ didFinishLoad = false;
+
+ EXPECT_FALSE(hasAssertionType(CFSTR("PreventUserIdleDisplaySleep")));
+ EXPECT_FALSE(hasAssertionType(CFSTR("PreventUserIdleSystemSleep")));
+
+ simulateKeyDown(window.get());
+ Util::run(&didBeginPlaying);
+
+ EXPECT_TRUE(hasAssertionType(CFSTR("PreventUserIdleDisplaySleep")));
+ EXPECT_FALSE(hasAssertionType(CFSTR("PreventUserIdleSystemSleep")));
+
+ simulateKeyDown(window.get());
+ Util::run(&didBeginRemotePlayback);
+
+ EXPECT_FALSE(hasAssertionType(CFSTR("PreventUserIdleDisplaySleep")));
+ EXPECT_TRUE(hasAssertionType(CFSTR("PreventUserIdleSystemSleep")));
+
+ simulateKeyDown(window.get());
+ Util::run(&didStopPlaying);
+
+ EXPECT_FALSE(hasAssertionType(CFSTR("PreventUserIdleDisplaySleep")));
+ EXPECT_FALSE(hasAssertionType(CFSTR("PreventUserIdleSystemSleep")));
+ }
+}
+
+}
+