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