Wrap legacy WebRTC API in runtime flag
[WebKit-https.git] / Tools / WebKitTestRunner / InjectedBundle / InjectedBundle.cpp
1 /*
2  * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "InjectedBundle.h"
28
29 #include "ActivateFonts.h"
30 #include "InjectedBundlePage.h"
31 #include "StringFunctions.h"
32 #include "WebCoreTestSupport.h"
33 #include <WebKit/WKBundle.h>
34 #include <WebKit/WKBundlePage.h>
35 #include <WebKit/WKBundlePagePrivate.h>
36 #include <WebKit/WKBundlePrivate.h>
37 #include <WebKit/WKRetainPtr.h>
38 #include <WebKit/WebKit2_C.h>
39 #include <wtf/text/CString.h>
40 #include <wtf/text/StringBuilder.h>
41 #include <wtf/Vector.h>
42
43 namespace WTR {
44
45 InjectedBundle& InjectedBundle::singleton()
46 {
47     static InjectedBundle& shared = *new InjectedBundle;
48     return shared;
49 }
50
51 InjectedBundle::InjectedBundle()
52     : m_bundle(0)
53     , m_topLoadingFrame(0)
54     , m_state(Idle)
55     , m_dumpPixels(false)
56     , m_useWaitToDumpWatchdogTimer(true)
57     , m_useWorkQueue(false)
58     , m_timeout(0)
59 {
60 }
61
62 void InjectedBundle::didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
63 {
64     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didCreatePage(page);
65 }
66
67 void InjectedBundle::willDestroyPage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
68 {
69     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->willDestroyPage(page);
70 }
71
72 void InjectedBundle::didInitializePageGroup(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, const void* clientInfo)
73 {
74     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didInitializePageGroup(pageGroup);
75 }
76
77 void InjectedBundle::didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
78 {
79     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didReceiveMessage(messageName, messageBody);
80 }
81
82 void InjectedBundle::didReceiveMessageToPage(WKBundleRef bundle, WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
83 {
84     static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didReceiveMessageToPage(page, messageName, messageBody);
85 }
86
87 void InjectedBundle::initialize(WKBundleRef bundle, WKTypeRef initializationUserData)
88 {
89     m_bundle = bundle;
90
91     WKBundleClientV1 client = {
92         { 1, this },
93         didCreatePage,
94         willDestroyPage,
95         didInitializePageGroup,
96         didReceiveMessage,
97         didReceiveMessageToPage
98     };
99     WKBundleSetClient(m_bundle, &client.base);
100
101     platformInitialize(initializationUserData);
102
103     activateFonts();
104 }
105
106 void InjectedBundle::didCreatePage(WKBundlePageRef page)
107 {
108     m_pages.append(std::make_unique<InjectedBundlePage>(page));
109 }
110
111 void InjectedBundle::willDestroyPage(WKBundlePageRef page)
112 {
113     m_pages.removeFirstMatching([page](auto& current) {
114         return current->page() == page;
115     });
116 }
117
118 void InjectedBundle::didInitializePageGroup(WKBundlePageGroupRef pageGroup)
119 {
120     m_pageGroup = pageGroup;
121 }
122
123 InjectedBundlePage* InjectedBundle::page() const
124 {
125     // It might be better to have the UI process send over a reference to the main
126     // page instead of just assuming it's the first one.
127     return m_pages[0].get();
128 }
129
130 void InjectedBundle::resetLocalSettings()
131 {
132     setlocale(LC_ALL, "");
133 }
134
135 void InjectedBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody)
136 {
137     WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
138     WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
139     WKBundlePostMessage(m_bundle, errorMessageName.get(), errorMessageBody.get());
140 }
141
142 void InjectedBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody)
143 {
144     if (WKStringIsEqualToUTF8CString(messageName, "BeginTest")) {
145         ASSERT(messageBody);
146         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
147         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
148
149         WKRetainPtr<WKStringRef> dumpPixelsKey(AdoptWK, WKStringCreateWithUTF8CString("DumpPixels"));
150         m_dumpPixels = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, dumpPixelsKey.get())));
151
152         WKRetainPtr<WKStringRef> useWaitToDumpWatchdogTimerKey(AdoptWK, WKStringCreateWithUTF8CString("UseWaitToDumpWatchdogTimer"));
153         m_useWaitToDumpWatchdogTimer = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, useWaitToDumpWatchdogTimerKey.get())));
154
155         WKRetainPtr<WKStringRef> timeoutKey(AdoptWK, WKStringCreateWithUTF8CString("Timeout"));
156         m_timeout = (int)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, timeoutKey.get())));
157
158         WKRetainPtr<WKStringRef> dumpJSConsoleLogInStdErrKey(AdoptWK, WKStringCreateWithUTF8CString("DumpJSConsoleLogInStdErr"));
159         m_dumpJSConsoleLogInStdErr = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, dumpJSConsoleLogInStdErrKey.get())));
160
161         WKRetainPtr<WKStringRef> ackMessageName(AdoptWK, WKStringCreateWithUTF8CString("Ack"));
162         WKRetainPtr<WKStringRef> ackMessageBody(AdoptWK, WKStringCreateWithUTF8CString("BeginTest"));
163         WKBundlePagePostMessage(page, ackMessageName.get(), ackMessageBody.get());
164
165         beginTesting(messageBodyDictionary);
166         return;
167     }
168
169     if (WKStringIsEqualToUTF8CString(messageName, "Reset")) {
170         ASSERT(messageBody);
171         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
172         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
173
174         WKRetainPtr<WKStringRef> shouldGCKey(AdoptWK, WKStringCreateWithUTF8CString("ShouldGC"));
175         bool shouldGC = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, shouldGCKey.get())));
176
177         if (shouldGC)
178             WKBundleGarbageCollectJavaScriptObjects(m_bundle);
179
180         WKRetainPtr<WKStringRef> allowedHostsKey(AdoptWK, WKStringCreateWithUTF8CString("AllowedHosts"));
181         WKTypeRef allowedHostsValue = WKDictionaryGetItemForKey(messageBodyDictionary, allowedHostsKey.get());
182         if (allowedHostsValue && WKGetTypeID(allowedHostsValue) == WKArrayGetTypeID()) {
183             WKArrayRef allowedHostsArray = static_cast<WKArrayRef>(allowedHostsValue);
184             for (size_t i = 0, size = WKArrayGetSize(allowedHostsArray); i < size; ++i) {
185                 WKTypeRef item = WKArrayGetItemAtIndex(allowedHostsArray, i);
186                 if (item && WKGetTypeID(item) == WKStringGetTypeID())
187                     m_allowedHosts.append(toWTFString(static_cast<WKStringRef>(item)));
188             }
189         }
190
191         m_state = Idle;
192         m_dumpPixels = false;
193         m_pixelResultIsPending = false;
194
195         resetLocalSettings();
196         TestRunner::removeAllWebNotificationPermissions();
197
198         InjectedBundle::page()->resetAfterTest();
199
200         return;
201     }
202
203     if (WKStringIsEqualToUTF8CString(messageName, "CallAddChromeInputFieldCallback")) {
204         m_testRunner->callAddChromeInputFieldCallback();
205         return;
206     }
207
208     if (WKStringIsEqualToUTF8CString(messageName, "CallRemoveChromeInputFieldCallback")) {
209         m_testRunner->callRemoveChromeInputFieldCallback();
210         return;
211     }
212
213     if (WKStringIsEqualToUTF8CString(messageName, "CallFocusWebViewCallback")) {
214         m_testRunner->callFocusWebViewCallback();
215         return;
216     }
217
218     if (WKStringIsEqualToUTF8CString(messageName, "CallSetBackingScaleFactorCallback")) {
219         m_testRunner->callSetBackingScaleFactorCallback();
220         return;
221     }
222
223     if (WKStringIsEqualToUTF8CString(messageName, "CallDidBeginSwipeCallback")) {
224         m_testRunner->callDidBeginSwipeCallback();
225         return;
226     }
227
228     if (WKStringIsEqualToUTF8CString(messageName, "CallWillEndSwipeCallback")) {
229         m_testRunner->callWillEndSwipeCallback();
230         return;
231     }
232
233     if (WKStringIsEqualToUTF8CString(messageName, "CallDidEndSwipeCallback")) {
234         m_testRunner->callDidEndSwipeCallback();
235         return;
236     }
237
238     if (WKStringIsEqualToUTF8CString(messageName, "CallDidRemoveSwipeSnapshotCallback")) {
239         m_testRunner->callDidRemoveSwipeSnapshotCallback();
240         return;
241     }
242
243     if (WKStringIsEqualToUTF8CString(messageName, "NotifyDownloadDone")) {
244         m_testRunner->notifyDone();
245         return;
246     }
247
248     if (WKStringIsEqualToUTF8CString(messageName, "CallUISideScriptCallback")) {
249         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
250
251         WKRetainPtr<WKStringRef> resultKey(AdoptWK, WKStringCreateWithUTF8CString("Result"));
252         WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID"));
253
254         unsigned callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
255
256         WKStringRef resultString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, resultKey.get()));
257         auto resultJSString = toJS(resultString);
258
259         m_testRunner->runUIScriptCallback(callbackID, resultJSString.get());
260         return;
261     }
262
263     if (WKStringIsEqualToUTF8CString(messageName, "WorkQueueProcessedCallback")) {
264         if (!topLoadingFrame() && !m_testRunner->waitToDump())
265             InjectedBundle::page()->dump();
266         return;
267     }
268
269     if (WKStringIsEqualToUTF8CString(messageName, "WebsiteDataDeletionForTopPrivatelyOwnedDomainsFinished")) {
270         m_testRunner->statisticsDidModifyDataRecordsCallback();
271         return;
272     }
273
274     WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
275     WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
276     WKBundlePagePostMessage(page, errorMessageName.get(), errorMessageBody.get());
277 }
278
279 bool InjectedBundle::booleanForKey(WKDictionaryRef dictionary, const char* key)
280 {
281     WKRetainPtr<WKStringRef> wkKey(AdoptWK, WKStringCreateWithUTF8CString(key));
282     WKTypeRef value = WKDictionaryGetItemForKey(dictionary, wkKey.get());
283     if (WKGetTypeID(value) != WKBooleanGetTypeID()) {
284         outputText(makeString("Boolean value for key", key, " not found in dictionary\n"));
285         return false;
286     }
287     return WKBooleanGetValue(static_cast<WKBooleanRef>(value));
288 }
289
290 void InjectedBundle::beginTesting(WKDictionaryRef settings)
291 {
292     m_state = Testing;
293
294     m_pixelResult.clear();
295     m_repaintRects.clear();
296
297     m_testRunner = TestRunner::create();
298     m_gcController = GCController::create();
299     m_eventSendingController = EventSendingController::create();
300     m_textInputController = TextInputController::create();
301 #if HAVE(ACCESSIBILITY)
302     m_accessibilityController = AccessibilityController::create();
303 #endif
304
305     WKBundleSetAllowUniversalAccessFromFileURLs(m_bundle, m_pageGroup, true);
306     WKBundleSetJavaScriptCanAccessClipboard(m_bundle, m_pageGroup, true);
307     WKBundleSetPrivateBrowsingEnabled(m_bundle, m_pageGroup, false);
308     WKBundleSetUseDashboardCompatibilityMode(m_bundle, m_pageGroup, false);
309     WKBundleSetAuthorAndUserStylesEnabled(m_bundle, m_pageGroup, true);
310     WKBundleSetFrameFlatteningEnabled(m_bundle, m_pageGroup, false);
311     WKBundleSetMinimumLogicalFontSize(m_bundle, m_pageGroup, 9);
312     WKBundleSetSpatialNavigationEnabled(m_bundle, m_pageGroup, false);
313     WKBundleSetAllowFileAccessFromFileURLs(m_bundle, m_pageGroup, true);
314     WKBundleSetPopupBlockingEnabled(m_bundle, m_pageGroup, false);
315     WKBundleSetAllowStorageAccessFromFileURLS(m_bundle, m_pageGroup, false);
316
317 #if PLATFORM(IOS)
318     WKBundlePageSetUseTestingViewportConfiguration(page()->page(), !booleanForKey(settings, "UseFlexibleViewport"));
319 #endif
320
321     m_testRunner->setPluginsEnabled(true);
322
323     m_testRunner->setShouldDumpFrameLoadCallbacks(booleanForKey(settings, "DumpFrameLoadDelegates"));
324     m_testRunner->setUserStyleSheetEnabled(false);
325     m_testRunner->setXSSAuditorEnabled(false);
326
327     m_testRunner->setShadowDOMEnabled(true);
328     m_testRunner->setCustomElementsEnabled(true);
329
330     m_testRunner->setWebGL2Enabled(true);
331     m_testRunner->setWebGPUEnabled(true);
332
333     m_testRunner->setFetchAPIEnabled(true);
334
335     m_testRunner->setDownloadAttributeEnabled(true);
336
337     m_testRunner->setEncryptedMediaAPIEnabled(true);
338
339     m_testRunner->setCloseRemainingWindowsWhenComplete(false);
340     m_testRunner->setAcceptsEditing(true);
341     m_testRunner->setTabKeyCyclesThroughElements(true);
342     m_testRunner->clearTestRunnerCallbacks();
343
344     m_testRunner->setSubtleCryptoEnabled(true);
345
346     m_testRunner->setMediaStreamEnabled(true);
347     m_testRunner->setPeerConnectionEnabled(true);
348     m_testRunner->setWebRTCLegacyAPIEnabled(true);
349
350     if (m_timeout > 0)
351         m_testRunner->setCustomTimeout(m_timeout);
352
353     page()->prepare();
354
355     WKBundleClearAllDatabases(m_bundle);
356     WKBundlePageClearApplicationCache(page()->page());
357     WKBundleResetOriginAccessWhitelists(m_bundle);
358
359     // [WK2] REGRESSION(r128623): It made layout tests extremely slow
360     // https://bugs.webkit.org/show_bug.cgi?id=96862
361     // WKBundleSetDatabaseQuota(m_bundle, 5 * 1024 * 1024);
362 }
363
364 void InjectedBundle::done()
365 {
366     m_state = Stopping;
367
368     m_useWorkQueue = false;
369
370     page()->stopLoading();
371     setTopLoadingFrame(0);
372
373     m_testRunner->invalidateWaitToDumpWatchdogTimer();
374
375     m_accessibilityController->resetToConsistentState();
376
377     WKRetainPtr<WKStringRef> doneMessageName(AdoptWK, WKStringCreateWithUTF8CString("Done"));
378     WKRetainPtr<WKMutableDictionaryRef> doneMessageBody(AdoptWK, WKMutableDictionaryCreate());
379
380     WKRetainPtr<WKStringRef> pixelResultIsPendingKey = adoptWK(WKStringCreateWithUTF8CString("PixelResultIsPending"));
381     WKRetainPtr<WKBooleanRef> pixelResultIsPending(AdoptWK, WKBooleanCreate(m_pixelResultIsPending));
382     WKDictionarySetItem(doneMessageBody.get(), pixelResultIsPendingKey.get(), pixelResultIsPending.get());
383
384     if (!m_pixelResultIsPending) {
385         WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
386         WKDictionarySetItem(doneMessageBody.get(), pixelResultKey.get(), m_pixelResult.get());
387     }
388
389     WKRetainPtr<WKStringRef> repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects"));
390     WKDictionarySetItem(doneMessageBody.get(), repaintRectsKey.get(), m_repaintRects.get());
391
392     WKRetainPtr<WKStringRef> audioResultKey = adoptWK(WKStringCreateWithUTF8CString("AudioResult"));
393     WKDictionarySetItem(doneMessageBody.get(), audioResultKey.get(), m_audioResult.get());
394
395     WKBundlePagePostMessage(page()->page(), doneMessageName.get(), doneMessageBody.get());
396
397     closeOtherPages();
398
399     m_state = Idle;
400 }
401
402 void InjectedBundle::closeOtherPages()
403 {
404     Vector<WKBundlePageRef> pagesToClose;
405     size_t size = m_pages.size();
406     for (size_t i = 1; i < size; ++i)
407         pagesToClose.append(m_pages[i]->page());
408     size = pagesToClose.size();
409     for (size_t i = 0; i < size; ++i)
410         WKBundlePageClose(pagesToClose[i]);
411 }
412
413 void InjectedBundle::dumpBackForwardListsForAllPages(StringBuilder& stringBuilder)
414 {
415     size_t size = m_pages.size();
416     for (size_t i = 0; i < size; ++i)
417         m_pages[i]->dumpBackForwardList(stringBuilder);
418 }
419
420 void InjectedBundle::dumpToStdErr(const String& output)
421 {
422     if (m_state != Testing)
423         return;
424     if (output.isEmpty())
425         return;
426     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("DumpToStdErr"));
427     WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithUTF8CString(output.utf8().data()));
428     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
429 }
430
431 void InjectedBundle::outputText(const String& output)
432 {
433     if (m_state != Testing)
434         return;
435     if (output.isEmpty())
436         return;
437     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("TextOutput"));
438     WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithUTF8CString(output.utf8().data()));
439     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
440 }
441
442 void InjectedBundle::postNewBeforeUnloadReturnValue(bool value)
443 {
444     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("BeforeUnloadReturnValue"));
445     WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
446     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
447 }
448
449 void InjectedBundle::postAddChromeInputField()
450 {
451     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("AddChromeInputField"));
452     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
453 }
454
455 void InjectedBundle::postRemoveChromeInputField()
456 {
457     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("RemoveChromeInputField"));
458     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
459 }
460
461 void InjectedBundle::postFocusWebView()
462 {
463     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("FocusWebView"));
464     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
465 }
466
467 void InjectedBundle::postSetBackingScaleFactor(double backingScaleFactor)
468 {
469     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetBackingScaleFactor"));
470     WKRetainPtr<WKDoubleRef> messageBody(AdoptWK, WKDoubleCreate(backingScaleFactor));
471     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
472 }
473
474 void InjectedBundle::postSetWindowIsKey(bool isKey)
475 {
476     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetWindowIsKey"));
477     WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(isKey));
478     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), messageBody.get(), 0);
479 }
480
481 void InjectedBundle::postSetViewSize(double width, double height)
482 {
483     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetViewSize"));
484
485     WKRetainPtr<WKStringRef> widthKey(AdoptWK, WKStringCreateWithUTF8CString("width"));
486     WKRetainPtr<WKStringRef> heightKey(AdoptWK, WKStringCreateWithUTF8CString("height"));
487
488     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
489
490     WKRetainPtr<WKDoubleRef> widthWK(AdoptWK, WKDoubleCreate(width));
491     WKDictionarySetItem(messageBody.get(), widthKey.get(), widthWK.get());
492
493     WKRetainPtr<WKDoubleRef> heightWK(AdoptWK, WKDoubleCreate(height));
494     WKDictionarySetItem(messageBody.get(), heightKey.get(), heightWK.get());
495
496     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), messageBody.get(), 0);
497 }
498
499 void InjectedBundle::postSimulateWebNotificationClick(uint64_t notificationID)
500 {
501     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SimulateWebNotificationClick"));
502     WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(notificationID));
503     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
504 }
505
506 void InjectedBundle::postSetAddsVisitedLinks(bool addsVisitedLinks)
507 {
508     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetAddsVisitedLinks"));
509     WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(addsVisitedLinks));
510     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
511 }
512
513 void InjectedBundle::setGeolocationPermission(bool enabled)
514 {
515     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetGeolocationPermission"));
516     WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(enabled));
517     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
518 }
519
520 void InjectedBundle::setMockGeolocationPosition(double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed)
521 {
522     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGeolocationPosition"));
523
524     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
525
526     WKRetainPtr<WKStringRef> latitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("latitude"));
527     WKRetainPtr<WKDoubleRef> latitudeWK(AdoptWK, WKDoubleCreate(latitude));
528     WKDictionarySetItem(messageBody.get(), latitudeKeyWK.get(), latitudeWK.get());
529
530     WKRetainPtr<WKStringRef> longitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("longitude"));
531     WKRetainPtr<WKDoubleRef> longitudeWK(AdoptWK, WKDoubleCreate(longitude));
532     WKDictionarySetItem(messageBody.get(), longitudeKeyWK.get(), longitudeWK.get());
533
534     WKRetainPtr<WKStringRef> accuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("accuracy"));
535     WKRetainPtr<WKDoubleRef> accuracyWK(AdoptWK, WKDoubleCreate(accuracy));
536     WKDictionarySetItem(messageBody.get(), accuracyKeyWK.get(), accuracyWK.get());
537
538     WKRetainPtr<WKStringRef> providesAltitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesAltitude"));
539     WKRetainPtr<WKBooleanRef> providesAltitudeWK(AdoptWK, WKBooleanCreate(providesAltitude));
540     WKDictionarySetItem(messageBody.get(), providesAltitudeKeyWK.get(), providesAltitudeWK.get());
541
542     WKRetainPtr<WKStringRef> altitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("altitude"));
543     WKRetainPtr<WKDoubleRef> altitudeWK(AdoptWK, WKDoubleCreate(altitude));
544     WKDictionarySetItem(messageBody.get(), altitudeKeyWK.get(), altitudeWK.get());
545
546     WKRetainPtr<WKStringRef> providesAltitudeAccuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesAltitudeAccuracy"));
547     WKRetainPtr<WKBooleanRef> providesAltitudeAccuracyWK(AdoptWK, WKBooleanCreate(providesAltitudeAccuracy));
548     WKDictionarySetItem(messageBody.get(), providesAltitudeAccuracyKeyWK.get(), providesAltitudeAccuracyWK.get());
549
550     WKRetainPtr<WKStringRef> altitudeAccuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("altitudeAccuracy"));
551     WKRetainPtr<WKDoubleRef> altitudeAccuracyWK(AdoptWK, WKDoubleCreate(altitudeAccuracy));
552     WKDictionarySetItem(messageBody.get(), altitudeAccuracyKeyWK.get(), altitudeAccuracyWK.get());
553
554     WKRetainPtr<WKStringRef> providesHeadingKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesHeading"));
555     WKRetainPtr<WKBooleanRef> providesHeadingWK(AdoptWK, WKBooleanCreate(providesHeading));
556     WKDictionarySetItem(messageBody.get(), providesHeadingKeyWK.get(), providesHeadingWK.get());
557
558     WKRetainPtr<WKStringRef> headingKeyWK(AdoptWK, WKStringCreateWithUTF8CString("heading"));
559     WKRetainPtr<WKDoubleRef> headingWK(AdoptWK, WKDoubleCreate(heading));
560     WKDictionarySetItem(messageBody.get(), headingKeyWK.get(), headingWK.get());
561
562     WKRetainPtr<WKStringRef> providesSpeedKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesSpeed"));
563     WKRetainPtr<WKBooleanRef> providesSpeedWK(AdoptWK, WKBooleanCreate(providesSpeed));
564     WKDictionarySetItem(messageBody.get(), providesSpeedKeyWK.get(), providesSpeedWK.get());
565
566     WKRetainPtr<WKStringRef> speedKeyWK(AdoptWK, WKStringCreateWithUTF8CString("speed"));
567     WKRetainPtr<WKDoubleRef> speedWK(AdoptWK, WKDoubleCreate(speed));
568     WKDictionarySetItem(messageBody.get(), speedKeyWK.get(), speedWK.get());
569
570     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
571 }
572
573 void InjectedBundle::setMockGeolocationPositionUnavailableError(WKStringRef errorMessage)
574 {
575     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGeolocationPositionUnavailableError"));
576     WKBundlePagePostMessage(page()->page(), messageName.get(), errorMessage);
577 }
578
579 bool InjectedBundle::isGeolocationProviderActive() const
580 {
581     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsGeolocationClientActive"));
582     WKTypeRef resultToPass = 0;
583     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), 0, &resultToPass);
584     WKRetainPtr<WKBooleanRef> isActive(AdoptWK, static_cast<WKBooleanRef>(resultToPass));
585
586     return WKBooleanGetValue(isActive.get());
587 }
588
589 unsigned InjectedBundle::imageCountInGeneralPasteboard() const
590 {
591     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ImageCountInGeneralPasteboard"));
592     WKTypeRef resultToPass = 0;
593     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), 0, &resultToPass);
594     WKRetainPtr<WKUInt64Ref> imageCount(AdoptWK, static_cast<WKUInt64Ref>(resultToPass));
595     
596     return static_cast<unsigned>(WKUInt64GetValue(imageCount.get()));
597 }
598
599 void InjectedBundle::setUserMediaPermission(bool enabled)
600 {
601     auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetUserMediaPermission"));
602     auto messageBody = adoptWK(WKBooleanCreate(enabled));
603     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
604 }
605
606 void InjectedBundle::setUserMediaPersistentPermissionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin)
607 {
608     auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetUserMediaPersistentPermissionForOrigin"));
609     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
610
611     WKRetainPtr<WKStringRef> permissionKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permission"));
612     WKRetainPtr<WKBooleanRef> permissionWK(AdoptWK, WKBooleanCreate(permission));
613     WKDictionarySetItem(messageBody.get(), permissionKeyWK.get(), permissionWK.get());
614
615     WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin"));
616     WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin);
617
618     WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
619     WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin);
620
621     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
622 }
623
624 unsigned InjectedBundle::userMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin) const
625 {
626     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("UserMediaPermissionRequestCountForOrigin"));
627     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
628
629     WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin"));
630     WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin);
631
632     WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
633     WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin);
634
635     WKTypeRef resultToPass = 0;
636     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), messageBody.get(), &resultToPass);
637     WKRetainPtr<WKUInt64Ref> count(AdoptWK, static_cast<WKUInt64Ref>(resultToPass));
638
639     return static_cast<unsigned>(WKUInt64GetValue(count.get()));
640 }
641
642 void InjectedBundle::resetUserMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin)
643 {
644     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ResetUserMediaPermissionRequestCountForOrigin"));
645     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
646
647     WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin"));
648     WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin);
649
650     WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
651     WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin);
652
653     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
654 }
655
656 void InjectedBundle::setCustomPolicyDelegate(bool enabled, bool permissive)
657 {
658     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetCustomPolicyDelegate"));
659
660     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
661
662     WKRetainPtr<WKStringRef> enabledKeyWK(AdoptWK, WKStringCreateWithUTF8CString("enabled"));
663     WKRetainPtr<WKBooleanRef> enabledWK(AdoptWK, WKBooleanCreate(enabled));
664     WKDictionarySetItem(messageBody.get(), enabledKeyWK.get(), enabledWK.get());
665
666     WKRetainPtr<WKStringRef> permissiveKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permissive"));
667     WKRetainPtr<WKBooleanRef> permissiveWK(AdoptWK, WKBooleanCreate(permissive));
668     WKDictionarySetItem(messageBody.get(), permissiveKeyWK.get(), permissiveWK.get());
669
670     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
671 }
672
673 void InjectedBundle::setHidden(bool hidden)
674 {
675     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetHidden"));
676     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
677
678     WKRetainPtr<WKStringRef> isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("hidden"));
679     WKRetainPtr<WKBooleanRef> isInitialWK(AdoptWK, WKBooleanCreate(hidden));
680     WKDictionarySetItem(messageBody.get(), isInitialKeyWK.get(), isInitialWK.get());
681
682     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
683 }
684
685 void InjectedBundle::setCacheModel(int model)
686 {
687     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetCacheModel"));
688     WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(model));
689     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
690 }
691
692 bool InjectedBundle::shouldProcessWorkQueue() const
693 {
694     if (!m_useWorkQueue)
695         return false;
696
697     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsWorkQueueEmpty"));
698     WKTypeRef resultToPass = 0;
699     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), 0, &resultToPass);
700     WKRetainPtr<WKBooleanRef> isEmpty(AdoptWK, static_cast<WKBooleanRef>(resultToPass));
701
702     return !WKBooleanGetValue(isEmpty.get());
703 }
704
705 void InjectedBundle::processWorkQueue()
706 {
707     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ProcessWorkQueue"));
708     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
709 }
710
711 void InjectedBundle::queueBackNavigation(unsigned howFarBackward)
712 {
713     m_useWorkQueue = true;
714
715     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueBackNavigation"));
716     WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(howFarBackward));
717     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
718 }
719
720 void InjectedBundle::queueForwardNavigation(unsigned howFarForward)
721 {
722     m_useWorkQueue = true;
723
724     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueForwardNavigation"));
725     WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(howFarForward));
726     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
727 }
728
729 void InjectedBundle::queueLoad(WKStringRef url, WKStringRef target, bool shouldOpenExternalURLs)
730 {
731     m_useWorkQueue = true;
732
733     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueLoad"));
734
735     WKRetainPtr<WKMutableDictionaryRef> loadData(AdoptWK, WKMutableDictionaryCreate());
736
737     WKRetainPtr<WKStringRef> urlKey(AdoptWK, WKStringCreateWithUTF8CString("url"));
738     WKDictionarySetItem(loadData.get(), urlKey.get(), url);
739
740     WKRetainPtr<WKStringRef> targetKey(AdoptWK, WKStringCreateWithUTF8CString("target"));
741     WKDictionarySetItem(loadData.get(), targetKey.get(), target);
742
743     WKRetainPtr<WKStringRef> shouldOpenExternalURLsKey(AdoptWK, WKStringCreateWithUTF8CString("shouldOpenExternalURLs"));
744     WKRetainPtr<WKBooleanRef> shouldOpenExternalURLsValue(AdoptWK, WKBooleanCreate(shouldOpenExternalURLs));
745     WKDictionarySetItem(loadData.get(), shouldOpenExternalURLsKey.get(), shouldOpenExternalURLsValue.get());
746
747     WKBundlePagePostMessage(page()->page(), messageName.get(), loadData.get());
748 }
749
750 void InjectedBundle::queueLoadHTMLString(WKStringRef content, WKStringRef baseURL, WKStringRef unreachableURL)
751 {
752     m_useWorkQueue = true;
753
754     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueLoadHTMLString"));
755
756     WKRetainPtr<WKMutableDictionaryRef> loadData(AdoptWK, WKMutableDictionaryCreate());
757
758     WKRetainPtr<WKStringRef> contentKey(AdoptWK, WKStringCreateWithUTF8CString("content"));
759     WKDictionarySetItem(loadData.get(), contentKey.get(), content);
760
761     if (baseURL) {
762         WKRetainPtr<WKStringRef> baseURLKey(AdoptWK, WKStringCreateWithUTF8CString("baseURL"));
763         WKDictionarySetItem(loadData.get(), baseURLKey.get(), baseURL);
764     }
765
766     if (unreachableURL) {
767         WKRetainPtr<WKStringRef> unreachableURLKey(AdoptWK, WKStringCreateWithUTF8CString("unreachableURL"));
768         WKDictionarySetItem(loadData.get(), unreachableURLKey.get(), unreachableURL);
769     }
770
771     WKBundlePagePostMessage(page()->page(), messageName.get(), loadData.get());
772 }
773
774 void InjectedBundle::queueReload()
775 {
776     m_useWorkQueue = true;
777
778     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueReload"));
779     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
780 }
781
782 void InjectedBundle::queueLoadingScript(WKStringRef script)
783 {
784     m_useWorkQueue = true;
785
786     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueLoadingScript"));
787     WKBundlePagePostMessage(page()->page(), messageName.get(), script);
788 }
789
790 void InjectedBundle::queueNonLoadingScript(WKStringRef script)
791 {
792     m_useWorkQueue = true;
793
794     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueNonLoadingScript"));
795     WKBundlePagePostMessage(page()->page(), messageName.get(), script);
796 }
797
798 bool InjectedBundle::isAllowedHost(WKStringRef host)
799 {
800     if (m_allowedHosts.isEmpty())
801         return false;
802     return m_allowedHosts.contains(toWTFString(host));
803 }
804
805 void InjectedBundle::setAllowsAnySSLCertificate(bool allowsAnySSLCertificate)
806 {
807     WebCoreTestSupport::setAllowsAnySSLCertificate(allowsAnySSLCertificate);
808 }
809
810 } // namespace WTR