Add and remove cookie partition accordingly in intermediary redirect requests
[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, "CallDidClearStatisticsThroughWebsiteDataRemoval")) {
244         m_testRunner->statisticsCallClearThroughWebsiteDataRemovalCallback();
245         return;
246     }
247
248     if (WKStringIsEqualToUTF8CString(messageName, "CallDidRemoveAllSessionCredentialsCallback")) {
249         m_testRunner->callDidRemoveAllSessionCredentialsCallback();
250         return;
251     }
252
253     if (WKStringIsEqualToUTF8CString(messageName, "NotifyDownloadDone")) {
254         if (m_testRunner->shouldFinishAfterDownload())
255             m_testRunner->notifyDone();
256         return;
257     }
258
259     if (WKStringIsEqualToUTF8CString(messageName, "CallUISideScriptCallback")) {
260         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
261
262         WKRetainPtr<WKStringRef> resultKey(AdoptWK, WKStringCreateWithUTF8CString("Result"));
263         WKRetainPtr<WKStringRef> callbackIDKey(AdoptWK, WKStringCreateWithUTF8CString("CallbackID"));
264
265         unsigned callbackID = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
266
267         WKStringRef resultString = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, resultKey.get()));
268         auto resultJSString = toJS(resultString);
269
270         m_testRunner->runUIScriptCallback(callbackID, resultJSString.get());
271         return;
272     }
273
274     if (WKStringIsEqualToUTF8CString(messageName, "WorkQueueProcessedCallback")) {
275         if (!topLoadingFrame() && !m_testRunner->waitToDump())
276             InjectedBundle::page()->dump();
277         return;
278     }
279
280     if (WKStringIsEqualToUTF8CString(messageName, "WebsiteDataDeletionForTopPrivatelyOwnedDomainsFinished")) {
281         m_testRunner->statisticsDidModifyDataRecordsCallback();
282         return;
283     }
284
285     if (WKStringIsEqualToUTF8CString(messageName, "WebsiteDataScanForTopPrivatelyControlledDomainsFinished")) {
286         m_testRunner->statisticsDidScanDataRecordsCallback();
287         return;
288     }
289
290     if (WKStringIsEqualToUTF8CString(messageName, "ResourceLoadStatisticsTelemetryFinished")) {
291         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
292         
293         unsigned totalPrevalentResources = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, WKStringCreateWithUTF8CString("TotalPrevalentResources"))));
294         unsigned totalPrevalentResourcesWithUserInteraction = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, WKStringCreateWithUTF8CString("TotalPrevalentResourcesWithUserInteraction"))));
295         unsigned top3SubframeUnderTopFrameOrigins = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, WKStringCreateWithUTF8CString("Top3SubframeUnderTopFrameOrigins"))));
296         
297         m_testRunner->statisticsDidRunTelemetryCallback(totalPrevalentResources, totalPrevalentResourcesWithUserInteraction, top3SubframeUnderTopFrameOrigins);
298         return;
299     }
300     
301     WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
302     WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
303     WKBundlePagePostMessage(page, errorMessageName.get(), errorMessageBody.get());
304 }
305
306 bool InjectedBundle::booleanForKey(WKDictionaryRef dictionary, const char* key)
307 {
308     WKRetainPtr<WKStringRef> wkKey(AdoptWK, WKStringCreateWithUTF8CString(key));
309     WKTypeRef value = WKDictionaryGetItemForKey(dictionary, wkKey.get());
310     if (WKGetTypeID(value) != WKBooleanGetTypeID()) {
311         outputText(makeString("Boolean value for key", key, " not found in dictionary\n"));
312         return false;
313     }
314     return WKBooleanGetValue(static_cast<WKBooleanRef>(value));
315 }
316
317 void InjectedBundle::beginTesting(WKDictionaryRef settings)
318 {
319     m_state = Testing;
320
321     m_pixelResult.clear();
322     m_repaintRects.clear();
323
324     m_testRunner = TestRunner::create();
325     m_gcController = GCController::create();
326     m_eventSendingController = EventSendingController::create();
327     m_textInputController = TextInputController::create();
328 #if HAVE(ACCESSIBILITY)
329     m_accessibilityController = AccessibilityController::create();
330 #endif
331
332     WKBundleSetAllowUniversalAccessFromFileURLs(m_bundle, m_pageGroup, true);
333     WKBundleSetJavaScriptCanAccessClipboard(m_bundle, m_pageGroup, true);
334     WKBundleSetPrivateBrowsingEnabled(m_bundle, m_pageGroup, false);
335     WKBundleSetUseDashboardCompatibilityMode(m_bundle, m_pageGroup, false);
336     WKBundleSetAuthorAndUserStylesEnabled(m_bundle, m_pageGroup, true);
337     WKBundleSetFrameFlatteningEnabled(m_bundle, m_pageGroup, false);
338     WKBundleSetAsyncFrameScrollingEnabled(m_bundle, m_pageGroup, false);
339     WKBundleSetMinimumLogicalFontSize(m_bundle, m_pageGroup, 9);
340     WKBundleSetSpatialNavigationEnabled(m_bundle, m_pageGroup, false);
341     WKBundleSetAllowFileAccessFromFileURLs(m_bundle, m_pageGroup, true);
342     WKBundleSetPopupBlockingEnabled(m_bundle, m_pageGroup, false);
343     WKBundleSetAllowStorageAccessFromFileURLS(m_bundle, m_pageGroup, false);
344
345 #if PLATFORM(IOS)
346     WKBundlePageSetUseTestingViewportConfiguration(page()->page(), !booleanForKey(settings, "UseFlexibleViewport"));
347 #endif
348
349     m_testRunner->setPluginsEnabled(true);
350
351     m_testRunner->setShouldDumpFrameLoadCallbacks(booleanForKey(settings, "DumpFrameLoadDelegates"));
352     m_testRunner->setUserStyleSheetEnabled(false);
353     m_testRunner->setXSSAuditorEnabled(false);
354
355     m_testRunner->setWebGL2Enabled(true);
356     m_testRunner->setWebGPUEnabled(true);
357
358     m_testRunner->setWritableStreamAPIEnabled(true);
359     m_testRunner->setReadableByteStreamAPIEnabled(true);
360
361     m_testRunner->setEncryptedMediaAPIEnabled(true);
362
363     m_testRunner->setCloseRemainingWindowsWhenComplete(false);
364     m_testRunner->setAcceptsEditing(true);
365     m_testRunner->setTabKeyCyclesThroughElements(true);
366     m_testRunner->clearTestRunnerCallbacks();
367
368     if (m_timeout > 0)
369         m_testRunner->setCustomTimeout(m_timeout);
370
371     page()->prepare();
372
373     WKBundleClearAllDatabases(m_bundle);
374     WKBundlePageClearApplicationCache(page()->page());
375     WKBundleResetOriginAccessWhitelists(m_bundle);
376     WKBundleClearResourceLoadStatistics(m_bundle);
377
378     // [WK2] REGRESSION(r128623): It made layout tests extremely slow
379     // https://bugs.webkit.org/show_bug.cgi?id=96862
380     // WKBundleSetDatabaseQuota(m_bundle, 5 * 1024 * 1024);
381 }
382
383 void InjectedBundle::done()
384 {
385     m_state = Stopping;
386
387     m_useWorkQueue = false;
388
389     page()->stopLoading();
390     setTopLoadingFrame(0);
391
392     m_testRunner->invalidateWaitToDumpWatchdogTimer();
393
394     m_accessibilityController->resetToConsistentState();
395
396     WKRetainPtr<WKStringRef> doneMessageName(AdoptWK, WKStringCreateWithUTF8CString("Done"));
397     WKRetainPtr<WKMutableDictionaryRef> doneMessageBody(AdoptWK, WKMutableDictionaryCreate());
398
399     WKRetainPtr<WKStringRef> pixelResultIsPendingKey = adoptWK(WKStringCreateWithUTF8CString("PixelResultIsPending"));
400     WKRetainPtr<WKBooleanRef> pixelResultIsPending(AdoptWK, WKBooleanCreate(m_pixelResultIsPending));
401     WKDictionarySetItem(doneMessageBody.get(), pixelResultIsPendingKey.get(), pixelResultIsPending.get());
402
403     if (!m_pixelResultIsPending) {
404         WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
405         WKDictionarySetItem(doneMessageBody.get(), pixelResultKey.get(), m_pixelResult.get());
406     }
407
408     WKRetainPtr<WKStringRef> repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects"));
409     WKDictionarySetItem(doneMessageBody.get(), repaintRectsKey.get(), m_repaintRects.get());
410
411     WKRetainPtr<WKStringRef> audioResultKey = adoptWK(WKStringCreateWithUTF8CString("AudioResult"));
412     WKDictionarySetItem(doneMessageBody.get(), audioResultKey.get(), m_audioResult.get());
413
414     WKBundlePagePostMessage(page()->page(), doneMessageName.get(), doneMessageBody.get());
415
416     closeOtherPages();
417
418     m_state = Idle;
419 }
420
421 void InjectedBundle::closeOtherPages()
422 {
423     Vector<WKBundlePageRef> pagesToClose;
424     size_t size = m_pages.size();
425     for (size_t i = 1; i < size; ++i)
426         pagesToClose.append(m_pages[i]->page());
427     size = pagesToClose.size();
428     for (size_t i = 0; i < size; ++i)
429         WKBundlePageClose(pagesToClose[i]);
430 }
431
432 void InjectedBundle::dumpBackForwardListsForAllPages(StringBuilder& stringBuilder)
433 {
434     size_t size = m_pages.size();
435     for (size_t i = 0; i < size; ++i)
436         m_pages[i]->dumpBackForwardList(stringBuilder);
437 }
438
439 void InjectedBundle::dumpToStdErr(const String& output)
440 {
441     if (m_state != Testing)
442         return;
443     if (output.isEmpty())
444         return;
445     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("DumpToStdErr"));
446     WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithUTF8CString(output.utf8().data()));
447     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
448 }
449
450 void InjectedBundle::outputText(const String& output)
451 {
452     if (m_state != Testing)
453         return;
454     if (output.isEmpty())
455         return;
456     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("TextOutput"));
457     WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithUTF8CString(output.utf8().data()));
458     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
459 }
460
461 void InjectedBundle::postNewBeforeUnloadReturnValue(bool value)
462 {
463     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("BeforeUnloadReturnValue"));
464     WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
465     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
466 }
467
468 void InjectedBundle::postAddChromeInputField()
469 {
470     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("AddChromeInputField"));
471     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
472 }
473
474 void InjectedBundle::postRemoveChromeInputField()
475 {
476     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("RemoveChromeInputField"));
477     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
478 }
479
480 void InjectedBundle::postFocusWebView()
481 {
482     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("FocusWebView"));
483     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
484 }
485
486 void InjectedBundle::postSetBackingScaleFactor(double backingScaleFactor)
487 {
488     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetBackingScaleFactor"));
489     WKRetainPtr<WKDoubleRef> messageBody(AdoptWK, WKDoubleCreate(backingScaleFactor));
490     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
491 }
492
493 void InjectedBundle::postSetWindowIsKey(bool isKey)
494 {
495     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetWindowIsKey"));
496     WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(isKey));
497     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), messageBody.get(), 0);
498 }
499
500 void InjectedBundle::postSetViewSize(double width, double height)
501 {
502     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetViewSize"));
503
504     WKRetainPtr<WKStringRef> widthKey(AdoptWK, WKStringCreateWithUTF8CString("width"));
505     WKRetainPtr<WKStringRef> heightKey(AdoptWK, WKStringCreateWithUTF8CString("height"));
506
507     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
508
509     WKRetainPtr<WKDoubleRef> widthWK(AdoptWK, WKDoubleCreate(width));
510     WKDictionarySetItem(messageBody.get(), widthKey.get(), widthWK.get());
511
512     WKRetainPtr<WKDoubleRef> heightWK(AdoptWK, WKDoubleCreate(height));
513     WKDictionarySetItem(messageBody.get(), heightKey.get(), heightWK.get());
514
515     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), messageBody.get(), 0);
516 }
517
518 void InjectedBundle::postSimulateWebNotificationClick(uint64_t notificationID)
519 {
520     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SimulateWebNotificationClick"));
521     WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(notificationID));
522     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
523 }
524
525 void InjectedBundle::postSetAddsVisitedLinks(bool addsVisitedLinks)
526 {
527     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetAddsVisitedLinks"));
528     WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(addsVisitedLinks));
529     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
530 }
531
532 void InjectedBundle::setGeolocationPermission(bool enabled)
533 {
534     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetGeolocationPermission"));
535     WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(enabled));
536     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
537 }
538
539 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, bool providesFloorLevel, double floorLevel)
540 {
541     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGeolocationPosition"));
542
543     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
544
545     WKRetainPtr<WKStringRef> latitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("latitude"));
546     WKRetainPtr<WKDoubleRef> latitudeWK(AdoptWK, WKDoubleCreate(latitude));
547     WKDictionarySetItem(messageBody.get(), latitudeKeyWK.get(), latitudeWK.get());
548
549     WKRetainPtr<WKStringRef> longitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("longitude"));
550     WKRetainPtr<WKDoubleRef> longitudeWK(AdoptWK, WKDoubleCreate(longitude));
551     WKDictionarySetItem(messageBody.get(), longitudeKeyWK.get(), longitudeWK.get());
552
553     WKRetainPtr<WKStringRef> accuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("accuracy"));
554     WKRetainPtr<WKDoubleRef> accuracyWK(AdoptWK, WKDoubleCreate(accuracy));
555     WKDictionarySetItem(messageBody.get(), accuracyKeyWK.get(), accuracyWK.get());
556
557     WKRetainPtr<WKStringRef> providesAltitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesAltitude"));
558     WKRetainPtr<WKBooleanRef> providesAltitudeWK(AdoptWK, WKBooleanCreate(providesAltitude));
559     WKDictionarySetItem(messageBody.get(), providesAltitudeKeyWK.get(), providesAltitudeWK.get());
560
561     WKRetainPtr<WKStringRef> altitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("altitude"));
562     WKRetainPtr<WKDoubleRef> altitudeWK(AdoptWK, WKDoubleCreate(altitude));
563     WKDictionarySetItem(messageBody.get(), altitudeKeyWK.get(), altitudeWK.get());
564
565     WKRetainPtr<WKStringRef> providesAltitudeAccuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesAltitudeAccuracy"));
566     WKRetainPtr<WKBooleanRef> providesAltitudeAccuracyWK(AdoptWK, WKBooleanCreate(providesAltitudeAccuracy));
567     WKDictionarySetItem(messageBody.get(), providesAltitudeAccuracyKeyWK.get(), providesAltitudeAccuracyWK.get());
568
569     WKRetainPtr<WKStringRef> altitudeAccuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("altitudeAccuracy"));
570     WKRetainPtr<WKDoubleRef> altitudeAccuracyWK(AdoptWK, WKDoubleCreate(altitudeAccuracy));
571     WKDictionarySetItem(messageBody.get(), altitudeAccuracyKeyWK.get(), altitudeAccuracyWK.get());
572
573     WKRetainPtr<WKStringRef> providesHeadingKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesHeading"));
574     WKRetainPtr<WKBooleanRef> providesHeadingWK(AdoptWK, WKBooleanCreate(providesHeading));
575     WKDictionarySetItem(messageBody.get(), providesHeadingKeyWK.get(), providesHeadingWK.get());
576
577     WKRetainPtr<WKStringRef> headingKeyWK(AdoptWK, WKStringCreateWithUTF8CString("heading"));
578     WKRetainPtr<WKDoubleRef> headingWK(AdoptWK, WKDoubleCreate(heading));
579     WKDictionarySetItem(messageBody.get(), headingKeyWK.get(), headingWK.get());
580
581     WKRetainPtr<WKStringRef> providesSpeedKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesSpeed"));
582     WKRetainPtr<WKBooleanRef> providesSpeedWK(AdoptWK, WKBooleanCreate(providesSpeed));
583     WKDictionarySetItem(messageBody.get(), providesSpeedKeyWK.get(), providesSpeedWK.get());
584
585     WKRetainPtr<WKStringRef> speedKeyWK(AdoptWK, WKStringCreateWithUTF8CString("speed"));
586     WKRetainPtr<WKDoubleRef> speedWK(AdoptWK, WKDoubleCreate(speed));
587     WKDictionarySetItem(messageBody.get(), speedKeyWK.get(), speedWK.get());
588
589     WKRetainPtr<WKStringRef> providesFloorLevelKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesFloorLevel"));
590     WKRetainPtr<WKBooleanRef> providesFloorLevelWK(AdoptWK, WKBooleanCreate(providesFloorLevel));
591     WKDictionarySetItem(messageBody.get(), providesFloorLevelKeyWK.get(), providesFloorLevelWK.get());
592
593     WKRetainPtr<WKStringRef> floorLevelKeyWK(AdoptWK, WKStringCreateWithUTF8CString("floorLevel"));
594     WKRetainPtr<WKDoubleRef> floorLevelWK(AdoptWK, WKDoubleCreate(floorLevel));
595     WKDictionarySetItem(messageBody.get(), floorLevelKeyWK.get(), floorLevelWK.get());
596
597     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
598 }
599
600 void InjectedBundle::setMockGeolocationPositionUnavailableError(WKStringRef errorMessage)
601 {
602     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGeolocationPositionUnavailableError"));
603     WKBundlePagePostMessage(page()->page(), messageName.get(), errorMessage);
604 }
605
606 bool InjectedBundle::isGeolocationProviderActive() const
607 {
608     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsGeolocationClientActive"));
609     WKTypeRef resultToPass = 0;
610     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), 0, &resultToPass);
611     WKRetainPtr<WKBooleanRef> isActive(AdoptWK, static_cast<WKBooleanRef>(resultToPass));
612
613     return WKBooleanGetValue(isActive.get());
614 }
615
616 unsigned InjectedBundle::imageCountInGeneralPasteboard() const
617 {
618     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ImageCountInGeneralPasteboard"));
619     WKTypeRef resultToPass = 0;
620     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), 0, &resultToPass);
621     WKRetainPtr<WKUInt64Ref> imageCount(AdoptWK, static_cast<WKUInt64Ref>(resultToPass));
622     
623     return static_cast<unsigned>(WKUInt64GetValue(imageCount.get()));
624 }
625
626 void InjectedBundle::setUserMediaPermission(bool enabled)
627 {
628     auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetUserMediaPermission"));
629     auto messageBody = adoptWK(WKBooleanCreate(enabled));
630     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
631 }
632
633 void InjectedBundle::resetUserMediaPermission()
634 {
635     auto messageName = adoptWK(WKStringCreateWithUTF8CString("ResetUserMediaPermission"));
636     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
637 }
638
639 void InjectedBundle::setUserMediaPersistentPermissionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin)
640 {
641     auto messageName = adoptWK(WKStringCreateWithUTF8CString("SetUserMediaPersistentPermissionForOrigin"));
642     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
643
644     WKRetainPtr<WKStringRef> permissionKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permission"));
645     WKRetainPtr<WKBooleanRef> permissionWK(AdoptWK, WKBooleanCreate(permission));
646     WKDictionarySetItem(messageBody.get(), permissionKeyWK.get(), permissionWK.get());
647
648     WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin"));
649     WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin);
650
651     WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
652     WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin);
653
654     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
655 }
656
657 unsigned InjectedBundle::userMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin) const
658 {
659     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("UserMediaPermissionRequestCountForOrigin"));
660     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
661
662     WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin"));
663     WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin);
664
665     WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
666     WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin);
667
668     WKTypeRef resultToPass = 0;
669     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), messageBody.get(), &resultToPass);
670     WKRetainPtr<WKUInt64Ref> count(AdoptWK, static_cast<WKUInt64Ref>(resultToPass));
671
672     return static_cast<unsigned>(WKUInt64GetValue(count.get()));
673 }
674
675 void InjectedBundle::resetUserMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin)
676 {
677     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ResetUserMediaPermissionRequestCountForOrigin"));
678     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
679
680     WKRetainPtr<WKStringRef> originKeyWK(AdoptWK, WKStringCreateWithUTF8CString("origin"));
681     WKDictionarySetItem(messageBody.get(), originKeyWK.get(), origin);
682
683     WKRetainPtr<WKStringRef> parentOriginKeyWK(AdoptWK, WKStringCreateWithUTF8CString("parentOrigin"));
684     WKDictionarySetItem(messageBody.get(), parentOriginKeyWK.get(), parentOrigin);
685
686     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
687 }
688
689 void InjectedBundle::setCustomPolicyDelegate(bool enabled, bool permissive)
690 {
691     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetCustomPolicyDelegate"));
692
693     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
694
695     WKRetainPtr<WKStringRef> enabledKeyWK(AdoptWK, WKStringCreateWithUTF8CString("enabled"));
696     WKRetainPtr<WKBooleanRef> enabledWK(AdoptWK, WKBooleanCreate(enabled));
697     WKDictionarySetItem(messageBody.get(), enabledKeyWK.get(), enabledWK.get());
698
699     WKRetainPtr<WKStringRef> permissiveKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permissive"));
700     WKRetainPtr<WKBooleanRef> permissiveWK(AdoptWK, WKBooleanCreate(permissive));
701     WKDictionarySetItem(messageBody.get(), permissiveKeyWK.get(), permissiveWK.get());
702
703     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
704 }
705
706 void InjectedBundle::setHidden(bool hidden)
707 {
708     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetHidden"));
709     WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
710
711     WKRetainPtr<WKStringRef> isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("hidden"));
712     WKRetainPtr<WKBooleanRef> isInitialWK(AdoptWK, WKBooleanCreate(hidden));
713     WKDictionarySetItem(messageBody.get(), isInitialKeyWK.get(), isInitialWK.get());
714
715     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
716 }
717
718 void InjectedBundle::setCacheModel(int model)
719 {
720     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetCacheModel"));
721     WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(model));
722     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
723 }
724
725 bool InjectedBundle::shouldProcessWorkQueue() const
726 {
727     if (!m_useWorkQueue)
728         return false;
729
730     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsWorkQueueEmpty"));
731     WKTypeRef resultToPass = 0;
732     WKBundlePagePostSynchronousMessageForTesting(page()->page(), messageName.get(), 0, &resultToPass);
733     WKRetainPtr<WKBooleanRef> isEmpty(AdoptWK, static_cast<WKBooleanRef>(resultToPass));
734
735     return !WKBooleanGetValue(isEmpty.get());
736 }
737
738 void InjectedBundle::processWorkQueue()
739 {
740     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ProcessWorkQueue"));
741     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
742 }
743
744 void InjectedBundle::queueBackNavigation(unsigned howFarBackward)
745 {
746     m_useWorkQueue = true;
747
748     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueBackNavigation"));
749     WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(howFarBackward));
750     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
751 }
752
753 void InjectedBundle::queueForwardNavigation(unsigned howFarForward)
754 {
755     m_useWorkQueue = true;
756
757     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueForwardNavigation"));
758     WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(howFarForward));
759     WKBundlePagePostMessage(page()->page(), messageName.get(), messageBody.get());
760 }
761
762 void InjectedBundle::queueLoad(WKStringRef url, WKStringRef target, bool shouldOpenExternalURLs)
763 {
764     m_useWorkQueue = true;
765
766     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueLoad"));
767
768     WKRetainPtr<WKMutableDictionaryRef> loadData(AdoptWK, WKMutableDictionaryCreate());
769
770     WKRetainPtr<WKStringRef> urlKey(AdoptWK, WKStringCreateWithUTF8CString("url"));
771     WKDictionarySetItem(loadData.get(), urlKey.get(), url);
772
773     WKRetainPtr<WKStringRef> targetKey(AdoptWK, WKStringCreateWithUTF8CString("target"));
774     WKDictionarySetItem(loadData.get(), targetKey.get(), target);
775
776     WKRetainPtr<WKStringRef> shouldOpenExternalURLsKey(AdoptWK, WKStringCreateWithUTF8CString("shouldOpenExternalURLs"));
777     WKRetainPtr<WKBooleanRef> shouldOpenExternalURLsValue(AdoptWK, WKBooleanCreate(shouldOpenExternalURLs));
778     WKDictionarySetItem(loadData.get(), shouldOpenExternalURLsKey.get(), shouldOpenExternalURLsValue.get());
779
780     WKBundlePagePostMessage(page()->page(), messageName.get(), loadData.get());
781 }
782
783 void InjectedBundle::queueLoadHTMLString(WKStringRef content, WKStringRef baseURL, WKStringRef unreachableURL)
784 {
785     m_useWorkQueue = true;
786
787     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueLoadHTMLString"));
788
789     WKRetainPtr<WKMutableDictionaryRef> loadData(AdoptWK, WKMutableDictionaryCreate());
790
791     WKRetainPtr<WKStringRef> contentKey(AdoptWK, WKStringCreateWithUTF8CString("content"));
792     WKDictionarySetItem(loadData.get(), contentKey.get(), content);
793
794     if (baseURL) {
795         WKRetainPtr<WKStringRef> baseURLKey(AdoptWK, WKStringCreateWithUTF8CString("baseURL"));
796         WKDictionarySetItem(loadData.get(), baseURLKey.get(), baseURL);
797     }
798
799     if (unreachableURL) {
800         WKRetainPtr<WKStringRef> unreachableURLKey(AdoptWK, WKStringCreateWithUTF8CString("unreachableURL"));
801         WKDictionarySetItem(loadData.get(), unreachableURLKey.get(), unreachableURL);
802     }
803
804     WKBundlePagePostMessage(page()->page(), messageName.get(), loadData.get());
805 }
806
807 void InjectedBundle::queueReload()
808 {
809     m_useWorkQueue = true;
810
811     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueReload"));
812     WKBundlePagePostMessage(page()->page(), messageName.get(), 0);
813 }
814
815 void InjectedBundle::queueLoadingScript(WKStringRef script)
816 {
817     m_useWorkQueue = true;
818
819     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueLoadingScript"));
820     WKBundlePagePostMessage(page()->page(), messageName.get(), script);
821 }
822
823 void InjectedBundle::queueNonLoadingScript(WKStringRef script)
824 {
825     m_useWorkQueue = true;
826
827     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueNonLoadingScript"));
828     WKBundlePagePostMessage(page()->page(), messageName.get(), script);
829 }
830
831 bool InjectedBundle::isAllowedHost(WKStringRef host)
832 {
833     if (m_allowedHosts.isEmpty())
834         return false;
835     return m_allowedHosts.contains(toWTFString(host));
836 }
837
838 void InjectedBundle::setAllowsAnySSLCertificate(bool allowsAnySSLCertificate)
839 {
840     WebCoreTestSupport::setAllowsAnySSLCertificate(allowsAnySSLCertificate);
841 }
842
843 void InjectedBundle::statisticsNotifyObserver()
844 {
845     WKBundleResourceLoadStatisticsNotifyObserver(m_bundle);
846 }
847
848 } // namespace WTR