Add completion handlers to TestRunner functions setStatisticsLastSeen(), setStatistic...
[WebKit-https.git] / Tools / WebKitTestRunner / TestInvocation.cpp
1 /*
2  * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
3  * Copyright (C) 2012 Intel Corporation. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "TestInvocation.h"
29
30 #include "PlatformWebView.h"
31 #include "StringFunctions.h"
32 #include "TestController.h"
33 #include "UIScriptController.h"
34 #include "WebCoreTestSupport.h"
35 #include <WebKit/WKContextPrivate.h>
36 #include <WebKit/WKCookieManager.h>
37 #include <WebKit/WKData.h>
38 #include <WebKit/WKDictionary.h>
39 #include <WebKit/WKInspector.h>
40 #include <WebKit/WKPagePrivate.h>
41 #include <WebKit/WKRetainPtr.h>
42 #include <WebKit/WKWebsiteDataStoreRef.h>
43 #include <climits>
44 #include <cstdio>
45 #include <unistd.h>
46 #include <wtf/StdLibExtras.h>
47 #include <wtf/text/CString.h>
48
49 #if PLATFORM(MAC) && !PLATFORM(IOS)
50 #include <Carbon/Carbon.h>
51 #endif
52
53 #if PLATFORM(COCOA)
54 #include <WebKit/WKPagePrivateMac.h>
55 #endif
56
57 using namespace JSC;
58 using namespace WebKit;
59 using namespace std;
60
61 namespace WTR {
62
63 TestInvocation::TestInvocation(WKURLRef url, const TestOptions& options)
64     : m_options(options)
65     , m_url(url)
66 {
67     WKRetainPtr<WKStringRef> urlString = adoptWK(WKURLCopyString(m_url.get()));
68
69     size_t stringLength = WKStringGetLength(urlString.get());
70
71     Vector<char> urlVector;
72     urlVector.resize(stringLength + 1);
73
74     WKStringGetUTF8CString(urlString.get(), urlVector.data(), stringLength + 1);
75
76     m_urlString = String(urlVector.data(), stringLength);
77
78     // FIXME: Avoid mutating the setting via a test directory like this.
79     m_dumpFrameLoadCallbacks = urlContains("loading/");
80 }
81
82 TestInvocation::~TestInvocation()
83 {
84     if (m_pendingUIScriptInvocationData)
85         m_pendingUIScriptInvocationData->testInvocation = nullptr;
86 }
87
88 WKURLRef TestInvocation::url() const
89 {
90     return m_url.get();
91 }
92
93 bool TestInvocation::urlContains(const char* searchString) const
94 {
95     return m_urlString.containsIgnoringASCIICase(searchString);
96 }
97
98 void TestInvocation::setIsPixelTest(const std::string& expectedPixelHash)
99 {
100     m_dumpPixels = true;
101     m_expectedPixelHash = expectedPixelHash;
102 }
103
104 double TestInvocation::shortTimeout() const
105 {
106     if (!m_timeout) {
107         // Running WKTR directly, without webkitpy.
108         return TestController::defaultShortTimeout;
109     }
110
111     // This is not exactly correct for the way short timeout is used - it should not depend on whether a test is "slow",
112     // but it currently does. There is no way to know what a normal test's timeout is, as webkitpy only passes timeouts
113     // for each test individually.
114     // But there shouldn't be any observable negative consequences from this.
115     return m_timeout / 1000. / 4;
116 }
117
118 bool TestInvocation::shouldLogHistoryClientCallbacks() const
119 {
120     return urlContains("globalhistory/");
121 }
122
123 WKRetainPtr<WKMutableDictionaryRef> TestInvocation::createTestSettingsDictionary()
124 {
125     WKRetainPtr<WKMutableDictionaryRef> beginTestMessageBody = adoptWK(WKMutableDictionaryCreate());
126
127     WKRetainPtr<WKStringRef> useFlexibleViewportKey = adoptWK(WKStringCreateWithUTF8CString("UseFlexibleViewport"));
128     WKRetainPtr<WKBooleanRef> useFlexibleViewportValue = adoptWK(WKBooleanCreate(options().useFlexibleViewport));
129     WKDictionarySetItem(beginTestMessageBody.get(), useFlexibleViewportKey.get(), useFlexibleViewportValue.get());
130
131     WKRetainPtr<WKStringRef> dumpPixelsKey = adoptWK(WKStringCreateWithUTF8CString("DumpPixels"));
132     WKRetainPtr<WKBooleanRef> dumpPixelsValue = adoptWK(WKBooleanCreate(m_dumpPixels));
133     WKDictionarySetItem(beginTestMessageBody.get(), dumpPixelsKey.get(), dumpPixelsValue.get());
134
135     WKRetainPtr<WKStringRef> useWaitToDumpWatchdogTimerKey = adoptWK(WKStringCreateWithUTF8CString("UseWaitToDumpWatchdogTimer"));
136     WKRetainPtr<WKBooleanRef> useWaitToDumpWatchdogTimerValue = adoptWK(WKBooleanCreate(TestController::singleton().useWaitToDumpWatchdogTimer()));
137     WKDictionarySetItem(beginTestMessageBody.get(), useWaitToDumpWatchdogTimerKey.get(), useWaitToDumpWatchdogTimerValue.get());
138
139     WKRetainPtr<WKStringRef> timeoutKey = adoptWK(WKStringCreateWithUTF8CString("Timeout"));
140     WKRetainPtr<WKUInt64Ref> timeoutValue = adoptWK(WKUInt64Create(m_timeout));
141     WKDictionarySetItem(beginTestMessageBody.get(), timeoutKey.get(), timeoutValue.get());
142
143     WKRetainPtr<WKStringRef> dumpJSConsoleLogInStdErrKey = adoptWK(WKStringCreateWithUTF8CString("DumpJSConsoleLogInStdErr"));
144     WKRetainPtr<WKBooleanRef> dumpJSConsoleLogInStdErrValue = adoptWK(WKBooleanCreate(m_dumpJSConsoleLogInStdErr));
145     WKDictionarySetItem(beginTestMessageBody.get(), dumpJSConsoleLogInStdErrKey.get(), dumpJSConsoleLogInStdErrValue.get());
146     
147     return beginTestMessageBody;
148 }
149
150 void TestInvocation::invoke()
151 {
152     TestController::singleton().configureViewForTest(*this);
153
154     WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), false);
155
156     m_textOutput.clear();
157
158     TestController::singleton().setShouldLogHistoryClientCallbacks(shouldLogHistoryClientCallbacks());
159
160     WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain);
161
162     // FIXME: We should clear out visited links here.
163
164     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("BeginTest"));
165     auto beginTestMessageBody = createTestSettingsDictionary();
166     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), beginTestMessageBody.get());
167
168     m_startedTesting = true;
169
170     bool shouldOpenExternalURLs = false;
171
172     TestController::singleton().runUntil(m_gotInitialResponse, TestController::noTimeout);
173     if (m_error)
174         goto end;
175
176     WKPageLoadURLWithShouldOpenExternalURLsPolicy(TestController::singleton().mainWebView()->page(), m_url.get(), shouldOpenExternalURLs);
177
178     TestController::singleton().runUntil(m_gotFinalMessage, TestController::noTimeout);
179     if (m_error)
180         goto end;
181
182     dumpResults();
183
184 end:
185 #if !PLATFORM(IOS)
186     if (m_gotInitialResponse)
187         WKInspectorClose(WKPageGetInspector(TestController::singleton().mainWebView()->page()));
188 #endif // !PLATFORM(IOS)
189
190     if (TestController::singleton().resetStateToConsistentValues(m_options))
191         return;
192
193     // The process is unresponsive, so let's start a new one.
194     TestController::singleton().terminateWebContentProcess();
195     // Make sure that we have a process, as invoke() will need one to send bundle messages for the next test.
196     TestController::singleton().reattachPageToWebProcess();
197 }
198
199 void TestInvocation::dumpWebProcessUnresponsiveness(const char* errorMessage)
200 {
201     fprintf(stderr, "%s", errorMessage);
202     char buffer[1024] = { };
203 #if PLATFORM(COCOA)
204     pid_t pid = WKPageGetProcessIdentifier(TestController::singleton().mainWebView()->page());
205     snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s (pid %ld)\n", TestController::webProcessName(), static_cast<long>(pid));
206 #else
207     snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s\n", TestController::webProcessName());
208 #endif
209
210     dump(errorMessage, buffer, true);
211     
212     if (!TestController::singleton().usingServerMode())
213         return;
214     
215     if (isatty(fileno(stdin)) || isatty(fileno(stderr)))
216         fputs("Grab an image of the stack, then hit enter...\n", stderr);
217     
218     if (!fgets(buffer, sizeof(buffer), stdin) || strcmp(buffer, "#SAMPLE FINISHED\n"))
219         fprintf(stderr, "Failed receive expected sample response, got:\n\t\"%s\"\nContinuing...\n", buffer);
220 }
221
222 void TestInvocation::dump(const char* textToStdout, const char* textToStderr, bool seenError)
223 {
224     printf("Content-Type: text/plain\n");
225     if (textToStdout)
226         fputs(textToStdout, stdout);
227     if (textToStderr)
228         fputs(textToStderr, stderr);
229
230     fputs("#EOF\n", stdout);
231     fputs("#EOF\n", stderr);
232     if (seenError)
233         fputs("#EOF\n", stdout);
234     fflush(stdout);
235     fflush(stderr);
236 }
237
238 void TestInvocation::forceRepaintDoneCallback(WKErrorRef error, void* context)
239 {
240     // The context may not be valid any more, e.g. if WebKit is invalidating callbacks at process exit.
241     if (error)
242         return;
243
244     TestInvocation* testInvocation = static_cast<TestInvocation*>(context);
245     RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(testInvocation));
246
247     testInvocation->m_gotRepaint = true;
248     TestController::singleton().notifyDone();
249 }
250
251 void TestInvocation::dumpResults()
252 {
253     if (m_textOutput.length() || !m_audioResult)
254         dump(m_textOutput.toString().utf8().data());
255     else
256         dumpAudio(m_audioResult.get());
257
258     if (m_dumpPixels) {
259         if (m_pixelResult)
260             dumpPixelsAndCompareWithExpected(SnapshotResultType::WebContents, m_repaintRects.get(), m_pixelResult.get());
261         else if (m_pixelResultIsPending) {
262             m_gotRepaint = false;
263             WKPageForceRepaint(TestController::singleton().mainWebView()->page(), this, TestInvocation::forceRepaintDoneCallback);
264             TestController::singleton().runUntil(m_gotRepaint, TestController::noTimeout);
265             dumpPixelsAndCompareWithExpected(SnapshotResultType::WebView, m_repaintRects.get());
266         }
267     }
268
269     fputs("#EOF\n", stdout);
270     fflush(stdout);
271     fflush(stderr);
272 }
273
274 void TestInvocation::dumpAudio(WKDataRef audioData)
275 {
276     size_t length = WKDataGetSize(audioData);
277     if (!length)
278         return;
279
280     const unsigned char* data = WKDataGetBytes(audioData);
281
282     printf("Content-Type: audio/wav\n");
283     printf("Content-Length: %lu\n", static_cast<unsigned long>(length));
284
285     fwrite(data, 1, length, stdout);
286     printf("#EOF\n");
287     fprintf(stderr, "#EOF\n");
288 }
289
290 bool TestInvocation::compareActualHashToExpectedAndDumpResults(const char actualHash[33])
291 {
292     // Compute the hash of the bitmap context pixels
293     fprintf(stdout, "\nActualHash: %s\n", actualHash);
294
295     if (!m_expectedPixelHash.length())
296         return false;
297
298     ASSERT(m_expectedPixelHash.length() == 32);
299     fprintf(stdout, "\nExpectedHash: %s\n", m_expectedPixelHash.c_str());
300
301     // FIXME: Do case insensitive compare.
302     return m_expectedPixelHash == actualHash;
303 }
304
305 void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
306 {
307     if (WKStringIsEqualToUTF8CString(messageName, "Error")) {
308         // Set all states to true to stop spinning the runloop.
309         m_gotInitialResponse = true;
310         m_gotFinalMessage = true;
311         m_error = true;
312         TestController::singleton().notifyDone();
313         return;
314     }
315
316     if (WKStringIsEqualToUTF8CString(messageName, "Ack")) {
317         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
318         WKStringRef messageBodyString = static_cast<WKStringRef>(messageBody);
319         if (WKStringIsEqualToUTF8CString(messageBodyString, "BeginTest")) {
320             m_gotInitialResponse = true;
321             TestController::singleton().notifyDone();
322             return;
323         }
324
325         ASSERT_NOT_REACHED();
326     }
327
328     if (WKStringIsEqualToUTF8CString(messageName, "Done")) {
329         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
330         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
331
332         WKRetainPtr<WKStringRef> pixelResultIsPendingKey = adoptWK(WKStringCreateWithUTF8CString("PixelResultIsPending"));
333         WKBooleanRef pixelResultIsPending = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultIsPendingKey.get()));
334         m_pixelResultIsPending = WKBooleanGetValue(pixelResultIsPending);
335
336         if (!m_pixelResultIsPending) {
337             WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
338             m_pixelResult = static_cast<WKImageRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultKey.get()));
339             ASSERT(!m_pixelResult || m_dumpPixels);
340         }
341
342         WKRetainPtr<WKStringRef> repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects"));
343         m_repaintRects = static_cast<WKArrayRef>(WKDictionaryGetItemForKey(messageBodyDictionary, repaintRectsKey.get()));
344
345         WKRetainPtr<WKStringRef> audioResultKey =  adoptWK(WKStringCreateWithUTF8CString("AudioResult"));
346         m_audioResult = static_cast<WKDataRef>(WKDictionaryGetItemForKey(messageBodyDictionary, audioResultKey.get()));
347
348         m_gotFinalMessage = true;
349         TestController::singleton().notifyDone();
350         return;
351     }
352
353     if (WKStringIsEqualToUTF8CString(messageName, "TextOutput")) {
354         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
355         WKStringRef textOutput = static_cast<WKStringRef>(messageBody);
356         m_textOutput.append(toWTFString(textOutput));
357         return;
358     }
359
360     if (WKStringIsEqualToUTF8CString(messageName, "DumpToStdErr")) {
361         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
362         WKStringRef textOutput = static_cast<WKStringRef>(messageBody);
363         fprintf(stderr, "%s", toWTFString(textOutput).utf8().data());
364         return;
365     }
366
367     if (WKStringIsEqualToUTF8CString(messageName, "BeforeUnloadReturnValue")) {
368         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
369         WKBooleanRef beforeUnloadReturnValue = static_cast<WKBooleanRef>(messageBody);
370         TestController::singleton().setBeforeUnloadReturnValue(WKBooleanGetValue(beforeUnloadReturnValue));
371         return;
372     }
373     
374     if (WKStringIsEqualToUTF8CString(messageName, "AddChromeInputField")) {
375         TestController::singleton().mainWebView()->addChromeInputField();
376         WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallAddChromeInputFieldCallback"));
377         WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
378         return;
379     }
380
381     if (WKStringIsEqualToUTF8CString(messageName, "RemoveChromeInputField")) {
382         TestController::singleton().mainWebView()->removeChromeInputField();
383         WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallRemoveChromeInputFieldCallback"));
384         WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
385         return;
386     }
387     
388     if (WKStringIsEqualToUTF8CString(messageName, "FocusWebView")) {
389         TestController::singleton().mainWebView()->makeWebViewFirstResponder();
390         WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallFocusWebViewCallback"));
391         WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
392         return;
393     }
394
395     if (WKStringIsEqualToUTF8CString(messageName, "SetBackingScaleFactor")) {
396         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
397         double backingScaleFactor = WKDoubleGetValue(static_cast<WKDoubleRef>(messageBody));
398         WKPageSetCustomBackingScaleFactor(TestController::singleton().mainWebView()->page(), backingScaleFactor);
399
400         WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallSetBackingScaleFactorCallback"));
401         WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
402         return;
403     }
404
405     if (WKStringIsEqualToUTF8CString(messageName, "SimulateWebNotificationClick")) {
406         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
407         uint64_t notificationID = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
408         TestController::singleton().simulateWebNotificationClick(notificationID);
409         return;
410     }
411
412     if (WKStringIsEqualToUTF8CString(messageName, "SetAddsVisitedLinks")) {
413         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
414         WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
415         WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), WKBooleanGetValue(enabledWK));
416         return;
417     }
418
419     if (WKStringIsEqualToUTF8CString(messageName, "SetGeolocationPermission")) {
420         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
421         WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
422         TestController::singleton().setGeolocationPermission(WKBooleanGetValue(enabledWK));
423         return;
424     }
425
426     if (WKStringIsEqualToUTF8CString(messageName, "SetMockGeolocationPosition")) {
427         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
428         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
429
430         WKRetainPtr<WKStringRef> latitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("latitude"));
431         WKDoubleRef latitudeWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, latitudeKeyWK.get()));
432         double latitude = WKDoubleGetValue(latitudeWK);
433
434         WKRetainPtr<WKStringRef> longitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("longitude"));
435         WKDoubleRef longitudeWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, longitudeKeyWK.get()));
436         double longitude = WKDoubleGetValue(longitudeWK);
437
438         WKRetainPtr<WKStringRef> accuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("accuracy"));
439         WKDoubleRef accuracyWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, accuracyKeyWK.get()));
440         double accuracy = WKDoubleGetValue(accuracyWK);
441
442         WKRetainPtr<WKStringRef> providesAltitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesAltitude"));
443         WKBooleanRef providesAltitudeWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesAltitudeKeyWK.get()));
444         bool providesAltitude = WKBooleanGetValue(providesAltitudeWK);
445
446         WKRetainPtr<WKStringRef> altitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("altitude"));
447         WKDoubleRef altitudeWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, altitudeKeyWK.get()));
448         double altitude = WKDoubleGetValue(altitudeWK);
449
450         WKRetainPtr<WKStringRef> providesAltitudeAccuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesAltitudeAccuracy"));
451         WKBooleanRef providesAltitudeAccuracyWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesAltitudeAccuracyKeyWK.get()));
452         bool providesAltitudeAccuracy = WKBooleanGetValue(providesAltitudeAccuracyWK);
453
454         WKRetainPtr<WKStringRef> altitudeAccuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("altitudeAccuracy"));
455         WKDoubleRef altitudeAccuracyWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, altitudeAccuracyKeyWK.get()));
456         double altitudeAccuracy = WKDoubleGetValue(altitudeAccuracyWK);
457
458         WKRetainPtr<WKStringRef> providesHeadingKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesHeading"));
459         WKBooleanRef providesHeadingWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesHeadingKeyWK.get()));
460         bool providesHeading = WKBooleanGetValue(providesHeadingWK);
461
462         WKRetainPtr<WKStringRef> headingKeyWK(AdoptWK, WKStringCreateWithUTF8CString("heading"));
463         WKDoubleRef headingWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, headingKeyWK.get()));
464         double heading = WKDoubleGetValue(headingWK);
465
466         WKRetainPtr<WKStringRef> providesSpeedKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesSpeed"));
467         WKBooleanRef providesSpeedWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesSpeedKeyWK.get()));
468         bool providesSpeed = WKBooleanGetValue(providesSpeedWK);
469
470         WKRetainPtr<WKStringRef> speedKeyWK(AdoptWK, WKStringCreateWithUTF8CString("speed"));
471         WKDoubleRef speedWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, speedKeyWK.get()));
472         double speed = WKDoubleGetValue(speedWK);
473
474         WKRetainPtr<WKStringRef> providesFloorLevelKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesFloorLevel"));
475         WKBooleanRef providesFloorLevelWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesFloorLevelKeyWK.get()));
476         bool providesFloorLevel = WKBooleanGetValue(providesFloorLevelWK);
477
478         WKRetainPtr<WKStringRef> floorLevelKeyWK(AdoptWK, WKStringCreateWithUTF8CString("floorLevel"));
479         WKDoubleRef floorLevelWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, floorLevelKeyWK.get()));
480         double floorLevel = WKDoubleGetValue(floorLevelWK);
481
482         TestController::singleton().setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed, providesFloorLevel, floorLevel);
483         return;
484     }
485
486     if (WKStringIsEqualToUTF8CString(messageName, "SetMockGeolocationPositionUnavailableError")) {
487         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
488         WKStringRef errorMessage = static_cast<WKStringRef>(messageBody);
489         TestController::singleton().setMockGeolocationPositionUnavailableError(errorMessage);
490         return;
491     }
492
493     if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPermission")) {
494         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
495         WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
496         TestController::singleton().setUserMediaPermission(WKBooleanGetValue(enabledWK));
497         return;
498     }
499
500     if (WKStringIsEqualToUTF8CString(messageName, "ResetUserMediaPermission")) {
501         TestController::singleton().resetUserMediaPermission();
502         return;
503     }
504
505     if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPersistentPermissionForOrigin")) {
506         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
507         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
508
509         WKRetainPtr<WKStringRef> permissionKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permission"));
510         WKBooleanRef permissionWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissionKeyWK.get()));
511         bool permission = WKBooleanGetValue(permissionWK);
512
513         WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin"));
514         WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
515
516         WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
517         WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
518
519         TestController::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK, parentOriginWK);
520         return;
521     }
522
523     if (WKStringIsEqualToUTF8CString(messageName, "ResetUserMediaPermissionRequestCountForOrigin")) {
524         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
525         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
526
527         WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin"));
528         WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
529
530         WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
531         WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
532         
533         TestController::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK, parentOriginWK);
534         return;
535     }
536
537     if (WKStringIsEqualToUTF8CString(messageName, "SetCacheModel")) {
538         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
539         uint64_t model = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
540         WKContextSetCacheModel(TestController::singleton().context(), model);
541         return;
542     }
543
544     if (WKStringIsEqualToUTF8CString(messageName, "SetCustomPolicyDelegate")) {
545         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
546         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
547
548         WKRetainPtr<WKStringRef> enabledKeyWK(AdoptWK, WKStringCreateWithUTF8CString("enabled"));
549         WKBooleanRef enabledWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, enabledKeyWK.get()));
550         bool enabled = WKBooleanGetValue(enabledWK);
551
552         WKRetainPtr<WKStringRef> permissiveKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permissive"));
553         WKBooleanRef permissiveWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissiveKeyWK.get()));
554         bool permissive = WKBooleanGetValue(permissiveWK);
555
556         TestController::singleton().setCustomPolicyDelegate(enabled, permissive);
557         return;
558     }
559
560     if (WKStringIsEqualToUTF8CString(messageName, "SetHidden")) {
561         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
562         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
563
564         WKRetainPtr<WKStringRef> isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("hidden"));
565         WKBooleanRef hiddenWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isInitialKeyWK.get()));
566         bool hidden = WKBooleanGetValue(hiddenWK);
567
568         TestController::singleton().setHidden(hidden);
569         return;
570     }
571
572     if (WKStringIsEqualToUTF8CString(messageName, "ProcessWorkQueue")) {
573         if (TestController::singleton().workQueueManager().processWorkQueue()) {
574             WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("WorkQueueProcessedCallback"));
575             WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
576         }
577         return;
578     }
579
580     if (WKStringIsEqualToUTF8CString(messageName, "QueueBackNavigation")) {
581         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
582         uint64_t stepCount = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
583         TestController::singleton().workQueueManager().queueBackNavigation(stepCount);
584         return;
585     }
586
587     if (WKStringIsEqualToUTF8CString(messageName, "QueueForwardNavigation")) {
588         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
589         uint64_t stepCount = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
590         TestController::singleton().workQueueManager().queueForwardNavigation(stepCount);
591         return;
592     }
593
594     if (WKStringIsEqualToUTF8CString(messageName, "QueueLoad")) {
595         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
596         WKDictionaryRef loadDataDictionary = static_cast<WKDictionaryRef>(messageBody);
597
598         WKRetainPtr<WKStringRef> urlKey(AdoptWK, WKStringCreateWithUTF8CString("url"));
599         WKStringRef urlWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, urlKey.get()));
600
601         WKRetainPtr<WKStringRef> targetKey(AdoptWK, WKStringCreateWithUTF8CString("target"));
602         WKStringRef targetWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, targetKey.get()));
603
604         WKRetainPtr<WKStringRef> shouldOpenExternalURLsKey(AdoptWK, WKStringCreateWithUTF8CString("shouldOpenExternalURLs"));
605         WKBooleanRef shouldOpenExternalURLsValueWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(loadDataDictionary, shouldOpenExternalURLsKey.get()));
606
607         TestController::singleton().workQueueManager().queueLoad(toWTFString(urlWK), toWTFString(targetWK), WKBooleanGetValue(shouldOpenExternalURLsValueWK));
608         return;
609     }
610
611     if (WKStringIsEqualToUTF8CString(messageName, "QueueLoadHTMLString")) {
612         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
613         WKDictionaryRef loadDataDictionary = static_cast<WKDictionaryRef>(messageBody);
614
615         WKRetainPtr<WKStringRef> contentKey(AdoptWK, WKStringCreateWithUTF8CString("content"));
616         WKStringRef contentWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, contentKey.get()));
617
618         WKRetainPtr<WKStringRef> baseURLKey(AdoptWK, WKStringCreateWithUTF8CString("baseURL"));
619         WKStringRef baseURLWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, baseURLKey.get()));
620
621         WKRetainPtr<WKStringRef> unreachableURLKey(AdoptWK, WKStringCreateWithUTF8CString("unreachableURL"));
622         WKStringRef unreachableURLWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, unreachableURLKey.get()));
623
624         TestController::singleton().workQueueManager().queueLoadHTMLString(toWTFString(contentWK), baseURLWK ? toWTFString(baseURLWK) : String(), unreachableURLWK ? toWTFString(unreachableURLWK) : String());
625         return;
626     }
627
628     if (WKStringIsEqualToUTF8CString(messageName, "QueueReload")) {
629         TestController::singleton().workQueueManager().queueReload();
630         return;
631     }
632
633     if (WKStringIsEqualToUTF8CString(messageName, "QueueLoadingScript")) {
634         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
635         WKStringRef script = static_cast<WKStringRef>(messageBody);
636         TestController::singleton().workQueueManager().queueLoadingScript(toWTFString(script));
637         return;
638     }
639
640     if (WKStringIsEqualToUTF8CString(messageName, "QueueNonLoadingScript")) {
641         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
642         WKStringRef script = static_cast<WKStringRef>(messageBody);
643         TestController::singleton().workQueueManager().queueNonLoadingScript(toWTFString(script));
644         return;
645     }
646
647     if (WKStringIsEqualToUTF8CString(messageName, "SetRejectsProtectionSpaceAndContinueForAuthenticationChallenges")) {
648         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
649         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
650         TestController::singleton().setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(WKBooleanGetValue(value));
651         return;
652     }
653
654     if (WKStringIsEqualToUTF8CString(messageName, "SetHandlesAuthenticationChallenges")) {
655         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
656         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
657         TestController::singleton().setHandlesAuthenticationChallenges(WKBooleanGetValue(value));
658         return;
659     }
660
661     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldLogCanAuthenticateAgainstProtectionSpace")) {
662         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
663         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
664         TestController::singleton().setShouldLogCanAuthenticateAgainstProtectionSpace(WKBooleanGetValue(value));
665         return;
666     }
667
668     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldLogDownloadCallbacks")) {
669         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
670         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
671         TestController::singleton().setShouldLogDownloadCallbacks(WKBooleanGetValue(value));
672         return;
673     }
674
675     if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationUsername")) {
676         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
677         WKStringRef username = static_cast<WKStringRef>(messageBody);
678         TestController::singleton().setAuthenticationUsername(toWTFString(username));
679         return;
680     }
681
682     if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationPassword")) {
683         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
684         WKStringRef password = static_cast<WKStringRef>(messageBody);
685         TestController::singleton().setAuthenticationPassword(toWTFString(password));
686         return;
687     }
688
689     if (WKStringIsEqualToUTF8CString(messageName, "SetBlockAllPlugins")) {
690         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
691         WKBooleanRef shouldBlock = static_cast<WKBooleanRef>(messageBody);
692         TestController::singleton().setBlockAllPlugins(WKBooleanGetValue(shouldBlock));
693         return;
694     }
695
696     if (WKStringIsEqualToUTF8CString(messageName, "SetPluginSupportedMode")) {
697         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
698         WKStringRef mode = static_cast<WKStringRef>(messageBody);
699         TestController::singleton().setPluginSupportedMode(toWTFString(mode));
700         return;
701     }
702
703     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDecideNavigationPolicyAfterDelay")) {
704         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
705         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
706         TestController::singleton().setShouldDecideNavigationPolicyAfterDelay(WKBooleanGetValue(value));
707         return;
708     }
709
710     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDecideResponsePolicyAfterDelay")) {
711         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
712         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
713         TestController::singleton().setShouldDecideResponsePolicyAfterDelay(WKBooleanGetValue(value));
714         return;
715     }
716
717     if (WKStringIsEqualToUTF8CString(messageName, "SetNavigationGesturesEnabled")) {
718         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
719         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
720         TestController::singleton().setNavigationGesturesEnabled(WKBooleanGetValue(value));
721         return;
722     }
723     
724     if (WKStringIsEqualToUTF8CString(messageName, "SetIgnoresViewportScaleLimits")) {
725         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
726         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
727         TestController::singleton().setIgnoresViewportScaleLimits(WKBooleanGetValue(value));
728         return;
729     }
730
731     if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDownloadUndisplayableMIMETypes")) {
732         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
733         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
734         TestController::singleton().setShouldDownloadUndisplayableMIMETypes(WKBooleanGetValue(value));
735         return;
736     }
737
738     if (WKStringIsEqualToUTF8CString(messageName, "TerminateStorageProcess")) {
739         ASSERT(!messageBody);
740         TestController::singleton().terminateStorageProcess();
741         return;
742     }
743
744     if (WKStringIsEqualToUTF8CString(messageName, "TerminateNetworkProcess")) {
745         ASSERT(!messageBody);
746         TestController::singleton().terminateNetworkProcess();
747         return;
748     }
749
750     if (WKStringIsEqualToUTF8CString(messageName, "TerminateServiceWorkerProcess")) {
751         ASSERT(!messageBody);
752         TestController::singleton().terminateServiceWorkerProcess();
753         return;
754     }
755
756     if (WKStringIsEqualToUTF8CString(messageName, "RunUIProcessScript")) {
757         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
758         WKRetainPtr<WKStringRef> scriptKey(AdoptWK, WKStringCreateWithUTF8CString("Script"));
759         WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID"));
760
761         UIScriptInvocationData* invocationData = new UIScriptInvocationData();
762         invocationData->testInvocation = this;
763         invocationData->callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
764         invocationData->scriptString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, scriptKey.get()));
765         m_pendingUIScriptInvocationData = invocationData;
766         WKPageCallAfterNextPresentationUpdate(TestController::singleton().mainWebView()->page(), invocationData, runUISideScriptAfterUpdateCallback);
767         return;
768     }
769
770     if (WKStringIsEqualToUTF8CString(messageName, "SetOpenPanelFileURLs")) {
771         TestController::singleton().setOpenPanelFileURLs(static_cast<WKArrayRef>(messageBody));
772         return;
773     }
774
775     ASSERT_NOT_REACHED();
776 }
777
778 WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
779 {
780     if (WKStringIsEqualToUTF8CString(messageName, "Initialization")) {
781         auto settings = createTestSettingsDictionary();
782         WKRetainPtr<WKStringRef> resumeTestingKey = adoptWK(WKStringCreateWithUTF8CString("ResumeTesting"));
783         WKRetainPtr<WKBooleanRef> resumeTestingValue = adoptWK(WKBooleanCreate(m_startedTesting));
784         WKDictionarySetItem(settings.get(), resumeTestingKey.get(), resumeTestingValue.get());
785         return settings;
786     }
787
788     if (WKStringIsEqualToUTF8CString(messageName, "SetDumpPixels")) {
789         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
790         m_dumpPixels = WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody));
791         return nullptr;
792     }
793     if (WKStringIsEqualToUTF8CString(messageName, "GetDumpPixels"))
794         return WKRetainPtr<WKTypeRef>(AdoptWK, WKBooleanCreate(m_dumpPixels));
795
796     if (WKStringIsEqualToUTF8CString(messageName, "SetWhatToDump")) {
797         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
798         m_whatToDump = static_cast<WhatToDump>(WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)));
799         return nullptr;
800     }
801     if (WKStringIsEqualToUTF8CString(messageName, "GetWhatToDump"))
802         return WKRetainPtr<WKTypeRef>(AdoptWK, WKUInt64Create(static_cast<uint64_t>(m_whatToDump)));
803
804     if (WKStringIsEqualToUTF8CString(messageName, "SetWaitUntilDone")) {
805         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
806         m_waitUntilDone = static_cast<unsigned char>(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
807         return nullptr;
808     }
809     if (WKStringIsEqualToUTF8CString(messageName, "GetWaitUntilDone"))
810         return WKRetainPtr<WKTypeRef>(AdoptWK, WKBooleanCreate(m_waitUntilDone));
811
812     if (WKStringIsEqualToUTF8CString(messageName, "SetDumpFrameLoadCallbacks")) {
813         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
814         m_dumpFrameLoadCallbacks = static_cast<unsigned char>(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
815         return nullptr;
816     }
817     if (WKStringIsEqualToUTF8CString(messageName, "GetDumpFrameLoadCallbacks"))
818         return WKRetainPtr<WKTypeRef>(AdoptWK, WKBooleanCreate(m_dumpFrameLoadCallbacks));
819
820     if (WKStringIsEqualToUTF8CString(messageName, "SetWindowIsKey")) {
821         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
822         WKBooleanRef isKeyValue = static_cast<WKBooleanRef>(messageBody);
823         TestController::singleton().mainWebView()->setWindowIsKey(WKBooleanGetValue(isKeyValue));
824         return nullptr;
825     }
826
827     if (WKStringIsEqualToUTF8CString(messageName, "SetViewSize")) {
828         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
829
830         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
831         WKRetainPtr<WKStringRef> widthKey(AdoptWK, WKStringCreateWithUTF8CString("width"));
832         WKRetainPtr<WKStringRef> heightKey(AdoptWK, WKStringCreateWithUTF8CString("height"));
833
834         WKDoubleRef widthWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, widthKey.get()));
835         WKDoubleRef heightWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, heightKey.get()));
836
837         TestController::singleton().mainWebView()->resizeTo(WKDoubleGetValue(widthWK), WKDoubleGetValue(heightWK));
838         return nullptr;
839     }
840
841     if (WKStringIsEqualToUTF8CString(messageName, "IsGeolocationClientActive")) {
842         bool isActive = TestController::singleton().isGeolocationProviderActive();
843         WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isActive));
844         return result;
845     }
846
847     if (WKStringIsEqualToUTF8CString(messageName, "IsWorkQueueEmpty")) {
848         bool isEmpty = TestController::singleton().workQueueManager().isWorkQueueEmpty();
849         WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isEmpty));
850         return result;
851     }
852
853     if (WKStringIsEqualToUTF8CString(messageName, "DidReceiveServerRedirectForProvisionalNavigation")) {
854         WKRetainPtr<WKBooleanRef> result(AdoptWK, WKBooleanCreate(TestController::singleton().didReceiveServerRedirectForProvisionalNavigation()));
855         return result;
856     }
857
858     if (WKStringIsEqualToUTF8CString(messageName, "ClearDidReceiveServerRedirectForProvisionalNavigation")) {
859         TestController::singleton().clearDidReceiveServerRedirectForProvisionalNavigation();
860         return nullptr;
861     }
862
863     if (WKStringIsEqualToUTF8CString(messageName, "SecureEventInputIsEnabled")) {
864 #if PLATFORM(MAC) && !PLATFORM(IOS)
865         WKRetainPtr<WKBooleanRef> result(AdoptWK, WKBooleanCreate(IsSecureEventInputEnabled()));
866 #else
867         WKRetainPtr<WKBooleanRef> result(AdoptWK, WKBooleanCreate(false));
868 #endif
869         return result;
870     }
871
872     if (WKStringIsEqualToUTF8CString(messageName, "SetAlwaysAcceptCookies")) {
873         WKBooleanRef accept = static_cast<WKBooleanRef>(messageBody);
874         WKHTTPCookieAcceptPolicy policy = WKBooleanGetValue(accept) ? kWKHTTPCookieAcceptPolicyAlways : kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain;
875         // FIXME: This updates the policy in WebProcess and in NetworkProcess asynchronously, which might break some tests' expectations.
876         WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), policy);
877         return nullptr;
878     }
879
880     if (WKStringIsEqualToUTF8CString(messageName, "SetCookieStoragePartitioningEnabled")) {
881         WKBooleanRef accept = static_cast<WKBooleanRef>(messageBody);
882         WKCookieManagerSetCookieStoragePartitioningEnabled(WKContextGetCookieManager(TestController::singleton().context()), WKBooleanGetValue(accept));
883         return nullptr;
884     }
885
886     if (WKStringIsEqualToUTF8CString(messageName, "SetCustomUserAgent")) {
887         WKStringRef userAgent = static_cast<WKStringRef>(messageBody);
888         WKPageSetCustomUserAgent(TestController::singleton().mainWebView()->page(), userAgent);
889         return nullptr;
890     }
891
892     if (WKStringIsEqualToUTF8CString(messageName, "SetStorageAccessAPIEnabled")) {
893         WKBooleanRef accept = static_cast<WKBooleanRef>(messageBody);
894         WKCookieManagerSetStorageAccessAPIEnabled(WKContextGetCookieManager(TestController::singleton().context()), WKBooleanGetValue(accept));
895         return nullptr;
896     }
897
898     if (WKStringIsEqualToUTF8CString(messageName, "GetAllStorageAccessEntries")) {
899         TestController::singleton().getAllStorageAccessEntries();
900         return nullptr;
901     }
902
903     if (WKStringIsEqualToUTF8CString(messageName, "SetAllowsAnySSLCertificate")) {
904         TestController::singleton().setAllowsAnySSLCertificate(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
905         return nullptr;
906     }
907
908     if (WKStringIsEqualToUTF8CString(messageName, "ImageCountInGeneralPasteboard")) {
909         unsigned count = TestController::singleton().imageCountInGeneralPasteboard();
910         WKRetainPtr<WKUInt64Ref> result(AdoptWK, WKUInt64Create(count));
911         return result;
912     }
913     
914     if (WKStringIsEqualToUTF8CString(messageName, "DeleteAllIndexedDatabases")) {
915         WKWebsiteDataStoreRemoveAllIndexedDatabases(WKContextGetWebsiteDataStore(TestController::singleton().context()));
916         return nullptr;
917     }
918
919     if (WKStringIsEqualToUTF8CString(messageName, "AddMockMediaDevice")) {
920         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
921
922         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
923         WKRetainPtr<WKStringRef> persistentIDKey(AdoptWK, WKStringCreateWithUTF8CString("PersistentID"));
924         WKRetainPtr<WKStringRef> labelKey(AdoptWK, WKStringCreateWithUTF8CString("Label"));
925         WKRetainPtr<WKStringRef> typeKey(AdoptWK, WKStringCreateWithUTF8CString("Type"));
926
927         auto persistentID = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, persistentIDKey.get()));
928         auto label = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, labelKey.get()));
929         auto type = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, typeKey.get()));
930
931         TestController::singleton().addMockMediaDevice(persistentID, label, type);
932         return nullptr;
933     }
934
935     if (WKStringIsEqualToUTF8CString(messageName, "ClearMockMediaDevices")) {
936         TestController::singleton().clearMockMediaDevices();
937         return nullptr;
938     }
939
940     if (WKStringIsEqualToUTF8CString(messageName, "RemoveMockMediaDevice")) {
941         WKStringRef persistentId = static_cast<WKStringRef>(messageBody);
942
943         TestController::singleton().removeMockMediaDevice(persistentId);
944         return nullptr;
945     }
946
947     if (WKStringIsEqualToUTF8CString(messageName, "ResetMockMediaDevices")) {
948         TestController::singleton().resetMockMediaDevices();
949         return nullptr;
950     }
951
952 #if PLATFORM(MAC)
953     if (WKStringIsEqualToUTF8CString(messageName, "ConnectMockGamepad")) {
954         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
955
956         uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
957         WebCoreTestSupport::connectMockGamepad(index);
958         
959         return nullptr;
960     }
961
962     if (WKStringIsEqualToUTF8CString(messageName, "DisconnectMockGamepad")) {
963         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
964
965         uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
966         WebCoreTestSupport::disconnectMockGamepad(index);
967
968         return nullptr;
969     }
970
971     if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadDetails")) {
972         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
973
974         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
975         WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex"));
976         WKRetainPtr<WKStringRef> gamepadIDKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadID"));
977         WKRetainPtr<WKStringRef> axisCountKey(AdoptWK, WKStringCreateWithUTF8CString("AxisCount"));
978         WKRetainPtr<WKStringRef> buttonCountKey(AdoptWK, WKStringCreateWithUTF8CString("ButtonCount"));
979
980         WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
981         WKStringRef gamepadID = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIDKey.get()));
982         WKUInt64Ref axisCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisCountKey.get()));
983         WKUInt64Ref buttonCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonCountKey.get()));
984
985         WebCoreTestSupport::setMockGamepadDetails(WKUInt64GetValue(gamepadIndex), toWTFString(gamepadID), WKUInt64GetValue(axisCount), WKUInt64GetValue(buttonCount));
986         return nullptr;
987     }
988
989     if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadAxisValue")) {
990         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
991
992         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
993         WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex"));
994         WKRetainPtr<WKStringRef> axisIndexKey(AdoptWK, WKStringCreateWithUTF8CString("AxisIndex"));
995         WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
996
997         WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
998         WKUInt64Ref axisIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisIndexKey.get()));
999         WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1000
1001         WebCoreTestSupport::setMockGamepadAxisValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(axisIndex), WKDoubleGetValue(value));
1002
1003         return nullptr;
1004     }
1005
1006     if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadButtonValue")) {
1007         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1008
1009         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1010         WKRetainPtr<WKStringRef> gamepadIndexKey(AdoptWK, WKStringCreateWithUTF8CString("GamepadIndex"));
1011         WKRetainPtr<WKStringRef> buttonIndexKey(AdoptWK, WKStringCreateWithUTF8CString("ButtonIndex"));
1012         WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
1013
1014         WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
1015         WKUInt64Ref buttonIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonIndexKey.get()));
1016         WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1017
1018         WebCoreTestSupport::setMockGamepadButtonValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(buttonIndex), WKDoubleGetValue(value));
1019
1020         return nullptr;
1021     }
1022 #endif // PLATFORM(MAC)
1023
1024     if (WKStringIsEqualToUTF8CString(messageName, "UserMediaPermissionRequestCountForOrigin")) {
1025         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1026         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1027
1028         WKRetainPtr<WKStringRef> originKey(AdoptWK, WKStringCreateWithUTF8CString("origin"));
1029         WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
1030
1031         WKRetainPtr<WKStringRef> parentOriginKey(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
1032         WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
1033         
1034         unsigned count = TestController::singleton().userMediaPermissionRequestCountForOrigin(originWK, parentOriginWK);
1035         WKRetainPtr<WKUInt64Ref> result(AdoptWK, WKUInt64Create(count));
1036         return result;
1037     }
1038
1039     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsLastSeen")) {
1040         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1041         
1042         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1043         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1044         WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
1045         
1046         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1047         WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1048         
1049         TestController::singleton().setStatisticsLastSeen(hostName, WKDoubleGetValue(value));
1050         
1051         return nullptr;
1052     }
1053     
1054     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsPrevalentResource")) {
1055         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1056
1057         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1058         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1059         WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
1060
1061         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1062         WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1063
1064         TestController::singleton().setStatisticsPrevalentResource(hostName, WKBooleanGetValue(value));
1065         return nullptr;
1066     }
1067
1068     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsVeryPrevalentResource")) {
1069         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1070         
1071         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1072         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1073         WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
1074         
1075         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1076         WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1077         
1078         TestController::singleton().setStatisticsVeryPrevalentResource(hostName, WKBooleanGetValue(value));
1079         return nullptr;
1080     }
1081     
1082     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsPrevalentResource")) {
1083         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1084
1085         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1086         bool isPrevalent = TestController::singleton().isStatisticsPrevalentResource(hostName);
1087         WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isPrevalent));
1088         return result;
1089     }
1090
1091     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsVeryPrevalentResource")) {
1092         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1093         
1094         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1095         bool isPrevalent = TestController::singleton().isStatisticsVeryPrevalentResource(hostName);
1096         WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isPrevalent));
1097         return result;
1098     }
1099     
1100     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsRegisteredAsSubFrameUnder")) {
1101         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1102         
1103         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1104         WKRetainPtr<WKStringRef> subFrameHostKey(AdoptWK, WKStringCreateWithUTF8CString("SubFrameHost"));
1105         WKRetainPtr<WKStringRef> topFrameHostKey(AdoptWK, WKStringCreateWithUTF8CString("TopFrameHost"));
1106         
1107         WKStringRef subFrameHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, subFrameHostKey.get()));
1108         WKStringRef topFrameHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostKey.get()));
1109
1110         bool isRegisteredAsSubFrameUnder = TestController::singleton().isStatisticsRegisteredAsSubFrameUnder(subFrameHost, topFrameHost);
1111         WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isRegisteredAsSubFrameUnder));
1112         return result;
1113     }
1114     
1115     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsRegisteredAsRedirectingTo")) {
1116         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1117         
1118         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1119         WKRetainPtr<WKStringRef> hostRedirectedFromKey(AdoptWK, WKStringCreateWithUTF8CString("HostRedirectedFrom"));
1120         WKRetainPtr<WKStringRef> hostRedirectedToKey(AdoptWK, WKStringCreateWithUTF8CString("HostRedirectedTo"));
1121         
1122         WKStringRef hostRedirectedFrom = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostRedirectedFromKey.get()));
1123         WKStringRef hostRedirectedTo = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostRedirectedToKey.get()));
1124         
1125         bool isRegisteredAsRedirectingTo = TestController::singleton().isStatisticsRegisteredAsRedirectingTo(hostRedirectedFrom, hostRedirectedTo);
1126         WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isRegisteredAsRedirectingTo));
1127         return result;
1128     }
1129     
1130     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsHasHadUserInteraction")) {
1131         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1132         
1133         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1134         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1135         WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
1136         
1137         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1138         WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1139         
1140         TestController::singleton().setStatisticsHasHadUserInteraction(hostName, WKBooleanGetValue(value));
1141         return nullptr;
1142     }
1143
1144     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsHasHadNonRecentUserInteraction")) {
1145         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1146         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1147         TestController::singleton().setStatisticsHasHadNonRecentUserInteraction(hostName);
1148         return nullptr;
1149     }
1150
1151     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsHasHadUserInteraction")) {
1152         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1153         
1154         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1155         bool hasHadUserInteraction = TestController::singleton().isStatisticsHasHadUserInteraction(hostName);
1156         WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(hasHadUserInteraction));
1157         return result;
1158     }
1159     
1160     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsGrandfathered")) {
1161         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1162         
1163         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1164         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1165         WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
1166         
1167         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1168         WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1169         
1170         TestController::singleton().setStatisticsGrandfathered(hostName, WKBooleanGetValue(value));
1171         return nullptr;
1172     }
1173     
1174     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsGrandfathered")) {
1175         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1176         
1177         WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1178         bool isGrandfathered = TestController::singleton().isStatisticsGrandfathered(hostName);
1179         WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isGrandfathered));
1180         return result;
1181     }
1182     
1183     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubframeUnderTopFrameOrigin")) {
1184         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1185         
1186         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1187         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1188         WKRetainPtr<WKStringRef> topFrameHostNameKey(AdoptWK, WKStringCreateWithUTF8CString("TopFrameHostName"));
1189         
1190         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1191         WKStringRef topFrameHostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostNameKey.get()));
1192
1193         TestController::singleton().setStatisticsSubframeUnderTopFrameOrigin(hostName, topFrameHostName);
1194         return nullptr;
1195     }
1196     
1197     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubresourceUnderTopFrameOrigin")) {
1198         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1199         
1200         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1201         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1202         WKRetainPtr<WKStringRef> topFrameHostNameKey(AdoptWK, WKStringCreateWithUTF8CString("TopFrameHostName"));
1203         
1204         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1205         WKStringRef topFrameHostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostNameKey.get()));
1206         
1207         TestController::singleton().setStatisticsSubresourceUnderTopFrameOrigin(hostName, topFrameHostName);
1208         return nullptr;
1209     }
1210     
1211     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubresourceUniqueRedirectTo")) {
1212         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1213         
1214         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1215         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1216         WKRetainPtr<WKStringRef> hostNameRedirectedToKey(AdoptWK, WKStringCreateWithUTF8CString("HostNameRedirectedTo"));
1217         
1218         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1219         WKStringRef hostNameRedirectedTo = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedToKey.get()));
1220         
1221         TestController::singleton().setStatisticsSubresourceUniqueRedirectTo(hostName, hostNameRedirectedTo);
1222         return nullptr;
1223     }
1224
1225     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubresourceUniqueRedirectFrom")) {
1226         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1227         
1228         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1229         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1230         WKRetainPtr<WKStringRef> hostNameRedirectedFromKey(AdoptWK, WKStringCreateWithUTF8CString("HostNameRedirectedFrom"));
1231         
1232         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1233         WKStringRef hostNameRedirectedFrom = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedFromKey.get()));
1234         
1235         TestController::singleton().setStatisticsSubresourceUniqueRedirectFrom(hostName, hostNameRedirectedFrom);
1236         return nullptr;
1237     }
1238     
1239     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTopFrameUniqueRedirectTo")) {
1240         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1241         
1242         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1243         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1244         WKRetainPtr<WKStringRef> hostNameRedirectedToKey(AdoptWK, WKStringCreateWithUTF8CString("HostNameRedirectedTo"));
1245         
1246         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1247         WKStringRef hostNameRedirectedTo = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedToKey.get()));
1248         
1249         TestController::singleton().setStatisticsTopFrameUniqueRedirectTo(hostName, hostNameRedirectedTo);
1250         return nullptr;
1251     }
1252     
1253     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTopFrameUniqueRedirectFrom")) {
1254         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1255         
1256         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1257         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1258         WKRetainPtr<WKStringRef> hostNameRedirectedFromKey(AdoptWK, WKStringCreateWithUTF8CString("HostNameRedirectedFrom"));
1259         
1260         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1261         WKStringRef hostNameRedirectedFrom = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedFromKey.get()));
1262         
1263         TestController::singleton().setStatisticsTopFrameUniqueRedirectFrom(hostName, hostNameRedirectedFrom);
1264         return nullptr;
1265     }
1266     
1267     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTimeToLiveUserInteraction")) {
1268         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1269         WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1270         TestController::singleton().setStatisticsTimeToLiveUserInteraction(WKDoubleGetValue(seconds));
1271         return nullptr;
1272     }
1273     
1274     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTimeToLiveCookiePartitionFree")) {
1275         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1276         WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1277         TestController::singleton().setStatisticsTimeToLiveCookiePartitionFree(WKDoubleGetValue(seconds));
1278         return nullptr;
1279     }
1280
1281     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsProcessStatisticsAndDataRecords")) {
1282         TestController::singleton().statisticsProcessStatisticsAndDataRecords();
1283         return nullptr;
1284     }
1285     
1286     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsUpdateCookiePartitioning")) {
1287         TestController::singleton().statisticsUpdateCookiePartitioning();
1288         return nullptr;
1289     }
1290
1291     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsSetShouldPartitionCookiesForHost")) {
1292         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1293         
1294         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1295         WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
1296         WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
1297         
1298         WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1299         WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1300         
1301         TestController::singleton().statisticsSetShouldPartitionCookiesForHost(hostName, WKBooleanGetValue(value));
1302         return nullptr;
1303     }
1304     
1305     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsSubmitTelemetry")) {
1306         TestController::singleton().statisticsSubmitTelemetry();
1307         return nullptr;
1308     }
1309     
1310     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsNotifyPagesWhenDataRecordsWereScanned")) {
1311         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1312         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1313         TestController::singleton().setStatisticsNotifyPagesWhenDataRecordsWereScanned(WKBooleanGetValue(value));
1314         return nullptr;
1315     }
1316
1317     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsNotifyPagesWhenTelemetryWasCaptured")) {
1318         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1319         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1320         TestController::singleton().setStatisticsNotifyPagesWhenTelemetryWasCaptured(WKBooleanGetValue(value));
1321         return nullptr;
1322     }
1323     
1324     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval")) {
1325         ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1326         WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1327         TestController::singleton().setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(WKBooleanGetValue(value));
1328         return nullptr;
1329     }
1330
1331     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsMinimumTimeBetweenDataRecordsRemoval")) {
1332         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1333         WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1334         TestController::singleton().setStatisticsMinimumTimeBetweenDataRecordsRemoval(WKDoubleGetValue(seconds));
1335         return nullptr;
1336     }
1337     
1338     if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsGrandfatheringTime")) {
1339         ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1340         WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1341         TestController::singleton().setStatisticsGrandfatheringTime(WKDoubleGetValue(seconds));
1342         return nullptr;
1343     }
1344     
1345     if (WKStringIsEqualToUTF8CString(messageName, "SetMaxStatisticsEntries")) {
1346         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1347         WKUInt64Ref entries = static_cast<WKUInt64Ref>(messageBody);
1348         TestController::singleton().setStatisticsMaxStatisticsEntries(WKUInt64GetValue(entries));
1349         return nullptr;
1350     }
1351     
1352     if (WKStringIsEqualToUTF8CString(messageName, "SetPruneEntriesDownTo")) {
1353         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1354         WKUInt64Ref entries = static_cast<WKUInt64Ref>(messageBody);
1355         TestController::singleton().setStatisticsPruneEntriesDownTo(WKUInt64GetValue(entries));
1356         return nullptr;
1357     }
1358     
1359     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsClearInMemoryAndPersistentStore")) {
1360         TestController::singleton().statisticsClearInMemoryAndPersistentStore();
1361         return nullptr;
1362     }
1363     
1364     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsClearInMemoryAndPersistentStoreModifiedSinceHours")) {
1365         ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1366         WKUInt64Ref hours = static_cast<WKUInt64Ref>(messageBody);
1367         TestController::singleton().statisticsClearInMemoryAndPersistentStoreModifiedSinceHours(WKUInt64GetValue(hours));
1368         return nullptr;
1369     }
1370     
1371     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsClearThroughWebsiteDataRemoval")) {
1372         TestController::singleton().statisticsClearThroughWebsiteDataRemoval();
1373         return nullptr;
1374     }
1375     
1376     if (WKStringIsEqualToUTF8CString(messageName, "StatisticsResetToConsistentState")) {
1377         TestController::singleton().statisticsResetToConsistentState();
1378         return nullptr;
1379     }
1380
1381     if (WKStringIsEqualToUTF8CString(messageName, "RemoveAllSessionCredentials")) {
1382         TestController::singleton().removeAllSessionCredentials();
1383         return nullptr;
1384     }
1385
1386     if (WKStringIsEqualToUTF8CString(messageName, "ClearDOMCache")) {
1387         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1388         WKStringRef origin = static_cast<WKStringRef>(messageBody);
1389
1390         TestController::singleton().clearDOMCache(origin);
1391         return nullptr;
1392     }
1393
1394     if (WKStringIsEqualToUTF8CString(messageName, "ClearDOMCaches")) {
1395         TestController::singleton().clearDOMCaches();
1396         return nullptr;
1397     }
1398
1399     if (WKStringIsEqualToUTF8CString(messageName, "HasDOMCache")) {
1400         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1401         WKStringRef origin = static_cast<WKStringRef>(messageBody);
1402
1403         bool hasDOMCache = TestController::singleton().hasDOMCache(origin);
1404         WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(hasDOMCache));
1405         return result;
1406     }
1407
1408     if (WKStringIsEqualToUTF8CString(messageName, "DOMCacheSize")) {
1409         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1410         WKStringRef origin = static_cast<WKStringRef>(messageBody);
1411
1412         auto domCacheSize = TestController::singleton().domCacheSize(origin);
1413         WKRetainPtr<WKTypeRef> result(AdoptWK, WKUInt64Create(domCacheSize));
1414         return result;
1415     }
1416
1417     if (WKStringIsEqualToUTF8CString(messageName, "InjectUserScript")) {
1418         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1419         WKStringRef script = static_cast<WKStringRef>(messageBody);
1420
1421         TestController::singleton().injectUserScript(script);
1422         return nullptr;
1423     }
1424
1425     if (WKStringIsEqualToUTF8CString(messageName, "GetApplicationManifest")) {
1426 #ifdef __BLOCKS__
1427         WKPageGetApplicationManifest_b(TestController::singleton().mainWebView()->page(), ^{
1428             WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("DidGetApplicationManifest"));
1429             WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1430         });
1431 #else
1432         // FIXME: Add API for loading the manifest on non-__BLOCKS__ ports.
1433         ASSERT_NOT_REACHED();
1434 #endif
1435         return nullptr;
1436     }
1437
1438     ASSERT_NOT_REACHED();
1439     return nullptr;
1440 }
1441
1442 void TestInvocation::runUISideScriptAfterUpdateCallback(WKErrorRef, void* context)
1443 {
1444     UIScriptInvocationData* data = static_cast<UIScriptInvocationData*>(context);
1445     if (TestInvocation* invocation = data->testInvocation) {
1446         RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(invocation));
1447         invocation->runUISideScript(data->scriptString.get(), data->callbackID);
1448     }
1449     delete data;
1450 }
1451
1452 void TestInvocation::runUISideScript(WKStringRef script, unsigned scriptCallbackID)
1453 {
1454     m_pendingUIScriptInvocationData = nullptr;
1455
1456     if (!m_UIScriptContext)
1457         m_UIScriptContext = std::make_unique<UIScriptContext>(*this);
1458     
1459     m_UIScriptContext->runUIScript(toWTFString(script), scriptCallbackID);
1460 }
1461
1462 void TestInvocation::uiScriptDidComplete(const String& result, unsigned scriptCallbackID)
1463 {
1464     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallUISideScriptCallback"));
1465
1466     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
1467     WKRetainPtr<WKStringRef> resultKey(AdoptWK, WKStringCreateWithUTF8CString("Result"));
1468     WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID"));
1469     WKRetainPtr<WKUInt64Ref> callbackIDValue = adoptWK(WKUInt64Create(scriptCallbackID));
1470
1471     WKDictionarySetItem(messageBody.get(), resultKey.get(), toWK(result).get());
1472     WKDictionarySetItem(messageBody.get(), callbackIDKey.get(), callbackIDValue.get());
1473
1474     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), messageBody.get());
1475 }
1476
1477 void TestInvocation::outputText(const WTF::String& text)
1478 {
1479     m_textOutput.append(text);
1480 }
1481
1482 void TestInvocation::didBeginSwipe()
1483 {
1484     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidBeginSwipeCallback"));
1485     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1486 }
1487
1488 void TestInvocation::willEndSwipe()
1489 {
1490     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallWillEndSwipeCallback"));
1491     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1492 }
1493
1494 void TestInvocation::didEndSwipe()
1495 {
1496     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidEndSwipeCallback"));
1497     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1498 }
1499
1500 void TestInvocation::didRemoveSwipeSnapshot()
1501 {
1502     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidRemoveSwipeSnapshotCallback"));
1503     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1504 }
1505
1506 void TestInvocation::notifyDownloadDone()
1507 {
1508     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("NotifyDownloadDone"));
1509     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1510 }
1511
1512 void TestInvocation::didClearStatisticsThroughWebsiteDataRemoval()
1513 {
1514     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidClearStatisticsThroughWebsiteDataRemoval"));
1515     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1516 }
1517
1518 void TestInvocation::didResetStatisticsToConsistentState()
1519 {
1520     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidResetStatisticsToConsistentState"));
1521     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1522 }
1523
1524 void TestInvocation::didSetPartitionOrBlockCookiesForHost()
1525 {
1526     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetPartitionOrBlockCookiesForHost"));
1527     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1528 }
1529
1530 void TestInvocation::didSetLastSeen()
1531 {
1532     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetLastSeen"));
1533     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1534 }
1535
1536 void TestInvocation::didSetPrevalentResource()
1537 {
1538     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetPrevalentResource"));
1539     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1540 }
1541
1542 void TestInvocation::didSetVeryPrevalentResource()
1543 {
1544     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetVeryPrevalentResource"));
1545     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1546 }
1547
1548 void TestInvocation::didSetHasHadUserInteraction()
1549 {
1550     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetHasHadUserInteraction"));
1551     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1552 }
1553
1554 void TestInvocation::didSetHasHadNonRecentUserInteraction()
1555 {
1556     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetHasHadNonRecentUserInteraction"));
1557     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1558 }
1559
1560 void TestInvocation::didReceiveAllStorageAccessEntries(Vector<String>& domains)
1561 {
1562     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidReceiveAllStorageAccessEntries"));
1563     
1564     WKRetainPtr<WKMutableArrayRef> messageBody(AdoptWK, WKMutableArrayCreate());
1565     for (auto& domain : domains)
1566         WKArrayAppendItem(messageBody.get(), adoptWK(WKStringCreateWithUTF8CString(domain.utf8().data())).get());
1567     
1568     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), messageBody.get());
1569 }
1570
1571 void TestInvocation::didRemoveAllSessionCredentials()
1572 {
1573     WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidRemoveAllSessionCredentialsCallback"));
1574     WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1575 }
1576
1577 } // namespace WTR