Title: [217447] trunk
Revision
217447
Author
jer.no...@apple.com
Date
2017-05-25 14:05:26 -0700 (Thu, 25 May 2017)

Log Message

System sleeps while playing to wireless target, ending stream.
https://bugs.webkit.org/show_bug.cgi?id=172541

Reviewed by Eric Carlson.

Source/WebCore:

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:

Tools:

* 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):

Modified Paths

Added Paths

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")));
+    }
+}
+
+}
+
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to