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 <wtf/StdLibExtras.h>
46#include <wtf/text/CString.h>
47
48#if PLATFORM(MAC) && !PLATFORM(IOS_FAMILY)
49#include <Carbon/Carbon.h>
50#endif
51
52#if PLATFORM(COCOA)
53#include <WebKit/WKPagePrivateMac.h>
54#endif
55
56#if PLATFORM(WIN)
57#include <io.h>
58#define isatty _isatty
59#else
60#include <unistd.h>
61#endif
62
63using namespace JSC;
64using namespace WebKit;
65using namespace std;
66
67namespace WTR {
68
69TestInvocation::TestInvocation(WKURLRef url, const TestOptions& options)
70 : m_options(options)
71 , m_url(url)
72 , m_waitToDumpWatchdogTimer(RunLoop::main(), this, &TestInvocation::waitToDumpWatchdogTimerFired)
73{
74 WKRetainPtr<WKStringRef> urlString = adoptWK(WKURLCopyString(m_url.get()));
75
76 size_t stringLength = WKStringGetLength(urlString.get());
77
78 Vector<char> urlVector;
79 urlVector.resize(stringLength + 1);
80
81 WKStringGetUTF8CString(urlString.get(), urlVector.data(), stringLength + 1);
82
83 m_urlString = String(urlVector.data(), stringLength);
84
85 // FIXME: Avoid mutating the setting via a test directory like this.
86 m_dumpFrameLoadCallbacks = urlContains("loading/");
87}
88
89TestInvocation::~TestInvocation()
90{
91 if (m_pendingUIScriptInvocationData)
92 m_pendingUIScriptInvocationData->testInvocation = nullptr;
93}
94
95WKURLRef TestInvocation::url() const
96{
97 return m_url.get();
98}
99
100bool TestInvocation::urlContains(const char* searchString) const
101{
102 return m_urlString.containsIgnoringASCIICase(searchString);
103}
104
105void TestInvocation::setIsPixelTest(const std::string& expectedPixelHash)
106{
107 m_dumpPixels = true;
108 m_expectedPixelHash = expectedPixelHash;
109}
110
111WTF::Seconds TestInvocation::shortTimeout() const
112{
113 if (!m_timeout) {
114 // Running WKTR directly, without webkitpy.
115 return TestController::defaultShortTimeout;
116 }
117
118 // This is not exactly correct for the way short timeout is used - it should not depend on whether a test is "slow",
119 // but it currently does. There is no way to know what a normal test's timeout is, as webkitpy only passes timeouts
120 // for each test individually.
121 // But there shouldn't be any observable negative consequences from this.
122 return m_timeout / 4;
123}
124
125bool TestInvocation::shouldLogHistoryClientCallbacks() const
126{
127 return urlContains("globalhistory/");
128}
129
130WKRetainPtr<WKMutableDictionaryRef> TestInvocation::createTestSettingsDictionary()
131{
132 WKRetainPtr<WKMutableDictionaryRef> beginTestMessageBody = adoptWK(WKMutableDictionaryCreate());
133
134 WKRetainPtr<WKStringRef> useFlexibleViewportKey = adoptWK(WKStringCreateWithUTF8CString("UseFlexibleViewport"));
135 WKRetainPtr<WKBooleanRef> useFlexibleViewportValue = adoptWK(WKBooleanCreate(options().useFlexibleViewport));
136 WKDictionarySetItem(beginTestMessageBody.get(), useFlexibleViewportKey.get(), useFlexibleViewportValue.get());
137
138 WKRetainPtr<WKStringRef> dumpPixelsKey = adoptWK(WKStringCreateWithUTF8CString("DumpPixels"));
139 WKRetainPtr<WKBooleanRef> dumpPixelsValue = adoptWK(WKBooleanCreate(m_dumpPixels));
140 WKDictionarySetItem(beginTestMessageBody.get(), dumpPixelsKey.get(), dumpPixelsValue.get());
141
142 WKRetainPtr<WKStringRef> timeoutKey = adoptWK(WKStringCreateWithUTF8CString("Timeout"));
143 WKRetainPtr<WKUInt64Ref> timeoutValue = adoptWK(WKUInt64Create(m_timeout.milliseconds()));
144 WKDictionarySetItem(beginTestMessageBody.get(), timeoutKey.get(), timeoutValue.get());
145
146 WKRetainPtr<WKStringRef> dumpJSConsoleLogInStdErrKey = adoptWK(WKStringCreateWithUTF8CString("DumpJSConsoleLogInStdErr"));
147 WKRetainPtr<WKBooleanRef> dumpJSConsoleLogInStdErrValue = adoptWK(WKBooleanCreate(m_dumpJSConsoleLogInStdErr));
148 WKDictionarySetItem(beginTestMessageBody.get(), dumpJSConsoleLogInStdErrKey.get(), dumpJSConsoleLogInStdErrValue.get());
149
150 WKRetainPtr<WKStringRef> additionalSupportedImageTypesKey = adoptWK(WKStringCreateWithUTF8CString("additionalSupportedImageTypes"));
151 WKRetainPtr<WKStringRef> additionalSupportedImageTypesValue = adoptWK(WKStringCreateWithUTF8CString(options().additionalSupportedImageTypes.c_str()));
152 WKDictionarySetItem(beginTestMessageBody.get(), additionalSupportedImageTypesKey.get(), additionalSupportedImageTypesValue.get());
153
154 return beginTestMessageBody;
155}
156
157void TestInvocation::invoke()
158{
159 TestController::singleton().configureViewForTest(*this);
160
161 WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), false);
162
163 m_textOutput.clear();
164
165 TestController::singleton().setShouldLogHistoryClientCallbacks(shouldLogHistoryClientCallbacks());
166
167 WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain);
168
169 // FIXME: We should clear out visited links here.
170
171 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("BeginTest"));
172 auto beginTestMessageBody = createTestSettingsDictionary();
173 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), beginTestMessageBody.get());
174
175 m_startedTesting = true;
176
177 bool shouldOpenExternalURLs = false;
178
179 TestController::singleton().runUntil(m_gotInitialResponse, TestController::noTimeout);
180 if (m_error)
181 goto end;
182
183 WKPageLoadURLWithShouldOpenExternalURLsPolicy(TestController::singleton().mainWebView()->page(), m_url.get(), shouldOpenExternalURLs);
184
185 TestController::singleton().runUntil(m_gotFinalMessage, TestController::noTimeout);
186 if (m_error)
187 goto end;
188
189 dumpResults();
190
191end:
192#if !PLATFORM(IOS_FAMILY)
193 if (m_gotInitialResponse)
194 WKInspectorClose(WKPageGetInspector(TestController::singleton().mainWebView()->page()));
195#endif // !PLATFORM(IOS_FAMILY)
196
197 if (TestController::singleton().resetStateToConsistentValues(m_options, TestController::ResetStage::AfterTest))
198 return;
199
200 // The process is unresponsive, so let's start a new one.
201 TestController::singleton().terminateWebContentProcess();
202 // Make sure that we have a process, as invoke() will need one to send bundle messages for the next test.
203 TestController::singleton().reattachPageToWebProcess();
204}
205
206void TestInvocation::dumpWebProcessUnresponsiveness(const char* errorMessage)
207{
208 fprintf(stderr, "%s", errorMessage);
209 char buffer[1024] = { };
210#if PLATFORM(COCOA)
211 pid_t pid = WKPageGetProcessIdentifier(TestController::singleton().mainWebView()->page());
212 snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s (pid %ld)\n", TestController::webProcessName(), static_cast<long>(pid));
213#else
214 snprintf(buffer, sizeof(buffer), "#PROCESS UNRESPONSIVE - %s\n", TestController::webProcessName());
215#endif
216
217 dump(errorMessage, buffer, true);
218
219 if (!TestController::singleton().usingServerMode())
220 return;
221
222 if (isatty(fileno(stdin)) || isatty(fileno(stderr)))
223 fputs("Grab an image of the stack, then hit enter...\n", stderr);
224
225 if (!fgets(buffer, sizeof(buffer), stdin) || strcmp(buffer, "#SAMPLE FINISHED\n"))
226 fprintf(stderr, "Failed receive expected sample response, got:\n\t\"%s\"\nContinuing...\n", buffer);
227}
228
229void TestInvocation::dump(const char* textToStdout, const char* textToStderr, bool seenError)
230{
231 printf("Content-Type: text/plain\n");
232 if (textToStdout)
233 fputs(textToStdout, stdout);
234 if (textToStderr)
235 fputs(textToStderr, stderr);
236
237 fputs("#EOF\n", stdout);
238 fputs("#EOF\n", stderr);
239 if (seenError)
240 fputs("#EOF\n", stdout);
241 fflush(stdout);
242 fflush(stderr);
243}
244
245void TestInvocation::forceRepaintDoneCallback(WKErrorRef error, void* context)
246{
247 // The context may not be valid any more, e.g. if WebKit is invalidating callbacks at process exit.
248 if (error)
249 return;
250
251 TestInvocation* testInvocation = static_cast<TestInvocation*>(context);
252 RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(testInvocation));
253
254 testInvocation->m_gotRepaint = true;
255 TestController::singleton().notifyDone();
256}
257
258void TestInvocation::dumpResults()
259{
260 if (m_shouldDumpResourceLoadStatistics)
261 m_textOutput.append(m_savedResourceLoadStatistics.isNull() ? TestController::singleton().dumpResourceLoadStatistics() : m_savedResourceLoadStatistics);
262
263 if (m_shouldDumpAdClickAttribution)
264 m_textOutput.append(TestController::singleton().dumpAdClickAttribution());
265
266 if (m_textOutput.length() || !m_audioResult)
267 dump(m_textOutput.toString().utf8().data());
268 else
269 dumpAudio(m_audioResult.get());
270
271 if (m_dumpPixels) {
272 if (m_pixelResult)
273 dumpPixelsAndCompareWithExpected(SnapshotResultType::WebContents, m_repaintRects.get(), m_pixelResult.get());
274 else if (m_pixelResultIsPending) {
275 m_gotRepaint = false;
276 WKPageForceRepaint(TestController::singleton().mainWebView()->page(), this, TestInvocation::forceRepaintDoneCallback);
277 TestController::singleton().runUntil(m_gotRepaint, TestController::noTimeout);
278 dumpPixelsAndCompareWithExpected(SnapshotResultType::WebView, m_repaintRects.get());
279 }
280 }
281
282 fputs("#EOF\n", stdout);
283 fflush(stdout);
284 fflush(stderr);
285}
286
287void TestInvocation::dumpAudio(WKDataRef audioData)
288{
289 size_t length = WKDataGetSize(audioData);
290 if (!length)
291 return;
292
293 const unsigned char* data = WKDataGetBytes(audioData);
294
295 printf("Content-Type: audio/wav\n");
296 printf("Content-Length: %lu\n", static_cast<unsigned long>(length));
297
298 fwrite(data, 1, length, stdout);
299 printf("#EOF\n");
300 fprintf(stderr, "#EOF\n");
301}
302
303bool TestInvocation::compareActualHashToExpectedAndDumpResults(const char actualHash[33])
304{
305 // Compute the hash of the bitmap context pixels
306 fprintf(stdout, "\nActualHash: %s\n", actualHash);
307
308 if (!m_expectedPixelHash.length())
309 return false;
310
311 ASSERT(m_expectedPixelHash.length() == 32);
312 fprintf(stdout, "\nExpectedHash: %s\n", m_expectedPixelHash.c_str());
313
314 // FIXME: Do case insensitive compare.
315 return m_expectedPixelHash == actualHash;
316}
317
318void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
319{
320 if (WKStringIsEqualToUTF8CString(messageName, "Error")) {
321 // Set all states to true to stop spinning the runloop.
322 m_gotInitialResponse = true;
323 m_gotFinalMessage = true;
324 m_error = true;
325 TestController::singleton().notifyDone();
326 return;
327 }
328
329 if (WKStringIsEqualToUTF8CString(messageName, "Ack")) {
330 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
331 WKStringRef messageBodyString = static_cast<WKStringRef>(messageBody);
332 if (WKStringIsEqualToUTF8CString(messageBodyString, "BeginTest")) {
333 m_gotInitialResponse = true;
334 TestController::singleton().notifyDone();
335 return;
336 }
337
338 ASSERT_NOT_REACHED();
339 }
340
341 if (WKStringIsEqualToUTF8CString(messageName, "Done")) {
342 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
343 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
344
345 WKRetainPtr<WKStringRef> pixelResultIsPendingKey = adoptWK(WKStringCreateWithUTF8CString("PixelResultIsPending"));
346 WKBooleanRef pixelResultIsPending = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultIsPendingKey.get()));
347 m_pixelResultIsPending = WKBooleanGetValue(pixelResultIsPending);
348
349 if (!m_pixelResultIsPending) {
350 WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
351 m_pixelResult = static_cast<WKImageRef>(WKDictionaryGetItemForKey(messageBodyDictionary, pixelResultKey.get()));
352 ASSERT(!m_pixelResult || m_dumpPixels);
353 }
354
355 WKRetainPtr<WKStringRef> repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects"));
356 m_repaintRects = static_cast<WKArrayRef>(WKDictionaryGetItemForKey(messageBodyDictionary, repaintRectsKey.get()));
357
358 WKRetainPtr<WKStringRef> audioResultKey = adoptWK(WKStringCreateWithUTF8CString("AudioResult"));
359 m_audioResult = static_cast<WKDataRef>(WKDictionaryGetItemForKey(messageBodyDictionary, audioResultKey.get()));
360
361 done();
362 return;
363 }
364
365 if (WKStringIsEqualToUTF8CString(messageName, "TextOutput")) {
366 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
367 WKStringRef textOutput = static_cast<WKStringRef>(messageBody);
368 m_textOutput.append(toWTFString(textOutput));
369 return;
370 }
371
372 if (WKStringIsEqualToUTF8CString(messageName, "DumpToStdErr")) {
373 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
374 WKStringRef textOutput = static_cast<WKStringRef>(messageBody);
375 fprintf(stderr, "%s", toWTFString(textOutput).utf8().data());
376 return;
377 }
378
379 if (WKStringIsEqualToUTF8CString(messageName, "BeforeUnloadReturnValue")) {
380 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
381 WKBooleanRef beforeUnloadReturnValue = static_cast<WKBooleanRef>(messageBody);
382 TestController::singleton().setBeforeUnloadReturnValue(WKBooleanGetValue(beforeUnloadReturnValue));
383 return;
384 }
385
386 if (WKStringIsEqualToUTF8CString(messageName, "AddChromeInputField")) {
387 TestController::singleton().mainWebView()->addChromeInputField();
388 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallAddChromeInputFieldCallback"));
389 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
390 return;
391 }
392
393 if (WKStringIsEqualToUTF8CString(messageName, "RemoveChromeInputField")) {
394 TestController::singleton().mainWebView()->removeChromeInputField();
395 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallRemoveChromeInputFieldCallback"));
396 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
397 return;
398 }
399
400 if (WKStringIsEqualToUTF8CString(messageName, "FocusWebView")) {
401 TestController::singleton().mainWebView()->makeWebViewFirstResponder();
402 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallFocusWebViewCallback"));
403 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
404 return;
405 }
406
407 if (WKStringIsEqualToUTF8CString(messageName, "SetBackingScaleFactor")) {
408 ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
409 double backingScaleFactor = WKDoubleGetValue(static_cast<WKDoubleRef>(messageBody));
410 WKPageSetCustomBackingScaleFactor(TestController::singleton().mainWebView()->page(), backingScaleFactor);
411
412 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallSetBackingScaleFactorCallback"));
413 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
414 return;
415 }
416
417 if (WKStringIsEqualToUTF8CString(messageName, "SimulateWebNotificationClick")) {
418 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
419 uint64_t notificationID = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
420 TestController::singleton().simulateWebNotificationClick(notificationID);
421 return;
422 }
423
424 if (WKStringIsEqualToUTF8CString(messageName, "SetAddsVisitedLinks")) {
425 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
426 WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
427 WKPageSetAddsVisitedLinks(TestController::singleton().mainWebView()->page(), WKBooleanGetValue(enabledWK));
428 return;
429 }
430
431 if (WKStringIsEqualToUTF8CString(messageName, "SetGeolocationPermission")) {
432 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
433 WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
434 TestController::singleton().setGeolocationPermission(WKBooleanGetValue(enabledWK));
435 return;
436 }
437
438 if (WKStringIsEqualToUTF8CString(messageName, "SetMockGeolocationPosition")) {
439 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
440 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
441
442 WKRetainPtr<WKStringRef> latitudeKeyWK = adoptWK(WKStringCreateWithUTF8CString("latitude"));
443 WKDoubleRef latitudeWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, latitudeKeyWK.get()));
444 double latitude = WKDoubleGetValue(latitudeWK);
445
446 WKRetainPtr<WKStringRef> longitudeKeyWK = adoptWK(WKStringCreateWithUTF8CString("longitude"));
447 WKDoubleRef longitudeWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, longitudeKeyWK.get()));
448 double longitude = WKDoubleGetValue(longitudeWK);
449
450 WKRetainPtr<WKStringRef> accuracyKeyWK = adoptWK(WKStringCreateWithUTF8CString("accuracy"));
451 WKDoubleRef accuracyWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, accuracyKeyWK.get()));
452 double accuracy = WKDoubleGetValue(accuracyWK);
453
454 WKRetainPtr<WKStringRef> providesAltitudeKeyWK = adoptWK(WKStringCreateWithUTF8CString("providesAltitude"));
455 WKBooleanRef providesAltitudeWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesAltitudeKeyWK.get()));
456 bool providesAltitude = WKBooleanGetValue(providesAltitudeWK);
457
458 WKRetainPtr<WKStringRef> altitudeKeyWK = adoptWK(WKStringCreateWithUTF8CString("altitude"));
459 WKDoubleRef altitudeWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, altitudeKeyWK.get()));
460 double altitude = WKDoubleGetValue(altitudeWK);
461
462 WKRetainPtr<WKStringRef> providesAltitudeAccuracyKeyWK = adoptWK(WKStringCreateWithUTF8CString("providesAltitudeAccuracy"));
463 WKBooleanRef providesAltitudeAccuracyWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesAltitudeAccuracyKeyWK.get()));
464 bool providesAltitudeAccuracy = WKBooleanGetValue(providesAltitudeAccuracyWK);
465
466 WKRetainPtr<WKStringRef> altitudeAccuracyKeyWK = adoptWK(WKStringCreateWithUTF8CString("altitudeAccuracy"));
467 WKDoubleRef altitudeAccuracyWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, altitudeAccuracyKeyWK.get()));
468 double altitudeAccuracy = WKDoubleGetValue(altitudeAccuracyWK);
469
470 WKRetainPtr<WKStringRef> providesHeadingKeyWK = adoptWK(WKStringCreateWithUTF8CString("providesHeading"));
471 WKBooleanRef providesHeadingWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesHeadingKeyWK.get()));
472 bool providesHeading = WKBooleanGetValue(providesHeadingWK);
473
474 WKRetainPtr<WKStringRef> headingKeyWK = adoptWK(WKStringCreateWithUTF8CString("heading"));
475 WKDoubleRef headingWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, headingKeyWK.get()));
476 double heading = WKDoubleGetValue(headingWK);
477
478 WKRetainPtr<WKStringRef> providesSpeedKeyWK = adoptWK(WKStringCreateWithUTF8CString("providesSpeed"));
479 WKBooleanRef providesSpeedWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesSpeedKeyWK.get()));
480 bool providesSpeed = WKBooleanGetValue(providesSpeedWK);
481
482 WKRetainPtr<WKStringRef> speedKeyWK = adoptWK(WKStringCreateWithUTF8CString("speed"));
483 WKDoubleRef speedWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, speedKeyWK.get()));
484 double speed = WKDoubleGetValue(speedWK);
485
486 WKRetainPtr<WKStringRef> providesFloorLevelKeyWK = adoptWK(WKStringCreateWithUTF8CString("providesFloorLevel"));
487 WKBooleanRef providesFloorLevelWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, providesFloorLevelKeyWK.get()));
488 bool providesFloorLevel = WKBooleanGetValue(providesFloorLevelWK);
489
490 WKRetainPtr<WKStringRef> floorLevelKeyWK = adoptWK(WKStringCreateWithUTF8CString("floorLevel"));
491 WKDoubleRef floorLevelWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, floorLevelKeyWK.get()));
492 double floorLevel = WKDoubleGetValue(floorLevelWK);
493
494 TestController::singleton().setMockGeolocationPosition(latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed, providesFloorLevel, floorLevel);
495 return;
496 }
497
498 if (WKStringIsEqualToUTF8CString(messageName, "SetMockGeolocationPositionUnavailableError")) {
499 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
500 WKStringRef errorMessage = static_cast<WKStringRef>(messageBody);
501 TestController::singleton().setMockGeolocationPositionUnavailableError(errorMessage);
502 return;
503 }
504
505 if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPermission")) {
506 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
507 WKBooleanRef enabledWK = static_cast<WKBooleanRef>(messageBody);
508 TestController::singleton().setUserMediaPermission(WKBooleanGetValue(enabledWK));
509 return;
510 }
511
512 if (WKStringIsEqualToUTF8CString(messageName, "ResetUserMediaPermission")) {
513 TestController::singleton().resetUserMediaPermission();
514 return;
515 }
516
517 if (WKStringIsEqualToUTF8CString(messageName, "SetUserMediaPersistentPermissionForOrigin")) {
518 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
519 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
520
521 WKRetainPtr<WKStringRef> permissionKeyWK = adoptWK(WKStringCreateWithUTF8CString("permission"));
522 WKBooleanRef permissionWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissionKeyWK.get()));
523 bool permission = WKBooleanGetValue(permissionWK);
524
525 WKRetainPtr<WKStringRef> originKey = adoptWK(WKStringCreateWithUTF8CString("origin"));
526 WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
527
528 WKRetainPtr<WKStringRef> parentOriginKey = adoptWK(WKStringCreateWithUTF8CString("parentOrigin"));
529 WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
530
531 TestController::singleton().setUserMediaPersistentPermissionForOrigin(permission, originWK, parentOriginWK);
532 return;
533 }
534
535 if (WKStringIsEqualToUTF8CString(messageName, "ResetUserMediaPermissionRequestCountForOrigin")) {
536 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
537 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
538
539 WKRetainPtr<WKStringRef> originKey = adoptWK(WKStringCreateWithUTF8CString("origin"));
540 WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
541
542 WKRetainPtr<WKStringRef> parentOriginKey = adoptWK(WKStringCreateWithUTF8CString("parentOrigin"));
543 WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
544
545 TestController::singleton().resetUserMediaPermissionRequestCountForOrigin(originWK, parentOriginWK);
546 return;
547 }
548
549 if (WKStringIsEqualToUTF8CString(messageName, "SetCacheModel")) {
550 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
551 uint64_t model = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
552 WKContextSetCacheModel(TestController::singleton().context(), model);
553 return;
554 }
555
556 if (WKStringIsEqualToUTF8CString(messageName, "SetCustomPolicyDelegate")) {
557 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
558 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
559
560 WKRetainPtr<WKStringRef> enabledKeyWK = adoptWK(WKStringCreateWithUTF8CString("enabled"));
561 WKBooleanRef enabledWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, enabledKeyWK.get()));
562 bool enabled = WKBooleanGetValue(enabledWK);
563
564 WKRetainPtr<WKStringRef> permissiveKeyWK = adoptWK(WKStringCreateWithUTF8CString("permissive"));
565 WKBooleanRef permissiveWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, permissiveKeyWK.get()));
566 bool permissive = WKBooleanGetValue(permissiveWK);
567
568 TestController::singleton().setCustomPolicyDelegate(enabled, permissive);
569 return;
570 }
571
572 if (WKStringIsEqualToUTF8CString(messageName, "SetHidden")) {
573 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
574 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
575
576 WKRetainPtr<WKStringRef> isInitialKeyWK = adoptWK(WKStringCreateWithUTF8CString("hidden"));
577 WKBooleanRef hiddenWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, isInitialKeyWK.get()));
578 bool hidden = WKBooleanGetValue(hiddenWK);
579
580 TestController::singleton().setHidden(hidden);
581 return;
582 }
583
584 if (WKStringIsEqualToUTF8CString(messageName, "ProcessWorkQueue")) {
585 if (TestController::singleton().workQueueManager().processWorkQueue()) {
586 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("WorkQueueProcessedCallback"));
587 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
588 }
589 return;
590 }
591
592 if (WKStringIsEqualToUTF8CString(messageName, "QueueBackNavigation")) {
593 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
594 uint64_t stepCount = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
595 TestController::singleton().workQueueManager().queueBackNavigation(stepCount);
596 return;
597 }
598
599 if (WKStringIsEqualToUTF8CString(messageName, "QueueForwardNavigation")) {
600 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
601 uint64_t stepCount = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
602 TestController::singleton().workQueueManager().queueForwardNavigation(stepCount);
603 return;
604 }
605
606 if (WKStringIsEqualToUTF8CString(messageName, "QueueLoad")) {
607 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
608 WKDictionaryRef loadDataDictionary = static_cast<WKDictionaryRef>(messageBody);
609
610 WKRetainPtr<WKStringRef> urlKey = adoptWK(WKStringCreateWithUTF8CString("url"));
611 WKStringRef urlWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, urlKey.get()));
612
613 WKRetainPtr<WKStringRef> targetKey = adoptWK(WKStringCreateWithUTF8CString("target"));
614 WKStringRef targetWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, targetKey.get()));
615
616 WKRetainPtr<WKStringRef> shouldOpenExternalURLsKey = adoptWK(WKStringCreateWithUTF8CString("shouldOpenExternalURLs"));
617 WKBooleanRef shouldOpenExternalURLsValueWK = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(loadDataDictionary, shouldOpenExternalURLsKey.get()));
618
619 TestController::singleton().workQueueManager().queueLoad(toWTFString(urlWK), toWTFString(targetWK), WKBooleanGetValue(shouldOpenExternalURLsValueWK));
620 return;
621 }
622
623 if (WKStringIsEqualToUTF8CString(messageName, "QueueLoadHTMLString")) {
624 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
625 WKDictionaryRef loadDataDictionary = static_cast<WKDictionaryRef>(messageBody);
626
627 WKRetainPtr<WKStringRef> contentKey = adoptWK(WKStringCreateWithUTF8CString("content"));
628 WKStringRef contentWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, contentKey.get()));
629
630 WKRetainPtr<WKStringRef> baseURLKey = adoptWK(WKStringCreateWithUTF8CString("baseURL"));
631 WKStringRef baseURLWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, baseURLKey.get()));
632
633 WKRetainPtr<WKStringRef> unreachableURLKey = adoptWK(WKStringCreateWithUTF8CString("unreachableURL"));
634 WKStringRef unreachableURLWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(loadDataDictionary, unreachableURLKey.get()));
635
636 TestController::singleton().workQueueManager().queueLoadHTMLString(toWTFString(contentWK), baseURLWK ? toWTFString(baseURLWK) : String(), unreachableURLWK ? toWTFString(unreachableURLWK) : String());
637 return;
638 }
639
640 if (WKStringIsEqualToUTF8CString(messageName, "QueueReload")) {
641 TestController::singleton().workQueueManager().queueReload();
642 return;
643 }
644
645 if (WKStringIsEqualToUTF8CString(messageName, "QueueLoadingScript")) {
646 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
647 WKStringRef script = static_cast<WKStringRef>(messageBody);
648 TestController::singleton().workQueueManager().queueLoadingScript(toWTFString(script));
649 return;
650 }
651
652 if (WKStringIsEqualToUTF8CString(messageName, "QueueNonLoadingScript")) {
653 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
654 WKStringRef script = static_cast<WKStringRef>(messageBody);
655 TestController::singleton().workQueueManager().queueNonLoadingScript(toWTFString(script));
656 return;
657 }
658
659 if (WKStringIsEqualToUTF8CString(messageName, "SetRejectsProtectionSpaceAndContinueForAuthenticationChallenges")) {
660 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
661 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
662 TestController::singleton().setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(WKBooleanGetValue(value));
663 return;
664 }
665
666 if (WKStringIsEqualToUTF8CString(messageName, "SetHandlesAuthenticationChallenges")) {
667 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
668 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
669 TestController::singleton().setHandlesAuthenticationChallenges(WKBooleanGetValue(value));
670 return;
671 }
672
673 if (WKStringIsEqualToUTF8CString(messageName, "SetShouldLogCanAuthenticateAgainstProtectionSpace")) {
674 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
675 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
676 TestController::singleton().setShouldLogCanAuthenticateAgainstProtectionSpace(WKBooleanGetValue(value));
677 return;
678 }
679
680 if (WKStringIsEqualToUTF8CString(messageName, "SetShouldLogDownloadCallbacks")) {
681 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
682 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
683 TestController::singleton().setShouldLogDownloadCallbacks(WKBooleanGetValue(value));
684 return;
685 }
686
687 if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationUsername")) {
688 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
689 WKStringRef username = static_cast<WKStringRef>(messageBody);
690 TestController::singleton().setAuthenticationUsername(toWTFString(username));
691 return;
692 }
693
694 if (WKStringIsEqualToUTF8CString(messageName, "SetAuthenticationPassword")) {
695 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
696 WKStringRef password = static_cast<WKStringRef>(messageBody);
697 TestController::singleton().setAuthenticationPassword(toWTFString(password));
698 return;
699 }
700
701 if (WKStringIsEqualToUTF8CString(messageName, "SetBlockAllPlugins")) {
702 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
703 WKBooleanRef shouldBlock = static_cast<WKBooleanRef>(messageBody);
704 TestController::singleton().setBlockAllPlugins(WKBooleanGetValue(shouldBlock));
705 return;
706 }
707
708 if (WKStringIsEqualToUTF8CString(messageName, "SetPluginSupportedMode")) {
709 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
710 WKStringRef mode = static_cast<WKStringRef>(messageBody);
711 TestController::singleton().setPluginSupportedMode(toWTFString(mode));
712 return;
713 }
714
715 if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDecideNavigationPolicyAfterDelay")) {
716 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
717 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
718 TestController::singleton().setShouldDecideNavigationPolicyAfterDelay(WKBooleanGetValue(value));
719 return;
720 }
721
722 if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDecideResponsePolicyAfterDelay")) {
723 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
724 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
725 TestController::singleton().setShouldDecideResponsePolicyAfterDelay(WKBooleanGetValue(value));
726 return;
727 }
728
729 if (WKStringIsEqualToUTF8CString(messageName, "SetNavigationGesturesEnabled")) {
730 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
731 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
732 TestController::singleton().setNavigationGesturesEnabled(WKBooleanGetValue(value));
733 return;
734 }
735
736 if (WKStringIsEqualToUTF8CString(messageName, "SetIgnoresViewportScaleLimits")) {
737 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
738 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
739 TestController::singleton().setIgnoresViewportScaleLimits(WKBooleanGetValue(value));
740 return;
741 }
742
743 if (WKStringIsEqualToUTF8CString(messageName, "SetShouldDownloadUndisplayableMIMETypes")) {
744 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
745 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
746 TestController::singleton().setShouldDownloadUndisplayableMIMETypes(WKBooleanGetValue(value));
747 return;
748 }
749
750 if (WKStringIsEqualToUTF8CString(messageName, "SetShouldAllowDeviceOrientationAndMotionAccess")) {
751 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
752 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
753 TestController::singleton().setShouldAllowDeviceOrientationAndMotionAccess(WKBooleanGetValue(value));
754 return;
755 }
756
757 if (WKStringIsEqualToUTF8CString(messageName, "RunUIProcessScript")) {
758 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
759 WKRetainPtr<WKStringRef> scriptKey = adoptWK(WKStringCreateWithUTF8CString("Script"));
760 WKRetainPtr<WKStringRef> callbackIDKey = adoptWK(WKStringCreateWithUTF8CString("CallbackID"));
761
762 UIScriptInvocationData* invocationData = new UIScriptInvocationData();
763 invocationData->testInvocation = this;
764 invocationData->callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
765 invocationData->scriptString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, scriptKey.get()));
766 m_pendingUIScriptInvocationData = invocationData;
767 WKPageCallAfterNextPresentationUpdate(TestController::singleton().mainWebView()->page(), invocationData, runUISideScriptAfterUpdateCallback);
768 return;
769 }
770
771 if (WKStringIsEqualToUTF8CString(messageName, "InstallCustomMenuAction")) {
772 auto messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
773 WKRetainPtr<WKStringRef> nameKey = adoptWK(WKStringCreateWithUTF8CString("name"));
774 WKRetainPtr<WKStringRef> name = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, nameKey.get()));
775 WKRetainPtr<WKStringRef> dismissesAutomaticallyKey = adoptWK(WKStringCreateWithUTF8CString("dismissesAutomatically"));
776 auto dismissesAutomatically = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, dismissesAutomaticallyKey.get()));
777 TestController::singleton().installCustomMenuAction(toWTFString(name.get()), WKBooleanGetValue(dismissesAutomatically));
778 return;
779 }
780
781 if (WKStringIsEqualToUTF8CString(messageName, "SetAllowedMenuActions")) {
782 auto messageBodyArray = static_cast<WKArrayRef>(messageBody);
783 auto size = WKArrayGetSize(messageBodyArray);
784 Vector<String> actions;
785 actions.reserveInitialCapacity(size);
786 for (size_t index = 0; index < size; ++index)
787 actions.append(toWTFString(static_cast<WKStringRef>(WKArrayGetItemAtIndex(messageBodyArray, index))));
788 TestController::singleton().setAllowedMenuActions(actions);
789 return;
790 }
791
792 if (WKStringIsEqualToUTF8CString(messageName, "SetOpenPanelFileURLs")) {
793 TestController::singleton().setOpenPanelFileURLs(static_cast<WKArrayRef>(messageBody));
794 return;
795 }
796
797#if PLATFORM(IOS_FAMILY)
798 if (WKStringIsEqualToUTF8CString(messageName, "SetOpenPanelFileURLsMediaIcon")) {
799 TestController::singleton().setOpenPanelFileURLsMediaIcon(static_cast<WKDataRef>(messageBody));
800 return;
801 }
802#endif
803
804 ASSERT_NOT_REACHED();
805}
806
807WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody)
808{
809 if (WKStringIsEqualToUTF8CString(messageName, "Initialization")) {
810 auto settings = createTestSettingsDictionary();
811 WKRetainPtr<WKStringRef> resumeTestingKey = adoptWK(WKStringCreateWithUTF8CString("ResumeTesting"));
812 WKRetainPtr<WKBooleanRef> resumeTestingValue = adoptWK(WKBooleanCreate(m_startedTesting));
813 WKDictionarySetItem(settings.get(), resumeTestingKey.get(), resumeTestingValue.get());
814 return settings;
815 }
816
817 if (WKStringIsEqualToUTF8CString(messageName, "SetDumpPixels")) {
818 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
819 m_dumpPixels = WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody));
820 return nullptr;
821 }
822 if (WKStringIsEqualToUTF8CString(messageName, "GetDumpPixels"))
823 return adoptWK(WKBooleanCreate(m_dumpPixels));
824
825 if (WKStringIsEqualToUTF8CString(messageName, "SetWhatToDump")) {
826 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
827 m_whatToDump = static_cast<WhatToDump>(WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody)));
828 return nullptr;
829 }
830 if (WKStringIsEqualToUTF8CString(messageName, "GetWhatToDump"))
831 return adoptWK(WKUInt64Create(static_cast<uint64_t>(m_whatToDump)));
832
833 if (WKStringIsEqualToUTF8CString(messageName, "SetWaitUntilDone")) {
834 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
835 setWaitUntilDone(static_cast<unsigned char>(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody))));
836 return nullptr;
837 }
838 if (WKStringIsEqualToUTF8CString(messageName, "GetWaitUntilDone"))
839 return adoptWK(WKBooleanCreate(m_waitUntilDone));
840
841 if (WKStringIsEqualToUTF8CString(messageName, "SetDumpFrameLoadCallbacks")) {
842 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
843 m_dumpFrameLoadCallbacks = static_cast<unsigned char>(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
844 return nullptr;
845 }
846 if (WKStringIsEqualToUTF8CString(messageName, "GetDumpFrameLoadCallbacks"))
847 return adoptWK(WKBooleanCreate(m_dumpFrameLoadCallbacks));
848
849 if (WKStringIsEqualToUTF8CString(messageName, "SetCanOpenWindows")) {
850 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
851 m_canOpenWindows = static_cast<unsigned char>(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
852 return nullptr;
853 }
854
855 if (WKStringIsEqualToUTF8CString(messageName, "SetWindowIsKey")) {
856 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
857 WKBooleanRef isKeyValue = static_cast<WKBooleanRef>(messageBody);
858 TestController::singleton().mainWebView()->setWindowIsKey(WKBooleanGetValue(isKeyValue));
859 return nullptr;
860 }
861
862 if (WKStringIsEqualToUTF8CString(messageName, "SetViewSize")) {
863 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
864
865 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
866 WKRetainPtr<WKStringRef> widthKey = adoptWK(WKStringCreateWithUTF8CString("width"));
867 WKRetainPtr<WKStringRef> heightKey = adoptWK(WKStringCreateWithUTF8CString("height"));
868
869 WKDoubleRef widthWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, widthKey.get()));
870 WKDoubleRef heightWK = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, heightKey.get()));
871
872 TestController::singleton().mainWebView()->resizeTo(WKDoubleGetValue(widthWK), WKDoubleGetValue(heightWK));
873 return nullptr;
874 }
875
876 if (WKStringIsEqualToUTF8CString(messageName, "IsGeolocationClientActive")) {
877 bool isActive = TestController::singleton().isGeolocationProviderActive();
878 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isActive));
879 return result;
880 }
881
882 if (WKStringIsEqualToUTF8CString(messageName, "IsWorkQueueEmpty")) {
883 bool isEmpty = TestController::singleton().workQueueManager().isWorkQueueEmpty();
884 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isEmpty));
885 return result;
886 }
887
888 if (WKStringIsEqualToUTF8CString(messageName, "DidReceiveServerRedirectForProvisionalNavigation")) {
889 WKRetainPtr<WKBooleanRef> result = adoptWK(WKBooleanCreate(TestController::singleton().didReceiveServerRedirectForProvisionalNavigation()));
890 return result;
891 }
892
893 if (WKStringIsEqualToUTF8CString(messageName, "ClearDidReceiveServerRedirectForProvisionalNavigation")) {
894 TestController::singleton().clearDidReceiveServerRedirectForProvisionalNavigation();
895 return nullptr;
896 }
897
898 if (WKStringIsEqualToUTF8CString(messageName, "SecureEventInputIsEnabled")) {
899#if PLATFORM(MAC) && !PLATFORM(IOS_FAMILY)
900 WKRetainPtr<WKBooleanRef> result = adoptWK(WKBooleanCreate(IsSecureEventInputEnabled()));
901#else
902 WKRetainPtr<WKBooleanRef> result = adoptWK(WKBooleanCreate(false));
903#endif
904 return result;
905 }
906
907 if (WKStringIsEqualToUTF8CString(messageName, "SetAlwaysAcceptCookies")) {
908 WKBooleanRef accept = static_cast<WKBooleanRef>(messageBody);
909 WKHTTPCookieAcceptPolicy policy = WKBooleanGetValue(accept) ? kWKHTTPCookieAcceptPolicyAlways : kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain;
910 // FIXME: This updates the policy in WebProcess and in NetworkProcess asynchronously, which might break some tests' expectations.
911 WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), policy);
912 return nullptr;
913 }
914
915 if (WKStringIsEqualToUTF8CString(messageName, "SetOnlyAcceptFirstPartyCookies")) {
916 WKBooleanRef accept = static_cast<WKBooleanRef>(messageBody);
917 WKHTTPCookieAcceptPolicy policy = WKBooleanGetValue(accept) ? kWKHTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain : kWKHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain;
918 // FIXME: This updates the policy in WebProcess and in NetworkProcess asynchronously, which might break some tests' expectations.
919 WKCookieManagerSetHTTPCookieAcceptPolicy(WKContextGetCookieManager(TestController::singleton().context()), policy);
920 return nullptr;
921 }
922
923 if (WKStringIsEqualToUTF8CString(messageName, "SetCustomUserAgent")) {
924 WKStringRef userAgent = static_cast<WKStringRef>(messageBody);
925 WKPageSetCustomUserAgent(TestController::singleton().mainWebView()->page(), userAgent);
926 return nullptr;
927 }
928
929 if (WKStringIsEqualToUTF8CString(messageName, "SetStorageAccessAPIEnabled")) {
930 WKBooleanRef accept = static_cast<WKBooleanRef>(messageBody);
931 WKCookieManagerSetStorageAccessAPIEnabled(WKContextGetCookieManager(TestController::singleton().context()), WKBooleanGetValue(accept));
932 return nullptr;
933 }
934
935 if (WKStringIsEqualToUTF8CString(messageName, "GetAllStorageAccessEntries")) {
936 TestController::singleton().getAllStorageAccessEntries();
937 return nullptr;
938 }
939
940 if (WKStringIsEqualToUTF8CString(messageName, "SetAllowsAnySSLCertificate")) {
941 TestController::singleton().setAllowsAnySSLCertificate(WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody)));
942 return nullptr;
943 }
944
945 if (WKStringIsEqualToUTF8CString(messageName, "ImageCountInGeneralPasteboard")) {
946 unsigned count = TestController::singleton().imageCountInGeneralPasteboard();
947 WKRetainPtr<WKUInt64Ref> result = adoptWK(WKUInt64Create(count));
948 return result;
949 }
950
951 if (WKStringIsEqualToUTF8CString(messageName, "DeleteAllIndexedDatabases")) {
952 WKWebsiteDataStoreRemoveAllIndexedDatabases(WKContextGetWebsiteDataStore(TestController::singleton().context()), nullptr, { });
953 return nullptr;
954 }
955
956 if (WKStringIsEqualToUTF8CString(messageName, "AddMockMediaDevice")) {
957 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
958
959 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
960 WKRetainPtr<WKStringRef> persistentIDKey = adoptWK(WKStringCreateWithUTF8CString("PersistentID"));
961 WKRetainPtr<WKStringRef> labelKey = adoptWK(WKStringCreateWithUTF8CString("Label"));
962 WKRetainPtr<WKStringRef> typeKey = adoptWK(WKStringCreateWithUTF8CString("Type"));
963
964 auto persistentID = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, persistentIDKey.get()));
965 auto label = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, labelKey.get()));
966 auto type = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, typeKey.get()));
967
968 TestController::singleton().addMockMediaDevice(persistentID, label, type);
969 return nullptr;
970 }
971
972 if (WKStringIsEqualToUTF8CString(messageName, "ClearMockMediaDevices")) {
973 TestController::singleton().clearMockMediaDevices();
974 return nullptr;
975 }
976
977 if (WKStringIsEqualToUTF8CString(messageName, "RemoveMockMediaDevice")) {
978 WKStringRef persistentId = static_cast<WKStringRef>(messageBody);
979
980 TestController::singleton().removeMockMediaDevice(persistentId);
981 return nullptr;
982 }
983
984 if (WKStringIsEqualToUTF8CString(messageName, "ResetMockMediaDevices")) {
985 TestController::singleton().resetMockMediaDevices();
986 return nullptr;
987 }
988
989#if PLATFORM(MAC)
990 if (WKStringIsEqualToUTF8CString(messageName, "ConnectMockGamepad")) {
991 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
992
993 uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
994 WebCoreTestSupport::connectMockGamepad(index);
995
996 return nullptr;
997 }
998
999 if (WKStringIsEqualToUTF8CString(messageName, "DisconnectMockGamepad")) {
1000 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1001
1002 uint64_t index = WKUInt64GetValue(static_cast<WKUInt64Ref>(messageBody));
1003 WebCoreTestSupport::disconnectMockGamepad(index);
1004
1005 return nullptr;
1006 }
1007
1008 if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadDetails")) {
1009 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1010
1011 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1012 WKRetainPtr<WKStringRef> gamepadIndexKey = adoptWK(WKStringCreateWithUTF8CString("GamepadIndex"));
1013 WKRetainPtr<WKStringRef> gamepadIDKey = adoptWK(WKStringCreateWithUTF8CString("GamepadID"));
1014 WKRetainPtr<WKStringRef> axisCountKey = adoptWK(WKStringCreateWithUTF8CString("AxisCount"));
1015 WKRetainPtr<WKStringRef> buttonCountKey = adoptWK(WKStringCreateWithUTF8CString("ButtonCount"));
1016
1017 WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
1018 WKStringRef gamepadID = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIDKey.get()));
1019 WKUInt64Ref axisCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisCountKey.get()));
1020 WKUInt64Ref buttonCount = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonCountKey.get()));
1021
1022 WebCoreTestSupport::setMockGamepadDetails(WKUInt64GetValue(gamepadIndex), toWTFString(gamepadID), WKUInt64GetValue(axisCount), WKUInt64GetValue(buttonCount));
1023 return nullptr;
1024 }
1025
1026 if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadAxisValue")) {
1027 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1028
1029 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1030 WKRetainPtr<WKStringRef> gamepadIndexKey = adoptWK(WKStringCreateWithUTF8CString("GamepadIndex"));
1031 WKRetainPtr<WKStringRef> axisIndexKey = adoptWK(WKStringCreateWithUTF8CString("AxisIndex"));
1032 WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1033
1034 WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
1035 WKUInt64Ref axisIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, axisIndexKey.get()));
1036 WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1037
1038 WebCoreTestSupport::setMockGamepadAxisValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(axisIndex), WKDoubleGetValue(value));
1039
1040 return nullptr;
1041 }
1042
1043 if (WKStringIsEqualToUTF8CString(messageName, "SetMockGamepadButtonValue")) {
1044 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1045
1046 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1047 WKRetainPtr<WKStringRef> gamepadIndexKey = adoptWK(WKStringCreateWithUTF8CString("GamepadIndex"));
1048 WKRetainPtr<WKStringRef> buttonIndexKey = adoptWK(WKStringCreateWithUTF8CString("ButtonIndex"));
1049 WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1050
1051 WKUInt64Ref gamepadIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, gamepadIndexKey.get()));
1052 WKUInt64Ref buttonIndex = static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, buttonIndexKey.get()));
1053 WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1054
1055 WebCoreTestSupport::setMockGamepadButtonValue(WKUInt64GetValue(gamepadIndex), WKUInt64GetValue(buttonIndex), WKDoubleGetValue(value));
1056
1057 return nullptr;
1058 }
1059#endif // PLATFORM(MAC)
1060
1061 if (WKStringIsEqualToUTF8CString(messageName, "UserMediaPermissionRequestCountForOrigin")) {
1062 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1063 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1064
1065 WKRetainPtr<WKStringRef> originKey = adoptWK(WKStringCreateWithUTF8CString("origin"));
1066 WKStringRef originWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, originKey.get()));
1067
1068 WKRetainPtr<WKStringRef> parentOriginKey = adoptWK(WKStringCreateWithUTF8CString("parentOrigin"));
1069 WKStringRef parentOriginWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, parentOriginKey.get()));
1070
1071 unsigned count = TestController::singleton().userMediaPermissionRequestCountForOrigin(originWK, parentOriginWK);
1072 WKRetainPtr<WKUInt64Ref> result = adoptWK(WKUInt64Create(count));
1073 return result;
1074 }
1075 if (WKStringIsEqualToUTF8CString(messageName, "IsDoingMediaCapture")) {
1076 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(TestController::singleton().isDoingMediaCapture()));
1077 return result;
1078 }
1079
1080 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsDebugMode")) {
1081 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1082 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1083 TestController::singleton().setStatisticsDebugMode(WKBooleanGetValue(value));
1084 return nullptr;
1085 }
1086
1087 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsPrevalentResourceForDebugMode")) {
1088 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1089 WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1090 TestController::singleton().setStatisticsPrevalentResourceForDebugMode(hostName);
1091 return nullptr;
1092 }
1093
1094 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsLastSeen")) {
1095 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1096
1097 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1098 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1099 WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1100
1101 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1102 WKDoubleRef value = static_cast<WKDoubleRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1103
1104 TestController::singleton().setStatisticsLastSeen(hostName, WKDoubleGetValue(value));
1105
1106 return nullptr;
1107 }
1108
1109 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsPrevalentResource")) {
1110 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1111
1112 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1113 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1114 WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1115
1116 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1117 WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1118
1119 TestController::singleton().setStatisticsPrevalentResource(hostName, WKBooleanGetValue(value));
1120 return nullptr;
1121 }
1122
1123 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsVeryPrevalentResource")) {
1124 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1125
1126 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1127 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1128 WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1129
1130 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1131 WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1132
1133 TestController::singleton().setStatisticsVeryPrevalentResource(hostName, WKBooleanGetValue(value));
1134 return nullptr;
1135 }
1136
1137 if (WKStringIsEqualToUTF8CString(messageName, "dumpResourceLoadStatistics")) {
1138 dumpResourceLoadStatistics();
1139 return nullptr;
1140 }
1141
1142 if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsPrevalentResource")) {
1143 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1144
1145 WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1146 bool isPrevalent = TestController::singleton().isStatisticsPrevalentResource(hostName);
1147 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isPrevalent));
1148 return result;
1149 }
1150
1151 if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsVeryPrevalentResource")) {
1152 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1153
1154 WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1155 bool isPrevalent = TestController::singleton().isStatisticsVeryPrevalentResource(hostName);
1156 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isPrevalent));
1157 return result;
1158 }
1159
1160 if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsRegisteredAsSubresourceUnder")) {
1161 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1162
1163 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1164 WKRetainPtr<WKStringRef> subresourceHostKey = adoptWK(WKStringCreateWithUTF8CString("SubresourceHost"));
1165 WKRetainPtr<WKStringRef> topFrameHostKey = adoptWK(WKStringCreateWithUTF8CString("TopFrameHost"));
1166
1167 WKStringRef subresourceHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, subresourceHostKey.get()));
1168 WKStringRef topFrameHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostKey.get()));
1169
1170 bool isRegisteredAsSubresourceUnder = TestController::singleton().isStatisticsRegisteredAsSubresourceUnder(subresourceHost, topFrameHost);
1171 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isRegisteredAsSubresourceUnder));
1172 return result;
1173 }
1174
1175 if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsRegisteredAsSubFrameUnder")) {
1176 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1177
1178 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1179 WKRetainPtr<WKStringRef> subFrameHostKey = adoptWK(WKStringCreateWithUTF8CString("SubFrameHost"));
1180 WKRetainPtr<WKStringRef> topFrameHostKey = adoptWK(WKStringCreateWithUTF8CString("TopFrameHost"));
1181
1182 WKStringRef subFrameHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, subFrameHostKey.get()));
1183 WKStringRef topFrameHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostKey.get()));
1184
1185 bool isRegisteredAsSubFrameUnder = TestController::singleton().isStatisticsRegisteredAsSubFrameUnder(subFrameHost, topFrameHost);
1186 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isRegisteredAsSubFrameUnder));
1187 return result;
1188 }
1189
1190 if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsRegisteredAsRedirectingTo")) {
1191 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1192
1193 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1194 WKRetainPtr<WKStringRef> hostRedirectedFromKey = adoptWK(WKStringCreateWithUTF8CString("HostRedirectedFrom"));
1195 WKRetainPtr<WKStringRef> hostRedirectedToKey = adoptWK(WKStringCreateWithUTF8CString("HostRedirectedTo"));
1196
1197 WKStringRef hostRedirectedFrom = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostRedirectedFromKey.get()));
1198 WKStringRef hostRedirectedTo = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostRedirectedToKey.get()));
1199
1200 bool isRegisteredAsRedirectingTo = TestController::singleton().isStatisticsRegisteredAsRedirectingTo(hostRedirectedFrom, hostRedirectedTo);
1201 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isRegisteredAsRedirectingTo));
1202 return result;
1203 }
1204
1205 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsHasHadUserInteraction")) {
1206 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1207
1208 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1209 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1210 WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1211
1212 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1213 WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1214
1215 TestController::singleton().setStatisticsHasHadUserInteraction(hostName, WKBooleanGetValue(value));
1216 return nullptr;
1217 }
1218
1219 if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsHasHadUserInteraction")) {
1220 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1221
1222 WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1223 bool hasHadUserInteraction = TestController::singleton().isStatisticsHasHadUserInteraction(hostName);
1224 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(hasHadUserInteraction));
1225 return result;
1226 }
1227
1228 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsGrandfathered")) {
1229 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1230
1231 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1232 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1233 WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("Value"));
1234
1235 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1236 WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1237
1238 TestController::singleton().setStatisticsGrandfathered(hostName, WKBooleanGetValue(value));
1239 return nullptr;
1240 }
1241
1242 if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsGrandfathered")) {
1243 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1244
1245 WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1246 bool isGrandfathered = TestController::singleton().isStatisticsGrandfathered(hostName);
1247 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(isGrandfathered));
1248 return result;
1249 }
1250
1251 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubframeUnderTopFrameOrigin")) {
1252 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1253
1254 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1255 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1256 WKRetainPtr<WKStringRef> topFrameHostNameKey = adoptWK(WKStringCreateWithUTF8CString("TopFrameHostName"));
1257
1258 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1259 WKStringRef topFrameHostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostNameKey.get()));
1260
1261 TestController::singleton().setStatisticsSubframeUnderTopFrameOrigin(hostName, topFrameHostName);
1262 return nullptr;
1263 }
1264
1265 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubresourceUnderTopFrameOrigin")) {
1266 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1267
1268 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1269 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1270 WKRetainPtr<WKStringRef> topFrameHostNameKey = adoptWK(WKStringCreateWithUTF8CString("TopFrameHostName"));
1271
1272 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1273 WKStringRef topFrameHostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, topFrameHostNameKey.get()));
1274
1275 TestController::singleton().setStatisticsSubresourceUnderTopFrameOrigin(hostName, topFrameHostName);
1276 return nullptr;
1277 }
1278
1279 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubresourceUniqueRedirectTo")) {
1280 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1281
1282 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1283 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1284 WKRetainPtr<WKStringRef> hostNameRedirectedToKey = adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedTo"));
1285
1286 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1287 WKStringRef hostNameRedirectedTo = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedToKey.get()));
1288
1289 TestController::singleton().setStatisticsSubresourceUniqueRedirectTo(hostName, hostNameRedirectedTo);
1290 return nullptr;
1291 }
1292
1293 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsSubresourceUniqueRedirectFrom")) {
1294 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1295
1296 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1297 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1298 WKRetainPtr<WKStringRef> hostNameRedirectedFromKey = adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedFrom"));
1299
1300 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1301 WKStringRef hostNameRedirectedFrom = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedFromKey.get()));
1302
1303 TestController::singleton().setStatisticsSubresourceUniqueRedirectFrom(hostName, hostNameRedirectedFrom);
1304 return nullptr;
1305 }
1306
1307 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTopFrameUniqueRedirectTo")) {
1308 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1309
1310 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1311 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1312 WKRetainPtr<WKStringRef> hostNameRedirectedToKey = adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedTo"));
1313
1314 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1315 WKStringRef hostNameRedirectedTo = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedToKey.get()));
1316
1317 TestController::singleton().setStatisticsTopFrameUniqueRedirectTo(hostName, hostNameRedirectedTo);
1318 return nullptr;
1319 }
1320
1321 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTopFrameUniqueRedirectFrom")) {
1322 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1323
1324 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1325 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1326 WKRetainPtr<WKStringRef> hostNameRedirectedFromKey = adoptWK(WKStringCreateWithUTF8CString("HostNameRedirectedFrom"));
1327
1328 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1329 WKStringRef hostNameRedirectedFrom = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameRedirectedFromKey.get()));
1330
1331 TestController::singleton().setStatisticsTopFrameUniqueRedirectFrom(hostName, hostNameRedirectedFrom);
1332 return nullptr;
1333 }
1334
1335 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsCrossSiteLoadWithLinkDecoration")) {
1336 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1337
1338 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1339 auto fromHostKey = adoptWK(WKStringCreateWithUTF8CString("FromHost"));
1340 auto toHostKey = adoptWK(WKStringCreateWithUTF8CString("ToHost"));
1341
1342 WKStringRef fromHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, fromHostKey.get()));
1343 WKStringRef toHost = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, toHostKey.get()));
1344
1345 TestController::singleton().setStatisticsCrossSiteLoadWithLinkDecoration(fromHost, toHost);
1346 return nullptr;
1347 }
1348
1349 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsTimeToLiveUserInteraction")) {
1350 ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1351 WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1352 TestController::singleton().setStatisticsTimeToLiveUserInteraction(WKDoubleGetValue(seconds));
1353 return nullptr;
1354 }
1355
1356 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsProcessStatisticsAndDataRecords")) {
1357 TestController::singleton().statisticsProcessStatisticsAndDataRecords();
1358 return nullptr;
1359 }
1360
1361 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsUpdateCookieBlocking")) {
1362 TestController::singleton().statisticsUpdateCookieBlocking();
1363 return nullptr;
1364 }
1365
1366 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsSubmitTelemetry")) {
1367 TestController::singleton().statisticsSubmitTelemetry();
1368 return nullptr;
1369 }
1370
1371 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsNotifyPagesWhenDataRecordsWereScanned")) {
1372 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1373 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1374 TestController::singleton().setStatisticsNotifyPagesWhenDataRecordsWereScanned(WKBooleanGetValue(value));
1375 return nullptr;
1376 }
1377
1378 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsSetIsRunningTest")) {
1379 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1380 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1381 TestController::singleton().setStatisticsIsRunningTest(WKBooleanGetValue(value));
1382 return nullptr;
1383 }
1384
1385 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsNotifyPagesWhenTelemetryWasCaptured")) {
1386 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1387 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1388 TestController::singleton().setStatisticsNotifyPagesWhenTelemetryWasCaptured(WKBooleanGetValue(value));
1389 return nullptr;
1390 }
1391
1392 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval")) {
1393 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1394 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1395 TestController::singleton().setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(WKBooleanGetValue(value));
1396 return nullptr;
1397 }
1398
1399 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsMinimumTimeBetweenDataRecordsRemoval")) {
1400 ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1401 WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1402 TestController::singleton().setStatisticsMinimumTimeBetweenDataRecordsRemoval(WKDoubleGetValue(seconds));
1403 return nullptr;
1404 }
1405
1406 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsGrandfatheringTime")) {
1407 ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1408 WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1409 TestController::singleton().setStatisticsGrandfatheringTime(WKDoubleGetValue(seconds));
1410 return nullptr;
1411 }
1412
1413 if (WKStringIsEqualToUTF8CString(messageName, "SetMaxStatisticsEntries")) {
1414 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1415 WKUInt64Ref entries = static_cast<WKUInt64Ref>(messageBody);
1416 TestController::singleton().setStatisticsMaxStatisticsEntries(WKUInt64GetValue(entries));
1417 return nullptr;
1418 }
1419
1420 if (WKStringIsEqualToUTF8CString(messageName, "SetPruneEntriesDownTo")) {
1421 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1422 WKUInt64Ref entries = static_cast<WKUInt64Ref>(messageBody);
1423 TestController::singleton().setStatisticsPruneEntriesDownTo(WKUInt64GetValue(entries));
1424 return nullptr;
1425 }
1426
1427 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsClearInMemoryAndPersistentStore")) {
1428 TestController::singleton().statisticsClearInMemoryAndPersistentStore();
1429 return nullptr;
1430 }
1431
1432 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsClearInMemoryAndPersistentStoreModifiedSinceHours")) {
1433 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1434 WKUInt64Ref hours = static_cast<WKUInt64Ref>(messageBody);
1435 TestController::singleton().statisticsClearInMemoryAndPersistentStoreModifiedSinceHours(WKUInt64GetValue(hours));
1436 return nullptr;
1437 }
1438
1439 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsClearThroughWebsiteDataRemoval")) {
1440 TestController::singleton().statisticsClearThroughWebsiteDataRemoval();
1441 return nullptr;
1442 }
1443
1444 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsDeleteCookiesForHost")) {
1445 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1446
1447 WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
1448 WKRetainPtr<WKStringRef> hostNameKey = adoptWK(WKStringCreateWithUTF8CString("HostName"));
1449 WKRetainPtr<WKStringRef> valueKey = adoptWK(WKStringCreateWithUTF8CString("IncludeHttpOnlyCookies"));
1450
1451 WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
1452 WKBooleanRef includeHttpOnlyCookies = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
1453
1454 TestController::singleton().statisticsDeleteCookiesForHost(hostName, WKBooleanGetValue(includeHttpOnlyCookies));
1455 return nullptr;
1456 }
1457
1458 if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsHasLocalStorage")) {
1459 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1460
1461 WKStringRef hostName = static_cast<WKStringRef>(messageBody);
1462 bool hasLocalStorage = TestController::singleton().isStatisticsHasLocalStorage(hostName);
1463 auto result = adoptWK(WKBooleanCreate(hasLocalStorage));
1464 return result;
1465 }
1466
1467 if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsCacheMaxAgeCap")) {
1468 ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
1469 WKDoubleRef seconds = static_cast<WKDoubleRef>(messageBody);
1470 TestController::singleton().setStatisticsCacheMaxAgeCap(WKDoubleGetValue(seconds));
1471 return nullptr;
1472 }
1473
1474 if (WKStringIsEqualToUTF8CString(messageName, "StatisticsResetToConsistentState")) {
1475 if (m_shouldDumpResourceLoadStatistics)
1476 m_savedResourceLoadStatistics = TestController::singleton().dumpResourceLoadStatistics();
1477 TestController::singleton().statisticsResetToConsistentState();
1478 return nullptr;
1479 }
1480
1481 if (WKStringIsEqualToUTF8CString(messageName, "RemoveAllSessionCredentials")) {
1482 TestController::singleton().removeAllSessionCredentials();
1483 return nullptr;
1484 }
1485
1486 if (WKStringIsEqualToUTF8CString(messageName, "ClearDOMCache")) {
1487 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1488 WKStringRef origin = static_cast<WKStringRef>(messageBody);
1489
1490 TestController::singleton().clearDOMCache(origin);
1491 return nullptr;
1492 }
1493
1494 if (WKStringIsEqualToUTF8CString(messageName, "ClearDOMCaches")) {
1495 TestController::singleton().clearDOMCaches();
1496 return nullptr;
1497 }
1498
1499 if (WKStringIsEqualToUTF8CString(messageName, "HasDOMCache")) {
1500 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1501 WKStringRef origin = static_cast<WKStringRef>(messageBody);
1502
1503 bool hasDOMCache = TestController::singleton().hasDOMCache(origin);
1504 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(hasDOMCache));
1505 return result;
1506 }
1507
1508 if (WKStringIsEqualToUTF8CString(messageName, "DOMCacheSize")) {
1509 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1510 WKStringRef origin = static_cast<WKStringRef>(messageBody);
1511
1512 auto domCacheSize = TestController::singleton().domCacheSize(origin);
1513 WKRetainPtr<WKTypeRef> result = adoptWK(WKUInt64Create(domCacheSize));
1514 return result;
1515 }
1516
1517 if (WKStringIsEqualToUTF8CString(messageName, "SetAllowStorageQuotaIncrease")) {
1518 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1519 auto canIncrease = WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody));
1520 TestController::singleton().setAllowStorageQuotaIncrease(canIncrease);
1521 return nullptr;
1522 }
1523
1524 if (WKStringIsEqualToUTF8CString(messageName, "SetIDBPerOriginQuota")) {
1525 ASSERT(WKGetTypeID(messageBody) == WKUInt64GetTypeID());
1526 WKUInt64Ref quota = static_cast<WKUInt64Ref>(messageBody);
1527 TestController::singleton().setIDBPerOriginQuota(WKUInt64GetValue(quota));
1528 return nullptr;
1529 }
1530
1531 if (WKStringIsEqualToUTF8CString(messageName, "InjectUserScript")) {
1532 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1533 WKStringRef script = static_cast<WKStringRef>(messageBody);
1534
1535 TestController::singleton().injectUserScript(script);
1536 return nullptr;
1537 }
1538
1539 if (WKStringIsEqualToUTF8CString(messageName, "GetApplicationManifest")) {
1540#ifdef __BLOCKS__
1541 WKPageGetApplicationManifest_b(TestController::singleton().mainWebView()->page(), ^{
1542 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("DidGetApplicationManifest"));
1543 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1544 });
1545#else
1546 // FIXME: Add API for loading the manifest on non-__BLOCKS__ ports.
1547 ASSERT_NOT_REACHED();
1548#endif
1549 return nullptr;
1550 }
1551
1552 if (WKStringIsEqualToUTF8CString(messageName, "SendDisplayConfigurationChangedMessageForTesting")) {
1553 TestController::singleton().sendDisplayConfigurationChangedMessageForTesting();
1554 return nullptr;
1555 }
1556
1557 if (WKStringIsEqualToUTF8CString(messageName, "TerminateNetworkProcess")) {
1558 ASSERT(!messageBody);
1559 TestController::singleton().terminateNetworkProcess();
1560 return nullptr;
1561 }
1562
1563 if (WKStringIsEqualToUTF8CString(messageName, "TerminateServiceWorkerProcess")) {
1564 ASSERT(!messageBody);
1565 TestController::singleton().terminateServiceWorkerProcess();
1566 return nullptr;
1567 }
1568
1569 if (WKStringIsEqualToUTF8CString(messageName, "SetWebAuthenticationMockConfiguration")) {
1570 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1571 TestController::singleton().setWebAuthenticationMockConfiguration(static_cast<WKDictionaryRef>(messageBody));
1572 return nullptr;
1573 }
1574
1575 if (WKStringIsEqualToUTF8CString(messageName, "AddTestKeyToKeychain")) {
1576 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1577 WKDictionaryRef testKeyDictionary = static_cast<WKDictionaryRef>(messageBody);
1578
1579 WKRetainPtr<WKStringRef> privateKeyKey = adoptWK(WKStringCreateWithUTF8CString("PrivateKey"));
1580 WKStringRef privateKeyWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testKeyDictionary, privateKeyKey.get()));
1581
1582 WKRetainPtr<WKStringRef> attrLabelKey = adoptWK(WKStringCreateWithUTF8CString("AttrLabel"));
1583 WKStringRef attrLabelWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testKeyDictionary, attrLabelKey.get()));
1584
1585 WKRetainPtr<WKStringRef> applicationTagKey = adoptWK(WKStringCreateWithUTF8CString("ApplicationTag"));
1586 WKStringRef applicationTagWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testKeyDictionary, applicationTagKey.get()));
1587
1588 TestController::singleton().addTestKeyToKeychain(toWTFString(privateKeyWK), toWTFString(attrLabelWK), toWTFString(applicationTagWK));
1589 return nullptr;
1590 }
1591
1592 if (WKStringIsEqualToUTF8CString(messageName, "CleanUpKeychain")) {
1593 ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
1594 TestController::singleton().cleanUpKeychain(toWTFString(static_cast<WKStringRef>(messageBody)));
1595 return nullptr;
1596 }
1597
1598 if (WKStringIsEqualToUTF8CString(messageName, "KeyExistsInKeychain")) {
1599 ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
1600 WKDictionaryRef testDictionary = static_cast<WKDictionaryRef>(messageBody);
1601
1602 WKRetainPtr<WKStringRef> attrLabelKey = adoptWK(WKStringCreateWithUTF8CString("AttrLabel"));
1603 WKStringRef attrLabelWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testDictionary, attrLabelKey.get()));
1604
1605 WKRetainPtr<WKStringRef> applicationTagKey = adoptWK(WKStringCreateWithUTF8CString("ApplicationTag"));
1606 WKStringRef applicationTagWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(testDictionary, applicationTagKey.get()));
1607
1608 bool keyExistsInKeychain = TestController::singleton().keyExistsInKeychain(toWTFString(attrLabelWK), toWTFString(applicationTagWK));
1609 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(keyExistsInKeychain));
1610 return result;
1611 }
1612
1613 if (WKStringIsEqualToUTF8CString(messageName, "SetCanHandleHTTPSServerTrustEvaluation")) {
1614 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1615 auto canHandle = WKBooleanGetValue(static_cast<WKBooleanRef>(messageBody));
1616 WKContextSetCanHandleHTTPSServerTrustEvaluation(TestController::singleton().context(), canHandle);
1617 return nullptr;
1618 }
1619
1620 if (WKStringIsEqualToUTF8CString(messageName, "CanDoServerTrustEvaluationInNetworkProcess")) {
1621 WKRetainPtr<WKTypeRef> result = adoptWK(WKBooleanCreate(TestController::singleton().canDoServerTrustEvaluationInNetworkProcess()));
1622 return result;
1623 }
1624
1625 if (WKStringIsEqualToUTF8CString(messageName, "ServerTrustEvaluationCallbackCallsCount")) {
1626 WKRetainPtr<WKTypeRef> result = adoptWK(WKUInt64Create(TestController::singleton().serverTrustEvaluationCallbackCallsCount()));
1627 return result;
1628 }
1629
1630 if (WKStringIsEqualToUTF8CString(messageName, "ShouldDismissJavaScriptAlertsAsynchronously")) {
1631 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1632 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1633 TestController::singleton().setShouldDismissJavaScriptAlertsAsynchronously(WKBooleanGetValue(value));
1634 return nullptr;
1635 }
1636
1637 if (WKStringIsEqualToUTF8CString(messageName, "AbortModal")) {
1638 TestController::singleton().abortModal();
1639 return nullptr;
1640 }
1641
1642 if (WKStringIsEqualToUTF8CString(messageName, "DumpAdClickAttribution")) {
1643 dumpAdClickAttribution();
1644 return nullptr;
1645 }
1646
1647 if (WKStringIsEqualToUTF8CString(messageName, "ClearAdClickAttribution")) {
1648 TestController::singleton().clearAdClickAttribution();
1649 return nullptr;
1650 }
1651
1652 if (WKStringIsEqualToUTF8CString(messageName, "ClearAdClickAttributionsThroughWebsiteDataRemoval")) {
1653 TestController::singleton().clearAdClickAttributionsThroughWebsiteDataRemoval();
1654 return nullptr;
1655 }
1656
1657 if (WKStringIsEqualToUTF8CString(messageName, "SetAdClickAttributionOverrideTimerForTesting")) {
1658 ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
1659 WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
1660 TestController::singleton().setAdClickAttributionOverrideTimerForTesting(WKBooleanGetValue(value));
1661 return nullptr;
1662 }
1663
1664 if (WKStringIsEqualToUTF8CString(messageName, "SetAdClickAttributionConversionURLForTesting")) {
1665 ASSERT(WKGetTypeID(messageBody) == WKURLGetTypeID());
1666 WKURLRef url = static_cast<WKURLRef>(messageBody);
1667 TestController::singleton().setAdClickAttributionConversionURLForTesting(url);
1668 return nullptr;
1669 }
1670
1671 if (WKStringIsEqualToUTF8CString(messageName, "MarkAdClickAttributionsAsExpiredForTesting")) {
1672 TestController::singleton().markAdClickAttributionsAsExpiredForTesting();
1673 return nullptr;
1674 }
1675
1676 ASSERT_NOT_REACHED();
1677 return nullptr;
1678}
1679
1680void TestInvocation::runUISideScriptAfterUpdateCallback(WKErrorRef, void* context)
1681{
1682 UIScriptInvocationData* data = static_cast<UIScriptInvocationData*>(context);
1683 if (TestInvocation* invocation = data->testInvocation) {
1684 RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(invocation));
1685 invocation->runUISideScript(data->scriptString.get(), data->callbackID);
1686 }
1687 delete data;
1688}
1689
1690void TestInvocation::runUISideScript(WKStringRef script, unsigned scriptCallbackID)
1691{
1692 m_pendingUIScriptInvocationData = nullptr;
1693
1694 if (!m_UIScriptContext)
1695 m_UIScriptContext = std::make_unique<UIScriptContext>(*this);
1696
1697 m_UIScriptContext->runUIScript(toWTFString(script), scriptCallbackID);
1698}
1699
1700void TestInvocation::uiScriptDidComplete(const String& result, unsigned scriptCallbackID)
1701{
1702 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallUISideScriptCallback"));
1703
1704 WKRetainPtr<WKMutableDictionaryRef> messageBody = adoptWK(WKMutableDictionaryCreate());
1705 WKRetainPtr<WKStringRef> resultKey = adoptWK(WKStringCreateWithUTF8CString("Result"));
1706 WKRetainPtr<WKStringRef> callbackIDKey = adoptWK(WKStringCreateWithUTF8CString("CallbackID"));
1707 WKRetainPtr<WKUInt64Ref> callbackIDValue = adoptWK(WKUInt64Create(scriptCallbackID));
1708
1709 WKDictionarySetItem(messageBody.get(), resultKey.get(), toWK(result).get());
1710 WKDictionarySetItem(messageBody.get(), callbackIDKey.get(), callbackIDValue.get());
1711
1712 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), messageBody.get());
1713}
1714
1715void TestInvocation::outputText(const WTF::String& text)
1716{
1717 m_textOutput.append(text);
1718}
1719
1720void TestInvocation::didBeginSwipe()
1721{
1722 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidBeginSwipeCallback"));
1723 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1724}
1725
1726void TestInvocation::willEndSwipe()
1727{
1728 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallWillEndSwipeCallback"));
1729 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1730}
1731
1732void TestInvocation::didEndSwipe()
1733{
1734 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidEndSwipeCallback"));
1735 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1736}
1737
1738void TestInvocation::didRemoveSwipeSnapshot()
1739{
1740 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidRemoveSwipeSnapshotCallback"));
1741 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1742}
1743
1744void TestInvocation::notifyDownloadDone()
1745{
1746 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("NotifyDownloadDone"));
1747 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1748}
1749
1750void TestInvocation::didClearStatisticsThroughWebsiteDataRemoval()
1751{
1752 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidClearStatisticsThroughWebsiteDataRemoval"));
1753 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1754}
1755
1756void TestInvocation::didResetStatisticsToConsistentState()
1757{
1758 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidResetStatisticsToConsistentState"));
1759 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1760}
1761
1762void TestInvocation::didSetBlockCookiesForHost()
1763{
1764 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetBlockCookiesForHost"));
1765 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1766}
1767
1768void TestInvocation::didSetStatisticsDebugMode()
1769{
1770 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetStatisticsDebugMode"));
1771 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1772}
1773
1774void TestInvocation::didSetPrevalentResourceForDebugMode()
1775{
1776 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetPrevalentResourceForDebugMode"));
1777 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1778}
1779
1780void TestInvocation::didSetLastSeen()
1781{
1782 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetLastSeen"));
1783 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1784}
1785
1786void TestInvocation::didSetPrevalentResource()
1787{
1788 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetPrevalentResource"));
1789 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1790}
1791
1792void TestInvocation::didSetVeryPrevalentResource()
1793{
1794 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetVeryPrevalentResource"));
1795 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1796}
1797
1798void TestInvocation::didSetHasHadUserInteraction()
1799{
1800 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidSetHasHadUserInteraction"));
1801 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1802}
1803
1804void TestInvocation::didReceiveAllStorageAccessEntries(Vector<String>& domains)
1805{
1806 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidReceiveAllStorageAccessEntries"));
1807
1808 WKRetainPtr<WKMutableArrayRef> messageBody = adoptWK(WKMutableArrayCreate());
1809 for (auto& domain : domains)
1810 WKArrayAppendItem(messageBody.get(), adoptWK(WKStringCreateWithUTF8CString(domain.utf8().data())).get());
1811
1812 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), messageBody.get());
1813}
1814
1815void TestInvocation::didRemoveAllSessionCredentials()
1816{
1817 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("CallDidRemoveAllSessionCredentialsCallback"));
1818 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1819}
1820
1821void TestInvocation::dumpResourceLoadStatistics()
1822{
1823 m_shouldDumpResourceLoadStatistics = true;
1824}
1825
1826void TestInvocation::dumpAdClickAttribution()
1827{
1828 m_shouldDumpAdClickAttribution = true;
1829}
1830
1831void TestInvocation::performCustomMenuAction()
1832{
1833 WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("PerformCustomMenuAction"));
1834 WKPagePostMessageToInjectedBundle(TestController::singleton().mainWebView()->page(), messageName.get(), 0);
1835}
1836
1837void TestInvocation::initializeWaitToDumpWatchdogTimerIfNeeded()
1838{
1839 if (m_waitToDumpWatchdogTimer.isActive())
1840 return;
1841
1842 m_waitToDumpWatchdogTimer.startOneShot(m_timeout);
1843}
1844
1845void TestInvocation::invalidateWaitToDumpWatchdogTimer()
1846{
1847 m_waitToDumpWatchdogTimer.stop();
1848}
1849
1850void TestInvocation::waitToDumpWatchdogTimerFired()
1851{
1852 invalidateWaitToDumpWatchdogTimer();
1853
1854#if PLATFORM(COCOA)
1855 char buffer[1024];
1856 snprintf(buffer, sizeof(buffer), "#PID UNRESPONSIVE - %s (pid %d)\n", getprogname(), getpid());
1857 outputText(buffer);
1858#endif
1859 outputText("FAIL: Timed out waiting for notifyDone to be called\n\n");
1860 done();
1861}
1862
1863void TestInvocation::setWaitUntilDone(bool waitUntilDone)
1864{
1865 m_waitUntilDone = waitUntilDone;
1866 if (waitUntilDone && TestController::singleton().useWaitToDumpWatchdogTimer())
1867 initializeWaitToDumpWatchdogTimerIfNeeded();
1868}
1869
1870void TestInvocation::done()
1871{
1872 m_gotFinalMessage = true;
1873 invalidateWaitToDumpWatchdogTimer();
1874 RunLoop::main().dispatch([] {
1875 TestController::singleton().notifyDone();
1876 });
1877}
1878
1879} // namespace WTR
1880