InjectedBundle.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. /*
  2. * Copyright (C) 2010, 2011, 2012 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. #include "config.h"
  26. #include "InjectedBundle.h"
  27. #include "ActivateFonts.h"
  28. #include "InjectedBundlePage.h"
  29. #include "StringFunctions.h"
  30. #include <WebKit2/WKBundle.h>
  31. #include <WebKit2/WKBundlePage.h>
  32. #include <WebKit2/WKBundlePagePrivate.h>
  33. #include <WebKit2/WKBundlePrivate.h>
  34. #include <WebKit2/WKRetainPtr.h>
  35. #include <WebKit2/WebKit2_C.h>
  36. #include <wtf/PassOwnPtr.h>
  37. #include <wtf/text/CString.h>
  38. #include <wtf/text/StringBuilder.h>
  39. #include <wtf/Vector.h>
  40. namespace WTR {
  41. InjectedBundle& InjectedBundle::shared()
  42. {
  43. static InjectedBundle& shared = *new InjectedBundle;
  44. return shared;
  45. }
  46. InjectedBundle::InjectedBundle()
  47. : m_bundle(0)
  48. , m_topLoadingFrame(0)
  49. , m_state(Idle)
  50. , m_dumpPixels(false)
  51. , m_useWaitToDumpWatchdogTimer(true)
  52. , m_useWorkQueue(false)
  53. , m_timeout(0)
  54. {
  55. }
  56. void InjectedBundle::didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
  57. {
  58. static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didCreatePage(page);
  59. }
  60. void InjectedBundle::willDestroyPage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
  61. {
  62. static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->willDestroyPage(page);
  63. }
  64. void InjectedBundle::didInitializePageGroup(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, const void* clientInfo)
  65. {
  66. static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didInitializePageGroup(pageGroup);
  67. }
  68. void InjectedBundle::didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
  69. {
  70. static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didReceiveMessage(messageName, messageBody);
  71. }
  72. void InjectedBundle::didReceiveMessageToPage(WKBundleRef bundle, WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
  73. {
  74. static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didReceiveMessageToPage(page, messageName, messageBody);
  75. }
  76. void InjectedBundle::initialize(WKBundleRef bundle, WKTypeRef initializationUserData)
  77. {
  78. m_bundle = bundle;
  79. WKBundleClient client = {
  80. kWKBundleClientCurrentVersion,
  81. this,
  82. didCreatePage,
  83. willDestroyPage,
  84. didInitializePageGroup,
  85. didReceiveMessage,
  86. didReceiveMessageToPage
  87. };
  88. WKBundleSetClient(m_bundle, &client);
  89. platformInitialize(initializationUserData);
  90. activateFonts();
  91. WKBundleActivateMacFontAscentHack(m_bundle);
  92. // FIXME: We'd like to start with a clean state for every test, but this function can't be used more than once yet.
  93. WKBundleSwitchNetworkLoaderToNewTestingSession(m_bundle);
  94. }
  95. void InjectedBundle::didCreatePage(WKBundlePageRef page)
  96. {
  97. m_pages.append(adoptPtr(new InjectedBundlePage(page)));
  98. }
  99. void InjectedBundle::willDestroyPage(WKBundlePageRef page)
  100. {
  101. size_t size = m_pages.size();
  102. for (size_t i = 0; i < size; ++i) {
  103. if (m_pages[i]->page() == page) {
  104. m_pages.remove(i);
  105. break;
  106. }
  107. }
  108. }
  109. void InjectedBundle::didInitializePageGroup(WKBundlePageGroupRef pageGroup)
  110. {
  111. m_pageGroup = pageGroup;
  112. }
  113. InjectedBundlePage* InjectedBundle::page() const
  114. {
  115. // It might be better to have the UI process send over a reference to the main
  116. // page instead of just assuming it's the first one.
  117. return m_pages[0].get();
  118. }
  119. void InjectedBundle::resetLocalSettings()
  120. {
  121. setlocale(LC_ALL, "");
  122. }
  123. void InjectedBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody)
  124. {
  125. if (WKStringIsEqualToUTF8CString(messageName, "BeginTest")) {
  126. ASSERT(messageBody);
  127. ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
  128. WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
  129. WKRetainPtr<WKStringRef> dumpPixelsKey(AdoptWK, WKStringCreateWithUTF8CString("DumpPixels"));
  130. m_dumpPixels = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, dumpPixelsKey.get())));
  131. WKRetainPtr<WKStringRef> useWaitToDumpWatchdogTimerKey(AdoptWK, WKStringCreateWithUTF8CString("UseWaitToDumpWatchdogTimer"));
  132. m_useWaitToDumpWatchdogTimer = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, useWaitToDumpWatchdogTimerKey.get())));
  133. WKRetainPtr<WKStringRef> timeoutKey(AdoptWK, WKStringCreateWithUTF8CString("Timeout"));
  134. m_timeout = (int)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, timeoutKey.get())));
  135. WKRetainPtr<WKStringRef> ackMessageName(AdoptWK, WKStringCreateWithUTF8CString("Ack"));
  136. WKRetainPtr<WKStringRef> ackMessageBody(AdoptWK, WKStringCreateWithUTF8CString("BeginTest"));
  137. WKBundlePostMessage(m_bundle, ackMessageName.get(), ackMessageBody.get());
  138. beginTesting(messageBodyDictionary);
  139. return;
  140. } else if (WKStringIsEqualToUTF8CString(messageName, "Reset")) {
  141. ASSERT(messageBody);
  142. ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
  143. WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
  144. WKRetainPtr<WKStringRef> shouldGCKey(AdoptWK, WKStringCreateWithUTF8CString("ShouldGC"));
  145. bool shouldGC = WKBooleanGetValue(static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, shouldGCKey.get())));
  146. if (shouldGC)
  147. WKBundleGarbageCollectJavaScriptObjects(m_bundle);
  148. m_state = Idle;
  149. m_dumpPixels = false;
  150. resetLocalSettings();
  151. m_testRunner->removeAllWebNotificationPermissions();
  152. page()->resetAfterTest();
  153. return;
  154. }
  155. if (WKStringIsEqualToUTF8CString(messageName, "CallAddChromeInputFieldCallback")) {
  156. m_testRunner->callAddChromeInputFieldCallback();
  157. return;
  158. }
  159. if (WKStringIsEqualToUTF8CString(messageName, "CallRemoveChromeInputFieldCallback")) {
  160. m_testRunner->callRemoveChromeInputFieldCallback();
  161. return;
  162. }
  163. if (WKStringIsEqualToUTF8CString(messageName, "CallFocusWebViewCallback")) {
  164. m_testRunner->callFocusWebViewCallback();
  165. return;
  166. }
  167. if (WKStringIsEqualToUTF8CString(messageName, "CallSetBackingScaleFactorCallback")) {
  168. m_testRunner->callSetBackingScaleFactorCallback();
  169. return;
  170. }
  171. if (WKStringIsEqualToUTF8CString(messageName, "WorkQueueProcessedCallback")) {
  172. if (!topLoadingFrame() && !m_testRunner->waitToDump())
  173. page()->dump();
  174. return;
  175. }
  176. WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
  177. WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
  178. WKBundlePostMessage(m_bundle, errorMessageName.get(), errorMessageBody.get());
  179. }
  180. void InjectedBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody)
  181. {
  182. WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
  183. WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
  184. WKBundlePostMessage(m_bundle, errorMessageName.get(), errorMessageBody.get());
  185. }
  186. bool InjectedBundle::booleanForKey(WKDictionaryRef dictionary, const char* key)
  187. {
  188. WKRetainPtr<WKStringRef> wkKey(AdoptWK, WKStringCreateWithUTF8CString(key));
  189. WKTypeRef value = WKDictionaryGetItemForKey(dictionary, wkKey.get());
  190. if (WKGetTypeID(value) != WKBooleanGetTypeID()) {
  191. outputText(makeString("Boolean value for key", key, " not found in dictionary\n"));
  192. return false;
  193. }
  194. return WKBooleanGetValue(static_cast<WKBooleanRef>(value));
  195. }
  196. void InjectedBundle::beginTesting(WKDictionaryRef settings)
  197. {
  198. m_state = Testing;
  199. m_pixelResult.clear();
  200. m_repaintRects.clear();
  201. m_testRunner = TestRunner::create();
  202. m_gcController = GCController::create();
  203. m_eventSendingController = EventSendingController::create();
  204. m_textInputController = TextInputController::create();
  205. m_accessibilityController = AccessibilityController::create();
  206. WKBundleSetShouldTrackVisitedLinks(m_bundle, false);
  207. WKBundleRemoveAllVisitedLinks(m_bundle);
  208. WKBundleSetAllowUniversalAccessFromFileURLs(m_bundle, m_pageGroup, true);
  209. WKBundleSetJavaScriptCanAccessClipboard(m_bundle, m_pageGroup, true);
  210. WKBundleSetPrivateBrowsingEnabled(m_bundle, m_pageGroup, false);
  211. WKBundleSetAuthorAndUserStylesEnabled(m_bundle, m_pageGroup, true);
  212. WKBundleSetFrameFlatteningEnabled(m_bundle, m_pageGroup, false);
  213. WKBundleSetMinimumLogicalFontSize(m_bundle, m_pageGroup, 9);
  214. WKBundleSetSpatialNavigationEnabled(m_bundle, m_pageGroup, false);
  215. WKBundleSetAllowFileAccessFromFileURLs(m_bundle, m_pageGroup, true);
  216. WKBundleSetPluginsEnabled(m_bundle, m_pageGroup, true);
  217. WKBundleSetPopupBlockingEnabled(m_bundle, m_pageGroup, false);
  218. WKBundleSetAlwaysAcceptCookies(m_bundle, false);
  219. WKBundleSetSerialLoadingEnabled(m_bundle, false);
  220. WKBundleSetShadowDOMEnabled(m_bundle, true);
  221. WKBundleSetSeamlessIFramesEnabled(m_bundle, true);
  222. WKBundleSetCacheModel(m_bundle, 1 /*CacheModelDocumentBrowser*/);
  223. WKBundleRemoveAllUserContent(m_bundle, m_pageGroup);
  224. m_testRunner->setShouldDumpFrameLoadCallbacks(booleanForKey(settings, "DumpFrameLoadDelegates"));
  225. m_testRunner->setUserStyleSheetEnabled(false);
  226. m_testRunner->setXSSAuditorEnabled(false);
  227. m_testRunner->setCloseRemainingWindowsWhenComplete(false);
  228. m_testRunner->setAcceptsEditing(true);
  229. m_testRunner->setTabKeyCyclesThroughElements(true);
  230. m_testRunner->setCustomTimeout(m_timeout);
  231. page()->prepare();
  232. WKBundleClearAllDatabases(m_bundle);
  233. WKBundleClearApplicationCache(m_bundle);
  234. WKBundleResetOriginAccessWhitelists(m_bundle);
  235. // [WK2] REGRESSION(r128623): It made layout tests extremely slow
  236. // https://bugs.webkit.org/show_bug.cgi?id=96862
  237. // WKBundleSetDatabaseQuota(m_bundle, 5 * 1024 * 1024);
  238. }
  239. void InjectedBundle::done()
  240. {
  241. m_state = Stopping;
  242. m_useWorkQueue = false;
  243. page()->stopLoading();
  244. setTopLoadingFrame(0);
  245. m_accessibilityController->resetToConsistentState();
  246. WKRetainPtr<WKStringRef> doneMessageName(AdoptWK, WKStringCreateWithUTF8CString("Done"));
  247. WKRetainPtr<WKMutableDictionaryRef> doneMessageBody(AdoptWK, WKMutableDictionaryCreate());
  248. WKRetainPtr<WKStringRef> pixelResultKey = adoptWK(WKStringCreateWithUTF8CString("PixelResult"));
  249. WKDictionaryAddItem(doneMessageBody.get(), pixelResultKey.get(), m_pixelResult.get());
  250. WKRetainPtr<WKStringRef> repaintRectsKey = adoptWK(WKStringCreateWithUTF8CString("RepaintRects"));
  251. WKDictionaryAddItem(doneMessageBody.get(), repaintRectsKey.get(), m_repaintRects.get());
  252. WKRetainPtr<WKStringRef> audioResultKey = adoptWK(WKStringCreateWithUTF8CString("AudioResult"));
  253. WKDictionaryAddItem(doneMessageBody.get(), audioResultKey.get(), m_audioResult.get());
  254. WKBundlePostMessage(m_bundle, doneMessageName.get(), doneMessageBody.get());
  255. closeOtherPages();
  256. m_state = Idle;
  257. }
  258. void InjectedBundle::closeOtherPages()
  259. {
  260. Vector<WKBundlePageRef> pagesToClose;
  261. size_t size = m_pages.size();
  262. for (size_t i = 1; i < size; ++i)
  263. pagesToClose.append(m_pages[i]->page());
  264. size = pagesToClose.size();
  265. for (size_t i = 0; i < size; ++i)
  266. WKBundlePageClose(pagesToClose[i]);
  267. }
  268. void InjectedBundle::dumpBackForwardListsForAllPages(StringBuilder& stringBuilder)
  269. {
  270. size_t size = m_pages.size();
  271. for (size_t i = 0; i < size; ++i)
  272. m_pages[i]->dumpBackForwardList(stringBuilder);
  273. }
  274. void InjectedBundle::outputText(const String& output)
  275. {
  276. if (m_state != Testing)
  277. return;
  278. if (output.isEmpty())
  279. return;
  280. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("TextOutput"));
  281. WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithUTF8CString(output.utf8().data()));
  282. WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
  283. }
  284. void InjectedBundle::postNewBeforeUnloadReturnValue(bool value)
  285. {
  286. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("BeforeUnloadReturnValue"));
  287. WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
  288. WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
  289. }
  290. void InjectedBundle::postAddChromeInputField()
  291. {
  292. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("AddChromeInputField"));
  293. WKBundlePostMessage(m_bundle, messageName.get(), 0);
  294. }
  295. void InjectedBundle::postRemoveChromeInputField()
  296. {
  297. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("RemoveChromeInputField"));
  298. WKBundlePostMessage(m_bundle, messageName.get(), 0);
  299. }
  300. void InjectedBundle::postFocusWebView()
  301. {
  302. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("FocusWebView"));
  303. WKBundlePostMessage(m_bundle, messageName.get(), 0);
  304. }
  305. void InjectedBundle::postSetBackingScaleFactor(double backingScaleFactor)
  306. {
  307. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetBackingScaleFactor"));
  308. WKRetainPtr<WKDoubleRef> messageBody(AdoptWK, WKDoubleCreate(backingScaleFactor));
  309. WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
  310. }
  311. void InjectedBundle::postSetWindowIsKey(bool isKey)
  312. {
  313. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetWindowIsKey"));
  314. WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(isKey));
  315. WKBundlePostSynchronousMessage(m_bundle, messageName.get(), messageBody.get(), 0);
  316. }
  317. void InjectedBundle::postSimulateWebNotificationClick(uint64_t notificationID)
  318. {
  319. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SimulateWebNotificationClick"));
  320. WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(notificationID));
  321. WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
  322. }
  323. void InjectedBundle::setGeolocationPermission(bool enabled)
  324. {
  325. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetGeolocationPermission"));
  326. WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(enabled));
  327. WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
  328. }
  329. 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)
  330. {
  331. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGeolocationPosition"));
  332. WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
  333. WKRetainPtr<WKStringRef> latitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("latitude"));
  334. WKRetainPtr<WKDoubleRef> latitudeWK(AdoptWK, WKDoubleCreate(latitude));
  335. WKDictionaryAddItem(messageBody.get(), latitudeKeyWK.get(), latitudeWK.get());
  336. WKRetainPtr<WKStringRef> longitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("longitude"));
  337. WKRetainPtr<WKDoubleRef> longitudeWK(AdoptWK, WKDoubleCreate(longitude));
  338. WKDictionaryAddItem(messageBody.get(), longitudeKeyWK.get(), longitudeWK.get());
  339. WKRetainPtr<WKStringRef> accuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("accuracy"));
  340. WKRetainPtr<WKDoubleRef> accuracyWK(AdoptWK, WKDoubleCreate(accuracy));
  341. WKDictionaryAddItem(messageBody.get(), accuracyKeyWK.get(), accuracyWK.get());
  342. WKRetainPtr<WKStringRef> providesAltitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesAltitude"));
  343. WKRetainPtr<WKBooleanRef> providesAltitudeWK(AdoptWK, WKBooleanCreate(providesAltitude));
  344. WKDictionaryAddItem(messageBody.get(), providesAltitudeKeyWK.get(), providesAltitudeWK.get());
  345. WKRetainPtr<WKStringRef> altitudeKeyWK(AdoptWK, WKStringCreateWithUTF8CString("altitude"));
  346. WKRetainPtr<WKDoubleRef> altitudeWK(AdoptWK, WKDoubleCreate(altitude));
  347. WKDictionaryAddItem(messageBody.get(), altitudeKeyWK.get(), altitudeWK.get());
  348. WKRetainPtr<WKStringRef> providesAltitudeAccuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesAltitudeAccuracy"));
  349. WKRetainPtr<WKBooleanRef> providesAltitudeAccuracyWK(AdoptWK, WKBooleanCreate(providesAltitudeAccuracy));
  350. WKDictionaryAddItem(messageBody.get(), providesAltitudeAccuracyKeyWK.get(), providesAltitudeAccuracyWK.get());
  351. WKRetainPtr<WKStringRef> altitudeAccuracyKeyWK(AdoptWK, WKStringCreateWithUTF8CString("altitudeAccuracy"));
  352. WKRetainPtr<WKDoubleRef> altitudeAccuracyWK(AdoptWK, WKDoubleCreate(altitudeAccuracy));
  353. WKDictionaryAddItem(messageBody.get(), altitudeAccuracyKeyWK.get(), altitudeAccuracyWK.get());
  354. WKRetainPtr<WKStringRef> providesHeadingKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesHeading"));
  355. WKRetainPtr<WKBooleanRef> providesHeadingWK(AdoptWK, WKBooleanCreate(providesHeading));
  356. WKDictionaryAddItem(messageBody.get(), providesHeadingKeyWK.get(), providesHeadingWK.get());
  357. WKRetainPtr<WKStringRef> headingKeyWK(AdoptWK, WKStringCreateWithUTF8CString("heading"));
  358. WKRetainPtr<WKDoubleRef> headingWK(AdoptWK, WKDoubleCreate(heading));
  359. WKDictionaryAddItem(messageBody.get(), headingKeyWK.get(), headingWK.get());
  360. WKRetainPtr<WKStringRef> providesSpeedKeyWK(AdoptWK, WKStringCreateWithUTF8CString("providesSpeed"));
  361. WKRetainPtr<WKBooleanRef> providesSpeedWK(AdoptWK, WKBooleanCreate(providesSpeed));
  362. WKDictionaryAddItem(messageBody.get(), providesSpeedKeyWK.get(), providesSpeedWK.get());
  363. WKRetainPtr<WKStringRef> speedKeyWK(AdoptWK, WKStringCreateWithUTF8CString("speed"));
  364. WKRetainPtr<WKDoubleRef> speedWK(AdoptWK, WKDoubleCreate(speed));
  365. WKDictionaryAddItem(messageBody.get(), speedKeyWK.get(), speedWK.get());
  366. WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
  367. }
  368. void InjectedBundle::setMockGeolocationPositionUnavailableError(WKStringRef errorMessage)
  369. {
  370. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetMockGeolocationPositionUnavailableError"));
  371. WKBundlePostMessage(m_bundle, messageName.get(), errorMessage);
  372. }
  373. void InjectedBundle::setCustomPolicyDelegate(bool enabled, bool permissive)
  374. {
  375. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetCustomPolicyDelegate"));
  376. WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
  377. WKRetainPtr<WKStringRef> enabledKeyWK(AdoptWK, WKStringCreateWithUTF8CString("enabled"));
  378. WKRetainPtr<WKBooleanRef> enabledWK(AdoptWK, WKBooleanCreate(enabled));
  379. WKDictionaryAddItem(messageBody.get(), enabledKeyWK.get(), enabledWK.get());
  380. WKRetainPtr<WKStringRef> permissiveKeyWK(AdoptWK, WKStringCreateWithUTF8CString("permissive"));
  381. WKRetainPtr<WKBooleanRef> permissiveWK(AdoptWK, WKBooleanCreate(permissive));
  382. WKDictionaryAddItem(messageBody.get(), permissiveKeyWK.get(), permissiveWK.get());
  383. WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
  384. }
  385. void InjectedBundle::setVisibilityState(WKPageVisibilityState visibilityState, bool isInitialState)
  386. {
  387. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetVisibilityState"));
  388. WKRetainPtr<WKMutableDictionaryRef> messageBody(AdoptWK, WKMutableDictionaryCreate());
  389. WKRetainPtr<WKStringRef> visibilityStateKeyWK(AdoptWK, WKStringCreateWithUTF8CString("visibilityState"));
  390. WKRetainPtr<WKUInt64Ref> visibilityStateWK(AdoptWK, WKUInt64Create(visibilityState));
  391. WKDictionaryAddItem(messageBody.get(), visibilityStateKeyWK.get(), visibilityStateWK.get());
  392. WKRetainPtr<WKStringRef> isInitialKeyWK(AdoptWK, WKStringCreateWithUTF8CString("isInitialState"));
  393. WKRetainPtr<WKBooleanRef> isInitialWK(AdoptWK, WKBooleanCreate(isInitialState));
  394. WKDictionaryAddItem(messageBody.get(), isInitialKeyWK.get(), isInitialWK.get());
  395. WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
  396. }
  397. bool InjectedBundle::shouldProcessWorkQueue() const
  398. {
  399. if (!m_useWorkQueue)
  400. return false;
  401. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsWorkQueueEmpty"));
  402. WKTypeRef resultToPass = 0;
  403. WKBundlePostSynchronousMessage(m_bundle, messageName.get(), 0, &resultToPass);
  404. WKRetainPtr<WKBooleanRef> isEmpty(AdoptWK, static_cast<WKBooleanRef>(resultToPass));
  405. return !WKBooleanGetValue(isEmpty.get());
  406. }
  407. void InjectedBundle::processWorkQueue()
  408. {
  409. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("ProcessWorkQueue"));
  410. WKBundlePostMessage(m_bundle, messageName.get(), 0);
  411. }
  412. void InjectedBundle::queueBackNavigation(unsigned howFarBackward)
  413. {
  414. m_useWorkQueue = true;
  415. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueBackNavigation"));
  416. WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(howFarBackward));
  417. WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
  418. }
  419. void InjectedBundle::queueForwardNavigation(unsigned howFarForward)
  420. {
  421. m_useWorkQueue = true;
  422. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueForwardNavigation"));
  423. WKRetainPtr<WKUInt64Ref> messageBody(AdoptWK, WKUInt64Create(howFarForward));
  424. WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
  425. }
  426. void InjectedBundle::queueLoad(WKStringRef url, WKStringRef target)
  427. {
  428. m_useWorkQueue = true;
  429. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueLoad"));
  430. WKRetainPtr<WKMutableDictionaryRef> loadData(AdoptWK, WKMutableDictionaryCreate());
  431. WKRetainPtr<WKStringRef> urlKey(AdoptWK, WKStringCreateWithUTF8CString("url"));
  432. WKDictionaryAddItem(loadData.get(), urlKey.get(), url);
  433. WKRetainPtr<WKStringRef> targetKey(AdoptWK, WKStringCreateWithUTF8CString("target"));
  434. WKDictionaryAddItem(loadData.get(), targetKey.get(), target);
  435. WKBundlePostMessage(m_bundle, messageName.get(), loadData.get());
  436. }
  437. void InjectedBundle::queueLoadHTMLString(WKStringRef content, WKStringRef baseURL, WKStringRef unreachableURL)
  438. {
  439. m_useWorkQueue = true;
  440. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueLoadHTMLString"));
  441. WKRetainPtr<WKMutableDictionaryRef> loadData(AdoptWK, WKMutableDictionaryCreate());
  442. WKRetainPtr<WKStringRef> contentKey(AdoptWK, WKStringCreateWithUTF8CString("content"));
  443. WKDictionaryAddItem(loadData.get(), contentKey.get(), content);
  444. if (baseURL) {
  445. WKRetainPtr<WKStringRef> baseURLKey(AdoptWK, WKStringCreateWithUTF8CString("baseURL"));
  446. WKDictionaryAddItem(loadData.get(), baseURLKey.get(), baseURL);
  447. }
  448. if (unreachableURL) {
  449. WKRetainPtr<WKStringRef> unreachableURLKey(AdoptWK, WKStringCreateWithUTF8CString("unreachableURL"));
  450. WKDictionaryAddItem(loadData.get(), unreachableURLKey.get(), unreachableURL);
  451. }
  452. WKBundlePostMessage(m_bundle, messageName.get(), loadData.get());
  453. }
  454. void InjectedBundle::queueReload()
  455. {
  456. m_useWorkQueue = true;
  457. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueReload"));
  458. WKBundlePostMessage(m_bundle, messageName.get(), 0);
  459. }
  460. void InjectedBundle::queueLoadingScript(WKStringRef script)
  461. {
  462. m_useWorkQueue = true;
  463. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueLoadingScript"));
  464. WKBundlePostMessage(m_bundle, messageName.get(), script);
  465. }
  466. void InjectedBundle::queueNonLoadingScript(WKStringRef script)
  467. {
  468. m_useWorkQueue = true;
  469. WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("QueueNonLoadingScript"));
  470. WKBundlePostMessage(m_bundle, messageName.get(), script);
  471. }
  472. } // namespace WTR