NowPlayingInfo should contain a unique identifier
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKitCocoa / NowPlayingControlsTests.mm
1 /*
2  * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #import "PlatformUtilities.h"
29 #import "TestWKWebView.h"
30
31 #import <WebKit/WKWebViewConfigurationPrivate.h>
32 #import <WebKit/WKWebViewPrivate.h>
33
34 #if WK_API_ENABLED && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101201)
35
36 @interface NowPlayingTestWebView : TestWKWebView
37 @property (nonatomic, readonly) BOOL hasActiveNowPlayingSession;
38 @property (readonly) NSString *lastUpdatedTitle;
39 @property (readonly) double lastUpdatedDuration;
40 @property (readonly) double lastUpdatedElapsedTime;
41 @property (readonly) NSInteger lastUniqueIdentifier;
42 @end
43
44 @implementation NowPlayingTestWebView {
45     bool _receivedNowPlayingInfoResponse;
46     BOOL _hasActiveNowPlayingSession;
47 }
48 - (BOOL)hasActiveNowPlayingSession
49 {
50     _receivedNowPlayingInfoResponse = false;
51
52     auto completionHandler = [retainedSelf = retainPtr(self), self](BOOL active, NSString *title, double duration, double elapsedTime, NSInteger uniqueIdentifier) {
53         _hasActiveNowPlayingSession = active;
54         _lastUpdatedTitle = [title copy];
55         _lastUpdatedDuration = duration;
56         _lastUniqueIdentifier = uniqueIdentifier;
57
58         _receivedNowPlayingInfoResponse = true;
59     };
60
61     [self _requestActiveNowPlayingSessionInfo:completionHandler];
62
63     TestWebKitAPI::Util::run(&_receivedNowPlayingInfoResponse);
64
65     return _hasActiveNowPlayingSession;
66 }
67
68 - (void)expectHasActiveNowPlayingSession:(BOOL)hasActiveNowPlayingSession
69 {
70     bool finishedWaiting = false;
71     while (!finishedWaiting) {
72         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
73         finishedWaiting = self.hasActiveNowPlayingSession == hasActiveNowPlayingSession;
74     }
75 }
76
77 - (void)_handleActiveNowPlayingSessionInfoResponse:(BOOL)hasActiveSession title:(NSString *)title duration:(double)duration elapsedTime:(double)elapsedTime
78 {
79     _hasActiveNowPlayingSession = hasActiveSession;
80     _lastUpdatedTitle = [title copy];
81     _lastUpdatedDuration = duration;
82     _lastUpdatedElapsedTime = elapsedTime;
83
84     _receivedNowPlayingInfoResponse = true;
85 }
86
87 - (void)setWindowVisible:(BOOL)isVisible
88 {
89 #if PLATFORM(MAC)
90     [self.window setIsVisible:isVisible];
91 #else
92     self.window.hidden = !isVisible;
93 #endif
94 }
95 @end
96
97 namespace TestWebKitAPI {
98
99 #if PLATFORM(MAC)
100 TEST(NowPlayingControlsTests, NowPlayingControlsDoNotShowForForegroundPage)
101 {
102     WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
103     configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
104     auto webView = adoptNS([[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
105     [webView loadTestPageNamed:@"large-video-test-now-playing"];
106     [webView waitForMessage:@"playing"];
107
108     [webView setWindowVisible:YES];
109     [webView.get().window makeKeyWindow];
110     [webView expectHasActiveNowPlayingSession:NO];
111
112     ASSERT_STREQ("foo", webView.get().lastUpdatedTitle.UTF8String);
113     ASSERT_EQ(10, webView.get().lastUpdatedDuration);
114     ASSERT_GE(webView.get().lastUpdatedElapsedTime, 0);
115 }
116
117 TEST(NowPlayingControlsTests, NowPlayingControlsShowForBackgroundPage)
118 {
119     WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
120     configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
121     auto webView = adoptNS([[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
122     [webView loadTestPageNamed:@"large-video-test-now-playing"];
123     [webView waitForMessage:@"playing"];
124
125     [webView setWindowVisible:NO];
126     [webView.get().window resignKeyWindow];
127     [webView expectHasActiveNowPlayingSession:YES];
128
129     ASSERT_STREQ("foo", webView.get().lastUpdatedTitle.UTF8String);
130     ASSERT_EQ(10, webView.get().lastUpdatedDuration);
131     ASSERT_GE(webView.get().lastUpdatedElapsedTime, 0);
132 }
133
134 TEST(NowPlayingControlsTests, NowPlayingControlsHideAfterShowingKeepsSessionActive)
135 {
136     WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
137     configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
138     auto webView = adoptNS([[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
139     [webView loadTestPageNamed:@"large-video-test-now-playing"];
140     [webView waitForMessage:@"playing"];
141
142     [webView setWindowVisible:NO];
143     [webView.get().window resignKeyWindow];
144
145     [webView expectHasActiveNowPlayingSession:YES];
146
147     [webView setWindowVisible:YES];
148     [webView.get().window makeKeyWindow];
149
150     [webView expectHasActiveNowPlayingSession:NO];
151
152     ASSERT_STREQ("foo", webView.get().lastUpdatedTitle.UTF8String);
153     ASSERT_EQ(10, webView.get().lastUpdatedDuration);
154     ASSERT_GE(webView.get().lastUpdatedElapsedTime, 0);
155 }
156
157 TEST(NowPlayingControlsTests, NowPlayingControlsClearInfoAfterSessionIsNoLongerValid)
158 {
159     WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
160     configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
161     auto webView = adoptNS([[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 480, 320) configuration:configuration]);
162     [webView loadTestPageNamed:@"large-video-test-now-playing"];
163     [webView waitForMessage:@"playing"];
164
165     BOOL initialHasActiveNowPlayingSession = webView.get().hasActiveNowPlayingSession;
166     NSString *initialTitle = webView.get().lastUpdatedTitle;
167     double initialDuration = webView.get().lastUpdatedDuration;
168     double initialElapsedTime = webView.get().lastUpdatedElapsedTime;
169     NSInteger initialUniqueIdentifier = webView.get().lastUniqueIdentifier;
170
171     [webView stringByEvaluatingJavaScript:@"document.querySelector('video').muted = true"];
172     [webView setWindowVisible:NO];
173     [webView.get().window resignKeyWindow];
174
175     while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {
176         if (initialHasActiveNowPlayingSession != webView.get().hasActiveNowPlayingSession)
177             break;
178
179         if (initialUniqueIdentifier != webView.get().lastUniqueIdentifier)
180             break;
181
182         if (initialDuration != webView.get().lastUpdatedDuration)
183             break;
184
185         if (initialElapsedTime != webView.get().lastUpdatedElapsedTime)
186             break;
187
188         if (![initialTitle isEqualToString:webView.get().lastUpdatedTitle])
189             break;
190     }
191
192     ASSERT_STREQ("", webView.get().lastUpdatedTitle.UTF8String);
193     ASSERT_TRUE(isnan(webView.get().lastUpdatedDuration));
194     ASSERT_TRUE(isnan(webView.get().lastUpdatedElapsedTime));
195     ASSERT_TRUE(!webView.get().lastUniqueIdentifier);
196 }
197 #endif // PLATFORM(MAC)
198
199 #if PLATFORM(IOS)
200 // FIXME: Re-enable this test once <webkit.org/b/175204> is resolved.
201 TEST(NowPlayingControlsTests, DISABLED_NowPlayingControlsIOS)
202 {
203     WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
204     configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
205     auto webView = adoptNS([[NowPlayingTestWebView alloc] initWithFrame:NSMakeRect(0, 0, 480, 320) configuration:configuration]);
206     [webView loadTestPageNamed:@"large-video-test-now-playing"];
207     [webView waitForMessage:@"playing"];
208
209     [webView expectHasActiveNowPlayingSession:YES];
210     ASSERT_STREQ("foo", webView.get().lastUpdatedTitle.UTF8String);
211     ASSERT_EQ(10, webView.get().lastUpdatedDuration);
212     ASSERT_GE(webView.get().lastUpdatedElapsedTime, 0);
213 }
214 #endif
215
216 } // namespace TestWebKitAPI
217
218 #endif // WK_API_ENABLED && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101201)