blob: 4fb2688d0c6c29f0be2357c6a6de39c3ca035b61 [file] [log] [blame]
/*
* 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"
#if JSC_OBJC_API_ENABLED
#import "PlatformUtilities.h"
#import "WebCoreTestSupport.h"
#import <Carbon/Carbon.h>
#import <IOKit/pwr_mgt/IOPMLib.h>
#import <JavaScriptCore/JSCConfig.h>
#import <JavaScriptCore/JSContext.h>
#import <WebCore/Settings.h>
#import <WebKit/WebKitLegacy.h>
#import <wtf/RetainPtr.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 = request.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(WebKitLegacy, MediaPlaybackSleepAssertion)
{
JSC::Config::configureForTesting();
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")));
}
}
}
#endif // JSC_OBJC_API_ENABLED