View state change callbacks are sometimes dropped on the floor
[WebKit-https.git] / Source / WebKit2 / UIProcess / WebPageProxy.cpp
1 /*
2  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
3  * Copyright (C) 2012 Intel Corporation. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "WebPageProxy.h"
29
30 #include "APIArray.h"
31 #include "APIFindClient.h"
32 #include "APIFormClient.h"
33 #include "APIGeometry.h"
34 #include "APILegacyContextHistoryClient.h"
35 #include "APILoaderClient.h"
36 #include "APIPolicyClient.h"
37 #include "APISecurityOrigin.h"
38 #include "APIUIClient.h"
39 #include "APIURLRequest.h"
40 #include "AuthenticationChallengeProxy.h"
41 #include "AuthenticationDecisionListener.h"
42 #include "DataReference.h"
43 #include "DownloadProxy.h"
44 #include "DrawingAreaProxy.h"
45 #include "DrawingAreaProxyMessages.h"
46 #include "EventDispatcherMessages.h"
47 #include "Logging.h"
48 #include "NativeWebKeyboardEvent.h"
49 #include "NativeWebMouseEvent.h"
50 #include "NativeWebWheelEvent.h"
51 #include "NavigationActionData.h"
52 #include "NotificationPermissionRequest.h"
53 #include "NotificationPermissionRequestManager.h"
54 #include "PageClient.h"
55 #include "PluginInformation.h"
56 #include "PluginProcessManager.h"
57 #include "PrintInfo.h"
58 #include "TextChecker.h"
59 #include "TextCheckerState.h"
60 #include "UserMediaPermissionRequestProxy.h"
61 #include "WKContextPrivate.h"
62 #include "WebBackForwardList.h"
63 #include "WebBackForwardListItem.h"
64 #include "WebCertificateInfo.h"
65 #include "WebContextMenuProxy.h"
66 #include "WebCoreArgumentCoders.h"
67 #include "WebEditCommandProxy.h"
68 #include "WebEvent.h"
69 #include "WebEventConversion.h"
70 #include "WebFormSubmissionListenerProxy.h"
71 #include "WebFramePolicyListenerProxy.h"
72 #include "WebFullScreenManagerProxy.h"
73 #include "WebFullScreenManagerProxyMessages.h"
74 #include "WebImage.h"
75 #include "WebInspectorProxy.h"
76 #include "WebInspectorProxyMessages.h"
77 #include "WebNotificationManagerProxy.h"
78 #include "WebOpenPanelParameters.h"
79 #include "WebOpenPanelResultListenerProxy.h"
80 #include "WebPageCreationParameters.h"
81 #include "WebPageGroup.h"
82 #include "WebPageGroupData.h"
83 #include "WebPageMessages.h"
84 #include "WebPageProxyMessages.h"
85 #include "WebPopupItem.h"
86 #include "WebPopupMenuProxy.h"
87 #include "WebPreferences.h"
88 #include "WebProcessMessages.h"
89 #include "WebProcessPool.h"
90 #include "WebProcessProxy.h"
91 #include "WebProtectionSpace.h"
92 #include "WebUserContentControllerProxy.h"
93 #include "WebsiteDataStore.h"
94 #include <WebCore/DragController.h>
95 #include <WebCore/DragData.h>
96 #include <WebCore/FloatRect.h>
97 #include <WebCore/FocusDirection.h>
98 #include <WebCore/MIMETypeRegistry.h>
99 #include <WebCore/RenderEmbeddedObject.h>
100 #include <WebCore/SerializedCryptoKeyWrap.h>
101 #include <WebCore/TextCheckerClient.h>
102 #include <WebCore/TextIndicator.h>
103 #include <WebCore/WindowFeatures.h>
104 #include <stdio.h>
105 #include <wtf/NeverDestroyed.h>
106 #include <wtf/text/StringView.h>
107
108 #if ENABLE(ASYNC_SCROLLING)
109 #include "RemoteScrollingCoordinatorProxy.h"
110 #endif
111
112 #if USE(COORDINATED_GRAPHICS)
113 #include "CoordinatedLayerTreeHostProxyMessages.h"
114 #endif
115
116 #if ENABLE(VIBRATION)
117 #include "WebVibrationProxy.h"
118 #endif
119
120 #ifndef NDEBUG
121 #include <wtf/RefCountedLeakCounter.h>
122 #endif
123
124 #if ENABLE(NETWORK_PROCESS)
125 #include "NetworkProcessMessages.h"
126 #endif
127
128 #if PLATFORM(COCOA)
129 #include "ViewSnapshotStore.h"
130 #include <WebCore/RunLoopObserver.h>
131 #endif
132
133 #if PLATFORM(IOS)
134 #include "RemoteLayerTreeDrawingAreaProxy.h"
135 #include "WebVideoFullscreenManagerProxy.h"
136 #include "WebVideoFullscreenManagerProxyMessages.h"
137 #endif
138
139 #if USE(CAIRO)
140 #include <WebCore/CairoUtilities.h>
141 #endif
142
143 // This controls what strategy we use for mouse wheel coalescing.
144 #define MERGE_WHEEL_EVENTS 1
145
146 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
147 #define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
148
149 using namespace WebCore;
150
151 // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively.
152 static const unsigned wheelEventQueueSizeThreshold = 10;
153
154 namespace WebKit {
155
156 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
157
158 class ExceededDatabaseQuotaRecords {
159     WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
160     friend class NeverDestroyed<ExceededDatabaseQuotaRecords>;
161 public:
162     struct Record {
163         uint64_t frameID;
164         String originIdentifier;
165         String databaseName;
166         String displayName;
167         uint64_t currentQuota;
168         uint64_t currentOriginUsage;
169         uint64_t currentDatabaseUsage;
170         uint64_t expectedUsage;
171         RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
172     };
173
174     static ExceededDatabaseQuotaRecords& shared();
175
176     std::unique_ptr<Record> createRecord(uint64_t frameID, String originIdentifier,
177         String databaseName, String displayName, uint64_t currentQuota,
178         uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, 
179         PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>);
180
181     void add(std::unique_ptr<Record>);
182     bool areBeingProcessed() const { return !!m_currentRecord; }
183     Record* next();
184
185 private:
186     ExceededDatabaseQuotaRecords() { }
187     ~ExceededDatabaseQuotaRecords() { }
188
189     Deque<std::unique_ptr<Record>> m_records;
190     std::unique_ptr<Record> m_currentRecord;
191 };
192
193 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::shared()
194 {
195     static NeverDestroyed<ExceededDatabaseQuotaRecords> records;
196     return records;
197 }
198
199 std::unique_ptr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
200     uint64_t frameID, String originIdentifier, String databaseName, String displayName,
201     uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
202     uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
203 {
204     auto record = std::make_unique<Record>();
205     record->frameID = frameID;
206     record->originIdentifier = originIdentifier;
207     record->databaseName = databaseName;
208     record->displayName = displayName;
209     record->currentQuota = currentQuota;
210     record->currentOriginUsage = currentOriginUsage;
211     record->currentDatabaseUsage = currentDatabaseUsage;
212     record->expectedUsage = expectedUsage;
213     record->reply = reply;
214     return WTF::move(record);
215 }
216
217 void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record)
218 {
219     m_records.append(WTF::move(record));
220 }
221
222 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
223 {
224     m_currentRecord = nullptr;
225     if (!m_records.isEmpty())
226         m_currentRecord = m_records.takeFirst();
227     return m_currentRecord.get();
228 }
229
230 #if !LOG_DISABLED
231 static const char* webKeyboardEventTypeString(WebEvent::Type type)
232 {
233     switch (type) {
234     case WebEvent::KeyDown:
235         return "KeyDown";
236     
237     case WebEvent::KeyUp:
238         return "KeyUp";
239     
240     case WebEvent::RawKeyDown:
241         return "RawKeyDown";
242     
243     case WebEvent::Char:
244         return "Char";
245     
246     default:
247         ASSERT_NOT_REACHED();
248         return "<unknown>";
249     }
250 }
251 #endif // !LOG_DISABLED
252
253 Ref<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
254 {
255     return adoptRef(*new WebPageProxy(pageClient, process, pageID, configuration));
256 }
257
258 WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration)
259     : m_pageClient(pageClient)
260     , m_loaderClient(std::make_unique<API::LoaderClient>())
261     , m_policyClient(std::make_unique<API::PolicyClient>())
262     , m_formClient(std::make_unique<API::FormClient>())
263     , m_uiClient(std::make_unique<API::UIClient>())
264     , m_findClient(std::make_unique<API::FindClient>())
265     , m_process(process)
266     , m_pageGroup(*configuration.pageGroup)
267     , m_preferences(*configuration.preferences)
268     , m_userContentController(configuration.userContentController)
269     , m_visitedLinkProvider(*configuration.visitedLinkProvider)
270     , m_websiteDataStore(*configuration.websiteDataStore)
271     , m_mainFrame(nullptr)
272     , m_userAgent(standardUserAgent())
273 #if PLATFORM(IOS)
274     , m_hasReceivedLayerTreeTransactionAfterDidCommitLoad(true)
275     , m_firstLayerTreeTransactionIdAfterDidCommitLoad(0)
276     , m_deviceOrientation(0)
277     , m_dynamicViewportSizeUpdateWaitingForTarget(false)
278     , m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit(false)
279     , m_dynamicViewportSizeUpdateLayerTreeTransactionID(0)
280 #endif
281     , m_geolocationPermissionRequestManager(*this)
282     , m_notificationPermissionRequestManager(*this)
283     , m_userMediaPermissionRequestManager(*this)
284     , m_viewState(ViewState::NoFlags)
285     , m_viewWasEverInWindow(false)
286     , m_backForwardList(WebBackForwardList::create(*this))
287     , m_maintainsInactiveSelection(false)
288 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
289     , m_temporarilyClosedComposition(false)
290 #endif
291     , m_textZoomFactor(1)
292     , m_pageZoomFactor(1)
293     , m_pageScaleFactor(1)
294     , m_intrinsicDeviceScaleFactor(1)
295     , m_customDeviceScaleFactor(0)
296     , m_topContentInset(0)
297     , m_layerHostingMode(LayerHostingMode::InProcess)
298     , m_drawsBackground(true)
299     , m_drawsTransparentBackground(false)
300     , m_useFixedLayout(false)
301     , m_suppressScrollbarAnimations(false)
302     , m_paginationMode(Pagination::Unpaginated)
303     , m_paginationBehavesLikeColumns(false)
304     , m_pageLength(0)
305     , m_gapBetweenPages(0)
306     , m_isValid(true)
307     , m_isClosed(false)
308     , m_canRunModal(false)
309     , m_isInPrintingMode(false)
310     , m_isPerformingDOMPrintOperation(false)
311     , m_inDecidePolicyForResponseSync(false)
312     , m_decidePolicyForResponseRequest(0)
313     , m_syncMimeTypePolicyActionIsValid(false)
314     , m_syncMimeTypePolicyAction(PolicyUse)
315     , m_syncMimeTypePolicyDownloadID(0)
316     , m_inDecidePolicyForNavigationAction(false)
317     , m_syncNavigationActionPolicyActionIsValid(false)
318     , m_syncNavigationActionPolicyAction(PolicyUse)
319     , m_syncNavigationActionPolicyDownloadID(0)
320     , m_processingMouseMoveEvent(false)
321 #if ENABLE(TOUCH_EVENTS)
322     , m_isTrackingTouchEvents(false)
323 #endif
324     , m_pageID(pageID)
325     , m_sessionID(configuration.sessionID)
326     , m_isPageSuspended(false)
327     , m_addsVisitedLinks(true)
328 #if ENABLE(REMOTE_INSPECTOR)
329     , m_allowsRemoteInspection(true)
330 #endif
331 #if PLATFORM(COCOA)
332     , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
333 #endif
334     , m_spellDocumentTag(0)
335     , m_hasSpellDocumentTag(false)
336     , m_pendingLearnOrIgnoreWordMessageCount(0)
337     , m_mainFrameHasCustomContentProvider(false)
338 #if ENABLE(DRAG_SUPPORT)
339     , m_currentDragOperation(DragOperationNone)
340     , m_currentDragIsOverFileInput(false)
341     , m_currentDragNumberOfFilesToBeAccepted(0)
342 #endif
343     , m_pageLoadState(*this)
344     , m_delegatesScrolling(false)
345     , m_mainFrameHasHorizontalScrollbar(false)
346     , m_mainFrameHasVerticalScrollbar(false)
347     , m_canShortCircuitHorizontalWheelEvents(true)
348     , m_mainFrameIsPinnedToLeftSide(true)
349     , m_mainFrameIsPinnedToRightSide(true)
350     , m_mainFrameIsPinnedToTopSide(true)
351     , m_mainFrameIsPinnedToBottomSide(true)
352     , m_shouldUseImplicitRubberBandControl(false)
353     , m_rubberBandsAtLeft(true)
354     , m_rubberBandsAtRight(true)
355     , m_rubberBandsAtTop(true)
356     , m_rubberBandsAtBottom(true)
357     , m_enableVerticalRubberBanding(true)
358     , m_enableHorizontalRubberBanding(true)
359     , m_backgroundExtendsBeyondPage(false)
360     , m_shouldRecordNavigationSnapshots(false)
361     , m_isShowingNavigationGestureSnapshot(false)
362     , m_pageCount(0)
363     , m_renderTreeSize(0)
364     , m_sessionRestorationRenderTreeSize(0)
365     , m_wantsSessionRestorationRenderTreeSizeThresholdEvent(false)
366     , m_hitRenderTreeSizeThreshold(false)
367     , m_shouldSendEventsSynchronously(false)
368     , m_suppressVisibilityUpdates(false)
369     , m_autoSizingShouldExpandToViewHeight(false)
370     , m_mediaVolume(1)
371     , m_muted(false)
372     , m_mayStartMediaWhenInWindow(true)
373     , m_scrollPinningBehavior(DoNotPin)
374     , m_navigationID(0)
375     , m_configurationPreferenceValues(configuration.preferenceValues)
376     , m_potentiallyChangedViewStateFlags(ViewState::NoFlags)
377     , m_viewStateChangeWantsSynchronousReply(false)
378     , m_isPlayingAudio(false)
379 {
380     m_websiteDataStore->addWebPage(*this);
381
382     if (m_process->state() == WebProcessProxy::State::Running) {
383         if (m_userContentController)
384             m_process->addWebUserContentControllerProxy(*m_userContentController);
385         m_process->addVisitedLinkProvider(m_visitedLinkProvider);
386     }
387
388     updateViewState();
389     updateActivityToken();
390     updateProccessSuppressionState();
391     
392 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
393     m_layerHostingMode = m_viewState & ViewState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess;
394 #endif
395
396     platformInitialize();
397
398 #ifndef NDEBUG
399     webPageProxyCounter.increment();
400 #endif
401
402     WebProcessPool::statistics().wkPageCount++;
403
404     m_preferences->addPage(*this);
405     m_pageGroup->addPage(this);
406
407 #if ENABLE(INSPECTOR)
408     m_inspector = WebInspectorProxy::create(this);
409 #endif
410 #if ENABLE(FULLSCREEN_API)
411     m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
412 #endif
413 #if PLATFORM(IOS) && (__IPHONE_OS_VERSION_MIN_REQUIRED > 80200)
414     m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
415 #endif
416 #if ENABLE(VIBRATION)
417     m_vibration = WebVibrationProxy::create(this);
418 #endif
419
420     m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
421
422     // FIXME: If we ever expose the session storage size as a preference, we need to pass it here.
423     IPC::Connection* connection = m_process->state() == WebProcessProxy::State::Running ? m_process->connection() : nullptr;
424     m_process->processPool().storageManager().createSessionStorageNamespace(m_pageID, connection, std::numeric_limits<unsigned>::max());
425     setSessionID(configuration.sessionID);
426
427 #if PLATFORM(COCOA)
428     const CFIndex viewStateChangeRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit - 1;
429     m_viewStateChangeDispatcher = RunLoopObserver::create(viewStateChangeRunLoopOrder, [this] {
430         this->dispatchViewStateChange();
431     });
432 #endif
433 }
434
435 WebPageProxy::~WebPageProxy()
436 {
437     ASSERT(m_process->webPage(m_pageID) != this);
438 #if !ASSERT_DISABLED
439     for (WebPageProxy* page : m_process->pages())
440         ASSERT(page != this);
441 #endif
442
443     if (!m_isClosed)
444         close();
445
446     WebProcessPool::statistics().wkPageCount--;
447
448     if (m_hasSpellDocumentTag)
449         TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
450
451     m_preferences->removePage(*this);
452     m_pageGroup->removePage(this);
453
454 #ifndef NDEBUG
455     webPageProxyCounter.decrement();
456 #endif
457 }
458
459 PlatformProcessIdentifier WebPageProxy::processIdentifier() const
460 {
461     if (m_isClosed)
462         return 0;
463
464     return m_process->processIdentifier();
465 }
466
467 bool WebPageProxy::isValid() const
468 {
469     // A page that has been explicitly closed is never valid.
470     if (m_isClosed)
471         return false;
472
473     return m_isValid;
474 }
475
476 void WebPageProxy::setPreferences(WebPreferences& preferences)
477 {
478     if (&preferences == m_preferences.ptr())
479         return;
480
481     m_preferences->removePage(*this);
482     m_preferences = preferences;
483     m_preferences->addPage(*this);
484
485     preferencesDidChange();
486 }
487
488 void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClient)
489 {
490     if (!loaderClient) {
491         m_loaderClient = std::make_unique<API::LoaderClient>();
492         return;
493     }
494
495     m_loaderClient = WTF::move(loaderClient);
496 }
497
498 void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClient)
499 {
500     if (!policyClient) {
501         m_policyClient = std::make_unique<API::PolicyClient>();
502         return;
503     }
504
505     m_policyClient = WTF::move(policyClient);
506 }
507
508 void WebPageProxy::setFormClient(std::unique_ptr<API::FormClient> formClient)
509 {
510     if (!formClient) {
511         m_formClient = std::make_unique<API::FormClient>();
512         return;
513     }
514
515     m_formClient = WTF::move(formClient);
516 }
517
518 void WebPageProxy::setUIClient(std::unique_ptr<API::UIClient> uiClient)
519 {
520     if (!uiClient) {
521         m_uiClient = std::make_unique<API::UIClient>();
522         return;
523     }
524
525     m_uiClient = WTF::move(uiClient);
526
527     if (!isValid())
528         return;
529
530     m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient->canRunBeforeUnloadConfirmPanel()), m_pageID);
531     setCanRunModal(m_uiClient->canRunModal());
532 }
533
534 void WebPageProxy::setFindClient(std::unique_ptr<API::FindClient> findClient)
535 {
536     if (!findClient) {
537         m_findClient = std::make_unique<API::FindClient>();
538         return;
539     }
540     
541     m_findClient = WTF::move(findClient);
542 }
543
544 void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClientBase* client)
545 {
546     m_findMatchesClient.initialize(client);
547 }
548
549 #if ENABLE(CONTEXT_MENUS)
550 void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClientBase* client)
551 {
552     m_contextMenuClient.initialize(client);
553 }
554 #endif
555
556 void WebPageProxy::reattachToWebProcess()
557 {
558     ASSERT(!m_isClosed);
559     ASSERT(!isValid());
560     ASSERT(m_process->state() == WebProcessProxy::State::Terminated);
561
562     m_isValid = true;
563     m_process->removeWebPage(m_pageID);
564     m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
565
566     if (m_process->processPool().processModel() == ProcessModelSharedSecondaryProcess)
567         m_process = m_process->processPool().ensureSharedWebProcess();
568     else
569         m_process = m_process->processPool().createNewWebProcessRespectingProcessCountLimit();
570
571     ASSERT(m_process->state() != ChildProcessProxy::State::Terminated);
572     if (m_process->state() == ChildProcessProxy::State::Running)
573         processDidFinishLaunching();
574     m_process->addExistingWebPage(this, m_pageID);
575     m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this);
576
577     updateViewState();
578     updateActivityToken();
579
580 #if ENABLE(INSPECTOR)
581     m_inspector = WebInspectorProxy::create(this);
582 #endif
583 #if ENABLE(FULLSCREEN_API)
584     m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient());
585 #endif
586 #if PLATFORM(IOS) && (__IPHONE_OS_VERSION_MIN_REQUIRED > 80200)
587     m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this);
588 #endif
589
590     initializeWebPage();
591
592     m_pageClient.didRelaunchProcess();
593     m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
594 }
595
596 uint64_t WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
597 {
598     if (m_isClosed)
599         return 0;
600
601     if (item && item != m_backForwardList->currentItem())
602         m_backForwardList->goToItem(item);
603
604     ASSERT(!isValid());
605     reattachToWebProcess();
606
607     if (!item)
608         return 0;
609
610     uint64_t navigationID = generateNavigationID();
611
612     m_process->send(Messages::WebPage::GoToBackForwardItem(navigationID, item->itemID()), m_pageID);
613     m_process->responsivenessTimer()->start();
614
615     return navigationID;
616 }
617
618 void WebPageProxy::setSessionID(SessionID sessionID)
619 {
620     m_sessionID = sessionID;
621     m_process->send(Messages::WebPage::SetSessionID(sessionID), m_pageID);
622
623 #if ENABLE(NETWORK_PROCESS)
624     if (sessionID.isEphemeral())
625         m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(sessionID));
626 #endif
627 }
628
629 void WebPageProxy::initializeWebPage()
630 {
631     ASSERT(isValid());
632
633     BackForwardListItemVector items = m_backForwardList->entries();
634     for (size_t i = 0; i < items.size(); ++i)
635         m_process->registerNewWebBackForwardListItem(items[i].get());
636
637     m_drawingArea = m_pageClient.createDrawingAreaProxy();
638     ASSERT(m_drawingArea);
639
640 #if ENABLE(ASYNC_SCROLLING)
641     if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) {
642         m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this);
643 #if PLATFORM(IOS)
644         // On iOS, main frame scrolls are sent in terms of visible rect updates.
645         m_scrollingCoordinatorProxy->setPropagatesMainFrameScrolls(false);
646 #endif
647     }
648 #endif
649
650 #if ENABLE(INSPECTOR_SERVER)
651     if (m_preferences->developerExtrasEnabled())
652         inspector()->enableRemoteInspection();
653 #endif
654
655     process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
656
657 #if PLATFORM(COCOA)
658     send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled));
659 #endif
660 }
661
662 void WebPageProxy::close()
663 {
664     if (m_isClosed)
665         return;
666
667     m_isClosed = true;
668
669     m_backForwardList->pageClosed();
670     m_pageClient.pageClosed();
671
672     m_process->disconnectFramesFromPage(this);
673
674     resetState(ResetStateReason::PageInvalidated);
675
676     m_loaderClient = std::make_unique<API::LoaderClient>();
677     m_policyClient = std::make_unique<API::PolicyClient>();
678     m_formClient = std::make_unique<API::FormClient>();
679     m_uiClient = std::make_unique<API::UIClient>();
680 #if PLATFORM(EFL)
681     m_uiPopupMenuClient.initialize(0);
682 #endif
683     m_findClient = std::make_unique<API::FindClient>();
684     m_findMatchesClient.initialize(0);
685 #if ENABLE(CONTEXT_MENUS)
686     m_contextMenuClient.initialize(0);
687 #endif
688
689     m_process->send(Messages::WebPage::Close(), m_pageID);
690     m_process->removeWebPage(m_pageID);
691     m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
692     m_process->processPool().storageManager().destroySessionStorageNamespace(m_pageID);
693     m_process->processPool().supplement<WebNotificationManagerProxy>()->clearNotifications(this);
694
695     m_websiteDataStore->removeWebPage(*this);
696 }
697
698 bool WebPageProxy::tryClose()
699 {
700     if (!isValid())
701         return true;
702
703     m_process->send(Messages::WebPage::TryClose(), m_pageID);
704     m_process->responsivenessTimer()->start();
705     return false;
706 }
707
708 bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const URL& url, SandboxExtension::Handle& sandboxExtensionHandle)
709 {
710     if (!url.isLocalFile())
711         return false;
712
713     if (m_process->hasAssumedReadAccessToURL(url))
714         return false;
715
716 #if ENABLE(INSPECTOR)
717     // Inspector resources are in a directory with assumed access.
718     ASSERT_WITH_SECURITY_IMPLICATION(!WebInspectorProxy::isInspectorPage(*this));
719 #endif
720
721     SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
722     return true;
723 }
724
725 uint64_t WebPageProxy::loadRequest(const ResourceRequest& request, API::Object* userData)
726 {
727     if (m_isClosed)
728         return 0;
729
730     uint64_t navigationID = generateNavigationID();
731
732     auto transaction = m_pageLoadState.transaction();
733
734     m_pageLoadState.setPendingAPIRequestURL(transaction, request.url());
735
736     if (!isValid())
737         reattachToWebProcess();
738
739     SandboxExtension::Handle sandboxExtensionHandle;
740     bool createdExtension = maybeInitializeSandboxExtensionHandle(request.url(), sandboxExtensionHandle);
741     if (createdExtension)
742         m_process->willAcquireUniversalFileReadSandboxExtension();
743     m_process->send(Messages::WebPage::LoadRequest(navigationID, request, sandboxExtensionHandle, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
744     m_process->responsivenessTimer()->start();
745
746     return navigationID;
747 }
748
749 uint64_t WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData)
750 {
751     if (m_isClosed)
752         return 0;
753
754     if (!isValid())
755         reattachToWebProcess();
756
757     URL fileURL = URL(URL(), fileURLString);
758     if (!fileURL.isLocalFile())
759         return 0;
760
761     URL resourceDirectoryURL;
762     if (resourceDirectoryURLString.isNull())
763         resourceDirectoryURL = URL(ParsedURLString, ASCIILiteral("file:///"));
764     else {
765         resourceDirectoryURL = URL(URL(), resourceDirectoryURLString);
766         if (!resourceDirectoryURL.isLocalFile())
767             return 0;
768     }
769
770     uint64_t navigationID = generateNavigationID();
771
772     auto transaction = m_pageLoadState.transaction();
773
774     m_pageLoadState.setPendingAPIRequestURL(transaction, fileURLString);
775
776     String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath();
777
778     SandboxExtension::Handle sandboxExtensionHandle;
779     SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, sandboxExtensionHandle);
780     m_process->assumeReadAccessToBaseURL(resourceDirectoryURL);
781     m_process->send(Messages::WebPage::LoadRequest(navigationID, fileURL, sandboxExtensionHandle, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
782     m_process->responsivenessTimer()->start();
783
784     return navigationID;
785 }
786
787 uint64_t WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
788 {
789     if (m_isClosed)
790         return 0;
791
792     uint64_t navigationID = generateNavigationID();
793
794     auto transaction = m_pageLoadState.transaction();
795
796     m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : ASCIILiteral("about:blank"));
797
798     if (!isValid())
799         reattachToWebProcess();
800
801     m_process->assumeReadAccessToBaseURL(baseURL);
802     m_process->send(Messages::WebPage::LoadData(data->dataReference(), MIMEType, encoding, baseURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
803     m_process->responsivenessTimer()->start();
804
805     return navigationID;
806 }
807
808 // FIXME: Get rid of loadHTMLString and just use loadData instead.
809 uint64_t WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData)
810 {
811     if (m_isClosed)
812         return 0;
813
814     uint64_t navigationID = generateNavigationID();
815
816     auto transaction = m_pageLoadState.transaction();
817
818     m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : ASCIILiteral("about:blank"));
819
820     if (!isValid())
821         reattachToWebProcess();
822
823     m_process->assumeReadAccessToBaseURL(baseURL);
824     m_process->send(Messages::WebPage::LoadHTMLString(navigationID, htmlString, baseURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
825     m_process->responsivenessTimer()->start();
826
827     return navigationID;
828 }
829
830 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, API::Object* userData)
831 {
832     if (m_isClosed)
833         return;
834
835     if (!isValid())
836         reattachToWebProcess();
837
838     auto transaction = m_pageLoadState.transaction();
839
840     m_pageLoadState.setUnreachableURL(transaction, unreachableURL);
841
842     if (m_mainFrame)
843         m_mainFrame->setUnreachableURL(unreachableURL);
844
845     m_process->assumeReadAccessToBaseURL(baseURL);
846     m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
847     m_process->responsivenessTimer()->start();
848 }
849
850 void WebPageProxy::loadPlainTextString(const String& string, API::Object* userData)
851 {
852     if (m_isClosed)
853         return;
854
855     if (!isValid())
856         reattachToWebProcess();
857
858     m_process->send(Messages::WebPage::LoadPlainTextString(string, UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
859     m_process->responsivenessTimer()->start();
860 }
861
862 void WebPageProxy::loadWebArchiveData(API::Data* webArchiveData, API::Object* userData)
863 {
864     if (m_isClosed)
865         return;
866
867     if (!isValid())
868         reattachToWebProcess();
869
870     m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference(), UserData(process().transformObjectsToHandles(userData).get())), m_pageID);
871     m_process->responsivenessTimer()->start();
872 }
873
874 void WebPageProxy::navigateToURLWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint)
875 {
876     if (m_isClosed)
877         return;
878
879     if (!isValid())
880         reattachToWebProcess();
881
882     m_process->send(Messages::WebPage::NavigateToURLWithSimulatedClick(url, documentPoint, screenPoint), m_pageID);
883     m_process->responsivenessTimer()->start();
884 }
885
886 void WebPageProxy::stopLoading()
887 {
888     if (!isValid())
889         return;
890
891     m_process->send(Messages::WebPage::StopLoading(), m_pageID);
892     m_process->responsivenessTimer()->start();
893 }
894
895 uint64_t WebPageProxy::reload(bool reloadFromOrigin)
896 {
897     SandboxExtension::Handle sandboxExtensionHandle;
898
899     if (m_backForwardList->currentItem()) {
900         String url = m_backForwardList->currentItem()->url();
901         auto transaction = m_pageLoadState.transaction();
902         m_pageLoadState.setPendingAPIRequestURL(transaction, url);
903
904         // We may not have an extension yet if back/forward list was reinstated after a WebProcess crash or a browser relaunch
905         bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), url), sandboxExtensionHandle);
906         if (createdExtension)
907             m_process->willAcquireUniversalFileReadSandboxExtension();
908     }
909
910     if (!isValid())
911         return reattachToWebProcessWithItem(m_backForwardList->currentItem());
912
913     uint64_t navigationID = generateNavigationID();
914
915     m_process->send(Messages::WebPage::Reload(navigationID, reloadFromOrigin, sandboxExtensionHandle), m_pageID);
916     m_process->responsivenessTimer()->start();
917
918     return navigationID;
919 }
920
921 void WebPageProxy::recordNavigationSnapshot()
922 {
923     if (WebBackForwardListItem* item = m_backForwardList->currentItem())
924         recordNavigationSnapshot(*item);
925 }
926
927 void WebPageProxy::recordNavigationSnapshot(WebBackForwardListItem& item)
928 {
929     if (!m_shouldRecordNavigationSnapshots)
930         return;
931
932 #if PLATFORM(COCOA)
933     ViewSnapshotStore::shared().recordSnapshot(*this, item);
934 #else
935     UNUSED_PARAM(item);
936 #endif
937 }
938
939 uint64_t WebPageProxy::goForward()
940 {
941     WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
942     if (!forwardItem)
943         return 0;
944
945     auto transaction = m_pageLoadState.transaction();
946
947     m_pageLoadState.setPendingAPIRequestURL(transaction, forwardItem->url());
948
949     if (!isValid())
950         return reattachToWebProcessWithItem(forwardItem);
951
952     uint64_t navigationID = m_backForwardList->currentItem()->itemIsInSameDocument(*forwardItem) ? 0 : generateNavigationID();
953
954     m_process->send(Messages::WebPage::GoForward(navigationID, forwardItem->itemID()), m_pageID);
955     m_process->responsivenessTimer()->start();
956
957     return navigationID;
958 }
959
960 uint64_t WebPageProxy::goBack()
961 {
962     WebBackForwardListItem* backItem = m_backForwardList->backItem();
963     if (!backItem)
964         return 0;
965
966     auto transaction = m_pageLoadState.transaction();
967
968     m_pageLoadState.setPendingAPIRequestURL(transaction, backItem->url());
969
970     if (!isValid())
971         return reattachToWebProcessWithItem(backItem);
972
973     uint64_t navigationID = m_backForwardList->currentItem()->itemIsInSameDocument(*backItem) ? 0 : generateNavigationID();
974
975     m_process->send(Messages::WebPage::GoBack(navigationID, backItem->itemID()), m_pageID);
976     m_process->responsivenessTimer()->start();
977
978     return navigationID;
979 }
980
981 uint64_t WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
982 {
983     if (!isValid())
984         return reattachToWebProcessWithItem(item);
985
986     auto transaction = m_pageLoadState.transaction();
987
988     m_pageLoadState.setPendingAPIRequestURL(transaction, item->url());
989
990     uint64_t navigationID = m_backForwardList->currentItem()->itemIsInSameDocument(*item) ? 0 : generateNavigationID();
991
992     m_process->send(Messages::WebPage::GoToBackForwardItem(navigationID, item->itemID()), m_pageID);
993     m_process->responsivenessTimer()->start();
994
995     return navigationID;
996 }
997
998 void WebPageProxy::tryRestoreScrollPosition()
999 {
1000     if (!isValid())
1001         return;
1002
1003     m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID);
1004 }
1005
1006 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<WebBackForwardListItem>> removed)
1007 {
1008     m_loaderClient->didChangeBackForwardList(this, added, WTF::move(removed));
1009
1010     auto transaction = m_pageLoadState.transaction();
1011
1012     m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem());
1013     m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem());
1014 }
1015
1016 void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, const UserData& userData)
1017 {
1018     if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID))
1019         m_loaderClient->willGoToBackForwardListItem(this, item, m_process->transformHandlesToObjects(userData.object()).get());
1020 }
1021
1022 bool WebPageProxy::shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem* item)
1023 {
1024     return m_loaderClient->shouldKeepCurrentBackForwardListItemInList(this, item);
1025 }
1026
1027 bool WebPageProxy::canShowMIMEType(const String& mimeType)
1028 {
1029     if (MIMETypeRegistry::canShowMIMEType(mimeType))
1030         return true;
1031
1032 #if ENABLE(NETSCAPE_PLUGIN_API)
1033     String newMimeType = mimeType;
1034     PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL());
1035     if (!plugin.path.isNull() && m_preferences->pluginsEnabled())
1036         return true;
1037 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1038
1039 #if PLATFORM(COCOA)
1040     // On Mac, we can show PDFs.
1041     if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebProcessPool::omitPDFSupport())
1042         return true;
1043 #endif // PLATFORM(COCOA)
1044
1045     return false;
1046 }
1047
1048 #if ENABLE(REMOTE_INSPECTOR)
1049 void WebPageProxy::setAllowsRemoteInspection(bool allow)
1050 {
1051     if (m_allowsRemoteInspection == allow)
1052         return;
1053
1054     m_allowsRemoteInspection = allow;
1055
1056     if (isValid())
1057         m_process->send(Messages::WebPage::SetAllowsRemoteInspection(allow), m_pageID);
1058 }
1059 #endif
1060
1061 void WebPageProxy::setDrawsBackground(bool drawsBackground)
1062 {
1063     if (m_drawsBackground == drawsBackground)
1064         return;
1065
1066     m_drawsBackground = drawsBackground;
1067
1068     if (isValid())
1069         m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
1070 }
1071
1072 void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
1073 {
1074     if (m_drawsTransparentBackground == drawsTransparentBackground)
1075         return;
1076
1077     m_drawsTransparentBackground = drawsTransparentBackground;
1078
1079     if (isValid())
1080         m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
1081 }
1082
1083 void WebPageProxy::setTopContentInset(float contentInset)
1084 {
1085     if (m_topContentInset == contentInset)
1086         return;
1087
1088     m_topContentInset = contentInset;
1089
1090     if (isValid())
1091         m_process->send(Messages::WebPage::SetTopContentInset(contentInset), m_pageID);
1092 }
1093
1094 void WebPageProxy::setUnderlayColor(const Color& color)
1095 {
1096     if (m_underlayColor == color)
1097         return;
1098
1099     m_underlayColor = color;
1100
1101     if (isValid())
1102         m_process->send(Messages::WebPage::SetUnderlayColor(color), m_pageID);
1103 }
1104
1105 void WebPageProxy::viewWillStartLiveResize()
1106 {
1107     if (!isValid())
1108         return;
1109 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1110     if (m_colorPicker)
1111         endColorPicker();
1112 #endif
1113     m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
1114 }
1115
1116 void WebPageProxy::viewWillEndLiveResize()
1117 {
1118     if (!isValid())
1119         return;
1120     m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
1121 }
1122
1123 void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
1124 {
1125     m_pageClient.setViewNeedsDisplay(rect);
1126 }
1127
1128 void WebPageProxy::displayView()
1129 {
1130     m_pageClient.displayView();
1131 }
1132
1133 bool WebPageProxy::canScrollView()
1134 {
1135     return m_pageClient.canScrollView();
1136 }
1137
1138 void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
1139 {
1140     m_pageClient.scrollView(scrollRect, scrollOffset);
1141 }
1142
1143 void WebPageProxy::requestScroll(const FloatPoint& scrollPosition, bool isProgrammaticScroll)
1144 {
1145     m_pageClient.requestScroll(scrollPosition, isProgrammaticScroll);
1146 }
1147
1148 void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate)
1149 {
1150     m_viewState &= ~flagsToUpdate;
1151     if (flagsToUpdate & ViewState::IsFocused && m_pageClient.isViewFocused())
1152         m_viewState |= ViewState::IsFocused;
1153     if (flagsToUpdate & ViewState::WindowIsActive && m_pageClient.isViewWindowActive())
1154         m_viewState |= ViewState::WindowIsActive;
1155     if (flagsToUpdate & ViewState::IsVisible && m_pageClient.isViewVisible())
1156         m_viewState |= ViewState::IsVisible;
1157     if (flagsToUpdate & ViewState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded())
1158         m_viewState |= ViewState::IsVisibleOrOccluded;
1159     if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow()) {
1160         m_viewState |= ViewState::IsInWindow;
1161         m_viewWasEverInWindow = true;
1162     }
1163     if (flagsToUpdate & ViewState::IsVisuallyIdle && m_pageClient.isVisuallyIdle())
1164         m_viewState |= ViewState::IsVisuallyIdle;
1165 }
1166
1167 void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsSynchronousReply, ViewStateChangeDispatchMode dispatchMode)
1168 {
1169     m_potentiallyChangedViewStateFlags |= mayHaveChanged;
1170     m_viewStateChangeWantsSynchronousReply = m_viewStateChangeWantsSynchronousReply || wantsSynchronousReply;
1171
1172 #if PLATFORM(COCOA)
1173     bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ViewState::IsInWindow) && m_pageClient.isViewInWindow();
1174     if (dispatchMode == ViewStateChangeDispatchMode::Immediate || isNewlyInWindow) {
1175         dispatchViewStateChange();
1176         return;
1177     }
1178     m_viewStateChangeDispatcher->schedule();
1179 #else
1180     UNUSED_PARAM(dispatchMode);
1181     dispatchViewStateChange();
1182 #endif
1183 }
1184
1185 void WebPageProxy::viewDidLeaveWindow()
1186 {
1187 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
1188     // When leaving the current page, close the popover color well.
1189     if (m_colorPicker)
1190         endColorPicker();
1191 #endif
1192 #if PLATFORM(IOS)
1193     // When leaving the current page, close the video fullscreen.
1194     if (m_videoFullscreenManager)
1195         m_videoFullscreenManager->requestHideAndExitFullscreen();
1196 #endif
1197 }
1198
1199 void WebPageProxy::viewDidEnterWindow()
1200 {
1201     LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1202     if (m_layerHostingMode != layerHostingMode) {
1203         m_layerHostingMode = layerHostingMode;
1204         m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1205     }
1206 }
1207
1208 void WebPageProxy::dispatchViewStateChange()
1209 {
1210 #if PLATFORM(COCOA)
1211     m_viewStateChangeDispatcher->invalidate();
1212 #endif
1213
1214     if (!isValid())
1215         return;
1216
1217     // If the visibility state may have changed, then so may the visually idle & occluded agnostic state.
1218     if (m_potentiallyChangedViewStateFlags & ViewState::IsVisible)
1219         m_potentiallyChangedViewStateFlags |= ViewState::IsVisibleOrOccluded | ViewState::IsVisuallyIdle;
1220
1221     // Record the prior view state, update the flags that may have changed,
1222     // and check which flags have actually changed.
1223     ViewState::Flags previousViewState = m_viewState;
1224     updateViewState(m_potentiallyChangedViewStateFlags);
1225     ViewState::Flags changed = m_viewState ^ previousViewState;
1226
1227     // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
1228     if (m_viewWasEverInWindow && (changed & ViewState::IsInWindow) && isInWindow())
1229         m_viewStateChangeWantsSynchronousReply = true;
1230
1231     if (changed || m_viewStateChangeWantsSynchronousReply || !m_nextViewStateChangeCallbacks.isEmpty())
1232         m_process->send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsSynchronousReply, m_nextViewStateChangeCallbacks), m_pageID);
1233
1234     m_nextViewStateChangeCallbacks.clear();
1235
1236     // This must happen after the SetViewState message is sent, to ensure the page visibility event can fire.
1237     updateActivityToken();
1238
1239     // If we've started the responsiveness timer as part of telling the web process to update the backing store
1240     // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
1241     // stop the unresponsiveness timer here.
1242     if ((changed & ViewState::IsVisible) && !isViewVisible())
1243         m_process->responsivenessTimer()->stop();
1244
1245     if (changed & ViewState::IsInWindow) {
1246         if (isInWindow())
1247             viewDidEnterWindow();
1248         else
1249             viewDidLeaveWindow();
1250     }
1251
1252     updateBackingStoreDiscardableState();
1253
1254     if (m_viewStateChangeWantsSynchronousReply)
1255         waitForDidUpdateViewState();
1256
1257     m_potentiallyChangedViewStateFlags = ViewState::NoFlags;
1258     m_viewStateChangeWantsSynchronousReply = false;
1259 }
1260
1261 void WebPageProxy::updateActivityToken()
1262 {
1263     if (m_viewState & ViewState::IsVisuallyIdle)
1264         m_pageIsUserObservableCount = nullptr;
1265     else if (!m_pageIsUserObservableCount)
1266         m_pageIsUserObservableCount = m_process->processPool().userObservablePageCount();
1267
1268 #if PLATFORM(IOS)
1269     if (!isViewVisible())
1270         m_activityToken = nullptr;
1271     else if (!m_activityToken)
1272         m_activityToken = m_process->throttler().foregroundActivityToken();
1273 #endif
1274 }
1275
1276 void WebPageProxy::updateProccessSuppressionState()
1277 {
1278     if (m_preferences->pageVisibilityBasedProcessSuppressionEnabled())
1279         m_preventProcessSuppressionCount = nullptr;
1280     else if (!m_preventProcessSuppressionCount)
1281         m_preventProcessSuppressionCount = m_process->processPool().processSuppressionDisabledForPageCount();
1282 }
1283
1284 void WebPageProxy::layerHostingModeDidChange()
1285 {
1286     if (!isValid())
1287         return;
1288
1289     LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
1290     if (m_layerHostingMode == layerHostingMode)
1291         return;
1292
1293     m_layerHostingMode = layerHostingMode;
1294     m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
1295 }
1296
1297 void WebPageProxy::waitForDidUpdateViewState()
1298 {
1299     if (!isValid())
1300         return;
1301
1302     if (m_process->state() != WebProcessProxy::State::Running)
1303         return;
1304
1305     // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding.
1306     if (m_waitingForDidUpdateViewState)
1307         return;
1308
1309     m_waitingForDidUpdateViewState = true;
1310
1311     m_drawingArea->waitForDidUpdateViewState();
1312 }
1313
1314 IntSize WebPageProxy::viewSize() const
1315 {
1316     return m_pageClient.viewSize();
1317 }
1318
1319 void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent)
1320 {
1321     if (!isValid())
1322         return;
1323     m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent), m_pageID);
1324 }
1325
1326 void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
1327 {
1328     if (!isValid())
1329         return;
1330     m_process->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
1331 }
1332     
1333 void WebPageProxy::clearSelection()
1334 {
1335     if (!isValid())
1336         return;
1337     m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
1338 }
1339
1340 void WebPageProxy::validateCommand(const String& commandName, std::function<void (const String&, bool, int32_t, CallbackBase::Error)> callbackFunction)
1341 {
1342     if (!isValid()) {
1343         callbackFunction(String(), false, 0, CallbackBase::Error::Unknown);
1344         return;
1345     }
1346
1347     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
1348     m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
1349 }
1350
1351 void WebPageProxy::setMaintainsInactiveSelection(bool newValue)
1352 {
1353     m_maintainsInactiveSelection = newValue;
1354 }
1355     
1356 void WebPageProxy::executeEditCommand(const String& commandName)
1357 {
1358     static NeverDestroyed<String> ignoreSpellingCommandName(ASCIILiteral("ignoreSpelling"));
1359
1360     if (!isValid())
1361         return;
1362
1363     if (commandName == ignoreSpellingCommandName)
1364         ++m_pendingLearnOrIgnoreWordMessageCount;
1365
1366     m_process->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
1367 }
1368
1369 #if !PLATFORM(IOS)
1370 void WebPageProxy::didCommitLayerTree(const RemoteLayerTreeTransaction&)
1371 {
1372 }
1373 #endif
1374
1375 #if USE(TILED_BACKING_STORE)
1376 void WebPageProxy::commitPageTransitionViewport()
1377 {
1378     if (!isValid())
1379         return;
1380
1381     process().send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID);
1382 }
1383 #endif
1384
1385 #if ENABLE(DRAG_SUPPORT)
1386 void WebPageProxy::dragEntered(DragData& dragData, const String& dragStorageName)
1387 {
1388     SandboxExtension::Handle sandboxExtensionHandle;
1389     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1390     performDragControllerAction(DragControllerActionEntered, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1391 }
1392
1393 void WebPageProxy::dragUpdated(DragData& dragData, const String& dragStorageName)
1394 {
1395     SandboxExtension::Handle sandboxExtensionHandle;
1396     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1397     performDragControllerAction(DragControllerActionUpdated, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1398 }
1399
1400 void WebPageProxy::dragExited(DragData& dragData, const String& dragStorageName)
1401 {
1402     SandboxExtension::Handle sandboxExtensionHandle;
1403     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1404     performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1405 }
1406
1407 void WebPageProxy::performDragOperation(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1408 {
1409     performDragControllerAction(DragControllerActionPerformDragOperation, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
1410 }
1411
1412 void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1413 {
1414     if (!isValid())
1415         return;
1416 #if PLATFORM(GTK)
1417     UNUSED_PARAM(dragStorageName);
1418     UNUSED_PARAM(sandboxExtensionHandle);
1419     UNUSED_PARAM(sandboxExtensionsForUpload);
1420
1421     String url = dragData.asURL();
1422     if (!url.isEmpty())
1423         m_process->assumeReadAccessToBaseURL(url);
1424     m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData), m_pageID);
1425 #else
1426     m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), dragStorageName, dragData.flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
1427 #endif
1428 }
1429
1430 void WebPageProxy::didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted)
1431 {
1432     MESSAGE_CHECK(dragOperation <= DragOperationDelete);
1433
1434     m_currentDragOperation = static_cast<DragOperation>(dragOperation);
1435     m_currentDragIsOverFileInput = mouseIsOverFileInput;
1436     m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted;
1437 }
1438
1439 #if PLATFORM(GTK)
1440 void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle)
1441 {
1442     RefPtr<ShareableBitmap> dragImage = 0;
1443     if (!dragImageHandle.isNull()) {
1444         dragImage = ShareableBitmap::create(dragImageHandle);
1445         if (!dragImage)
1446             return;
1447     }
1448
1449     m_pageClient.startDrag(dragData, dragImage.release());
1450 }
1451 #endif
1452
1453 void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation)
1454 {
1455     if (!isValid())
1456         return;
1457     m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
1458 }
1459 #endif // ENABLE(DRAG_SUPPORT)
1460
1461 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
1462 {
1463     if (!isValid())
1464         return;
1465
1466     // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
1467     if (event.type() != WebEvent::MouseMove)
1468         m_process->responsivenessTimer()->start();
1469     else {
1470         if (m_processingMouseMoveEvent) {
1471             m_nextMouseMoveEvent = std::make_unique<NativeWebMouseEvent>(event);
1472             return;
1473         }
1474
1475         m_processingMouseMoveEvent = true;
1476     }
1477
1478     // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
1479     // display a popup menu for select elements. When the user changes the selected item,
1480     // we fake a mouse up event by using this stored down event. This event gets cleared
1481     // when the mouse up message is received from WebProcess.
1482     if (event.type() == WebEvent::MouseDown)
1483         m_currentlyProcessedMouseDownEvent = std::make_unique<NativeWebMouseEvent>(event);
1484
1485     if (m_shouldSendEventsSynchronously) {
1486         bool handled = false;
1487         m_process->sendSync(Messages::WebPage::MouseEventSyncForTesting(event), Messages::WebPage::MouseEventSyncForTesting::Reply(handled), m_pageID);
1488         didReceiveEvent(event.type(), handled);
1489     } else
1490         m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
1491 }
1492
1493 #if MERGE_WHEEL_EVENTS
1494 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1495 {
1496     if (a.position() != b.position())
1497         return false;
1498     if (a.globalPosition() != b.globalPosition())
1499         return false;
1500     if (a.modifiers() != b.modifiers())
1501         return false;
1502     if (a.granularity() != b.granularity())
1503         return false;
1504 #if PLATFORM(COCOA)
1505     if (a.phase() != b.phase())
1506         return false;
1507     if (a.momentumPhase() != b.momentumPhase())
1508         return false;
1509     if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas())
1510         return false;
1511 #endif
1512
1513     return true;
1514 }
1515
1516 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1517 {
1518     ASSERT(canCoalesce(a, b));
1519
1520     FloatSize mergedDelta = a.delta() + b.delta();
1521     FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();
1522
1523 #if PLATFORM(COCOA)
1524     FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta();
1525
1526     return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.directionInvertedFromDevice(), b.phase(), b.momentumPhase(), b.hasPreciseScrollingDeltas(), b.scrollCount(), mergedUnacceleratedScrollingDelta, b.modifiers(), b.timestamp());
1527 #else
1528     return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp());
1529 #endif
1530 }
1531 #endif // MERGE_WHEEL_EVENTS
1532
1533 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents)
1534 {
1535     ASSERT(!queue.isEmpty());
1536     ASSERT(coalescedEvents.isEmpty());
1537
1538 #if MERGE_WHEEL_EVENTS
1539     NativeWebWheelEvent firstEvent = queue.takeFirst();
1540     coalescedEvents.append(firstEvent);
1541
1542     WebWheelEvent event = firstEvent;
1543     while (!queue.isEmpty() && canCoalesce(event, queue.first())) {
1544         NativeWebWheelEvent firstEvent = queue.takeFirst();
1545         coalescedEvents.append(firstEvent);
1546         event = coalesce(event, firstEvent);
1547     }
1548
1549     return event;
1550 #else
1551     while (!queue.isEmpty())
1552         coalescedEvents.append(queue.takeFirst());
1553     return coalescedEvents.last();
1554 #endif
1555 }
1556
1557 void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
1558 {
1559 #if ENABLE(ASYNC_SCROLLING)
1560     if (m_scrollingCoordinatorProxy && m_scrollingCoordinatorProxy->handleWheelEvent(platform(event)))
1561         return;
1562 #endif
1563
1564     if (!isValid())
1565         return;
1566
1567     if (!m_currentlyProcessedWheelEvents.isEmpty()) {
1568         m_wheelEventQueue.append(event);
1569         if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold)
1570             return;
1571         // The queue has too many wheel events, so push a new event.
1572     }
1573
1574     if (!m_wheelEventQueue.isEmpty()) {
1575         processNextQueuedWheelEvent();
1576         return;
1577     }
1578
1579     auto coalescedWheelEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1580     coalescedWheelEvent->append(event);
1581     m_currentlyProcessedWheelEvents.append(WTF::move(coalescedWheelEvent));
1582     sendWheelEvent(event);
1583 }
1584
1585 void WebPageProxy::processNextQueuedWheelEvent()
1586 {
1587     auto nextCoalescedEvent = std::make_unique<Vector<NativeWebWheelEvent>>();
1588     WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get());
1589     m_currentlyProcessedWheelEvents.append(WTF::move(nextCoalescedEvent));
1590     sendWheelEvent(nextWheelEvent);
1591 }
1592
1593 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
1594 {
1595     m_process->responsivenessTimer()->start();
1596
1597     if (m_shouldSendEventsSynchronously) {
1598         bool handled = false;
1599         m_process->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID);
1600         didReceiveEvent(event.type(), handled);
1601         return;
1602     }
1603
1604     m_process->send(
1605         Messages::EventDispatcher::WheelEvent(
1606             m_pageID,
1607             event,
1608             shouldUseImplicitRubberBandControl() ? !m_backForwardList->backItem() : rubberBandsAtLeft(),
1609             shouldUseImplicitRubberBandControl() ? !m_backForwardList->forwardItem() : rubberBandsAtRight(),
1610             rubberBandsAtTop(),
1611             rubberBandsAtBottom()
1612         ), 0);
1613 }
1614
1615 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
1616 {
1617     if (!isValid())
1618         return;
1619     
1620     LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type()));
1621
1622     m_keyEventQueue.append(event);
1623
1624     m_process->responsivenessTimer()->start();
1625     if (m_shouldSendEventsSynchronously) {
1626         bool handled = false;
1627         m_process->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID);
1628         didReceiveEvent(event.type(), handled);
1629     } else if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler.
1630         m_process->send(Messages::WebPage::KeyEvent(event), m_pageID);
1631 }
1632
1633 uint64_t WebPageProxy::generateNavigationID()
1634 {
1635     return ++m_navigationID;
1636 }
1637
1638 WebPreferencesStore WebPageProxy::preferencesStore() const
1639 {
1640     if (m_configurationPreferenceValues.isEmpty())
1641         return m_preferences->store();
1642
1643     WebPreferencesStore store = m_preferences->store();
1644     for (const auto& preference : m_configurationPreferenceValues)
1645         store.m_values.set(preference.key, preference.value);
1646
1647     return store;
1648 }
1649
1650 #if ENABLE(NETSCAPE_PLUGIN_API)
1651 void WebPageProxy::findPlugin(const String& mimeType, uint32_t processType, const String& urlString, const String& frameURLString, const String& pageURLString, bool allowOnlyApplicationPlugins, uint64_t& pluginProcessToken, String& newMimeType, uint32_t& pluginLoadPolicy, String& unavailabilityDescription)
1652 {
1653     MESSAGE_CHECK_URL(urlString);
1654
1655     newMimeType = mimeType.lower();
1656     pluginLoadPolicy = PluginModuleLoadNormally;
1657
1658     PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
1659     PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes);
1660     if (!plugin.path) {
1661         pluginProcessToken = 0;
1662         return;
1663     }
1664
1665     pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin);
1666
1667 #if PLATFORM(COCOA)
1668     RefPtr<API::Dictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String());
1669     pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription);
1670 #else
1671     UNUSED_PARAM(frameURLString);
1672     UNUSED_PARAM(pageURLString);
1673     UNUSED_PARAM(unavailabilityDescription);
1674 #endif
1675
1676     PluginProcessSandboxPolicy pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1677     switch (pluginLoadPolicy) {
1678     case PluginModuleLoadNormally:
1679         pluginProcessSandboxPolicy = PluginProcessSandboxPolicyNormal;
1680         break;
1681     case PluginModuleLoadUnsandboxed:
1682         pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed;
1683         break;
1684
1685     case PluginModuleBlocked:
1686         pluginProcessToken = 0;
1687         return;
1688     }
1689
1690     pluginProcessToken = PluginProcessManager::shared().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy);
1691 }
1692
1693 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1694
1695 #if ENABLE(TOUCH_EVENTS)
1696
1697 bool WebPageProxy::shouldStartTrackingTouchEvents(const WebTouchEvent& touchStartEvent) const
1698 {
1699 #if ENABLE(ASYNC_SCROLLING)
1700     for (auto& touchPoint : touchStartEvent.touchPoints()) {
1701         if (m_scrollingCoordinatorProxy->isPointInNonFastScrollableRegion(touchPoint.location()))
1702             return true;
1703     }
1704
1705     return false;
1706 #else
1707     UNUSED_PARAM(touchStartEvent);
1708 #endif // ENABLE(ASYNC_SCROLLING)
1709     return true;
1710 }
1711
1712 #endif
1713
1714 #if ENABLE(IOS_TOUCH_EVENTS)
1715 void WebPageProxy::handleTouchEventSynchronously(const NativeWebTouchEvent& event)
1716 {
1717     if (!isValid())
1718         return;
1719
1720     if (event.type() == WebEvent::TouchStart)
1721         m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1722
1723     if (!m_isTrackingTouchEvents)
1724         return;
1725
1726     m_process->responsivenessTimer()->start();
1727     bool handled = false;
1728     m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID);
1729     didReceiveEvent(event.type(), handled);
1730     m_pageClient.doneWithTouchEvent(event, handled);
1731     m_process->responsivenessTimer()->stop();
1732
1733     if (event.allTouchPointsAreReleased())
1734         m_isTrackingTouchEvents = false;
1735 }
1736
1737 void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event)
1738 {
1739     if (!isValid())
1740         return;
1741
1742     if (!m_isTrackingTouchEvents)
1743         return;
1744
1745     m_process->send(Messages::EventDispatcher::TouchEvent(m_pageID, event), 0);
1746
1747     if (event.allTouchPointsAreReleased())
1748         m_isTrackingTouchEvents = false;
1749 }
1750
1751 #elif ENABLE(TOUCH_EVENTS)
1752 void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
1753 {
1754     if (!isValid())
1755         return;
1756
1757     if (event.type() == WebEvent::TouchStart)
1758         m_isTrackingTouchEvents = shouldStartTrackingTouchEvents(event);
1759
1760     if (!m_isTrackingTouchEvents)
1761         return;
1762
1763     // If the page is suspended, which should be the case during panning, pinching
1764     // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then
1765     // we do not send any of the events to the page even if is has listeners.
1766     if (!m_isPageSuspended) {
1767         m_touchEventQueue.append(event);
1768         m_process->responsivenessTimer()->start();
1769         if (m_shouldSendEventsSynchronously) {
1770             bool handled = false;
1771             m_process->sendSync(Messages::WebPage::TouchEventSyncForTesting(event), Messages::WebPage::TouchEventSyncForTesting::Reply(handled), m_pageID);
1772             didReceiveEvent(event.type(), handled);
1773         } else
1774             m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
1775     } else {
1776         if (m_touchEventQueue.isEmpty()) {
1777             bool isEventHandled = false;
1778             m_pageClient.doneWithTouchEvent(event, isEventHandled);
1779         } else {
1780             // We attach the incoming events to the newest queued event so that all
1781             // the events are delivered in the correct order when the event is dequed.
1782             QueuedTouchEvents& lastEvent = m_touchEventQueue.last();
1783             lastEvent.deferredTouchEvents.append(event);
1784         }
1785     }
1786
1787     if (event.allTouchPointsAreReleased())
1788         m_isTrackingTouchEvents = false;
1789 }
1790 #endif // ENABLE(TOUCH_EVENTS)
1791
1792 void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
1793 {
1794     if (!isValid())
1795         return;
1796
1797     m_process->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID);
1798 }
1799
1800 void WebPageProxy::centerSelectionInVisibleArea()
1801 {
1802     if (!isValid())
1803         return;
1804
1805     m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID);
1806 }
1807
1808 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID, uint64_t navigationID)
1809 {
1810     if (!isValid())
1811         return;
1812
1813     auto transaction = m_pageLoadState.transaction();
1814
1815     if (action == PolicyIgnore)
1816         m_pageLoadState.clearPendingAPIRequestURL(transaction);
1817
1818     uint64_t downloadID = 0;
1819     if (action == PolicyDownload) {
1820         // Create a download proxy.
1821         // FIXME: We should ensure that the downloadRequest is never empty.
1822         const ResourceRequest& downloadRequest = m_decidePolicyForResponseRequest ? *m_decidePolicyForResponseRequest : ResourceRequest();
1823         DownloadProxy* download = m_process->processPool().createDownloadProxy(downloadRequest);
1824         downloadID = download->downloadID();
1825         handleDownloadRequest(download);
1826     }
1827
1828     // If we received a policy decision while in decidePolicyForResponse the decision will
1829     // be sent back to the web process by decidePolicyForResponse.
1830     if (m_inDecidePolicyForResponseSync) {
1831         m_syncMimeTypePolicyActionIsValid = true;
1832         m_syncMimeTypePolicyAction = action;
1833         m_syncMimeTypePolicyDownloadID = downloadID;
1834         return;
1835     }
1836
1837     // If we received a policy decision while in decidePolicyForNavigationAction the decision will 
1838     // be sent back to the web process by decidePolicyForNavigationAction. 
1839     if (m_inDecidePolicyForNavigationAction) {
1840         m_syncNavigationActionPolicyActionIsValid = true;
1841         m_syncNavigationActionPolicyAction = action;
1842         m_syncNavigationActionPolicyDownloadID = downloadID;
1843         return;
1844     }
1845     
1846     m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, navigationID, downloadID), m_pageID);
1847 }
1848
1849 void WebPageProxy::setUserAgent(const String& userAgent)
1850 {
1851     if (m_userAgent == userAgent)
1852         return;
1853     m_userAgent = userAgent;
1854
1855     if (!isValid())
1856         return;
1857     m_process->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
1858 }
1859
1860 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
1861 {
1862     if (m_applicationNameForUserAgent == applicationName)
1863         return;
1864
1865     m_applicationNameForUserAgent = applicationName;
1866     if (!m_customUserAgent.isEmpty())
1867         return;
1868
1869     setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
1870 }
1871
1872 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
1873 {
1874     if (m_customUserAgent == customUserAgent)
1875         return;
1876
1877     m_customUserAgent = customUserAgent;
1878
1879     if (m_customUserAgent.isEmpty()) {
1880         setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
1881         return;
1882     }
1883
1884     setUserAgent(m_customUserAgent);
1885 }
1886
1887 void WebPageProxy::resumeActiveDOMObjectsAndAnimations()
1888 {
1889     if (!isValid() || !m_isPageSuspended)
1890         return;
1891
1892     m_isPageSuspended = false;
1893
1894     m_process->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID);
1895 }
1896
1897 void WebPageProxy::suspendActiveDOMObjectsAndAnimations()
1898 {
1899     if (!isValid() || m_isPageSuspended)
1900         return;
1901
1902     m_isPageSuspended = true;
1903
1904     m_process->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID);
1905 }
1906
1907 bool WebPageProxy::supportsTextEncoding() const
1908 {
1909     // FIXME (118840): We should probably only support this for text documents, not all non-image documents.
1910     return m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
1911 }
1912
1913 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
1914 {
1915     if (m_customTextEncodingName == encodingName)
1916         return;
1917     m_customTextEncodingName = encodingName;
1918
1919     if (!isValid())
1920         return;
1921     m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
1922 }
1923
1924 void WebPageProxy::terminateProcess()
1925 {
1926     // requestTermination() is a no-op for launching processes, so we get into an inconsistent state by calling resetStateAfterProcessExited().
1927     // FIXME: A client can terminate the page at any time, so we should do something more meaningful than assert and fall apart in release builds.
1928     // See also <https://bugs.webkit.org/show_bug.cgi?id=136012>.
1929     ASSERT(m_process->state() != WebProcessProxy::State::Launching);
1930
1931     // NOTE: This uses a check of m_isValid rather than calling isValid() since
1932     // we want this to run even for pages being closed or that already closed.
1933     if (!m_isValid)
1934         return;
1935
1936     m_process->requestTermination();
1937     resetStateAfterProcessExited();
1938 }
1939
1940 SessionState WebPageProxy::sessionState(const std::function<bool (WebBackForwardListItem&)>& filter) const
1941 {
1942     SessionState sessionState;
1943
1944     sessionState.backForwardListState = m_backForwardList->backForwardListState(filter);
1945
1946     String provisionalURLString = m_pageLoadState.pendingAPIRequestURL();
1947     if (provisionalURLString.isEmpty())
1948         provisionalURLString = m_pageLoadState.provisionalURL();
1949
1950     if (!provisionalURLString.isEmpty())
1951         sessionState.provisionalURL = URL(URL(), provisionalURLString);
1952
1953     sessionState.renderTreeSize = renderTreeSize();
1954     return sessionState;
1955 }
1956
1957 uint64_t WebPageProxy::restoreFromSessionState(SessionState sessionState, bool navigate)
1958 {
1959     m_sessionRestorationRenderTreeSize = 0;
1960     m_hitRenderTreeSizeThreshold = false;
1961
1962     bool hasBackForwardList = !!sessionState.backForwardListState.currentIndex;
1963
1964     if (hasBackForwardList) {
1965         m_backForwardList->restoreFromState(WTF::move(sessionState.backForwardListState));
1966
1967         for (const auto& entry : m_backForwardList->entries())
1968             process().registerNewWebBackForwardListItem(entry.get());
1969
1970         process().send(Messages::WebPage::RestoreSession(m_backForwardList->itemStates()), m_pageID);
1971     }
1972
1973     // FIXME: Navigating should be separate from state restoration.
1974     if (navigate) {
1975         m_sessionRestorationRenderTreeSize = sessionState.renderTreeSize;
1976         if (!m_sessionRestorationRenderTreeSize)
1977             m_hitRenderTreeSizeThreshold = true; // If we didn't get data on renderTreeSize, just don't fire the milestone.
1978
1979         if (!sessionState.provisionalURL.isNull())
1980             return loadRequest(sessionState.provisionalURL);
1981
1982         if (hasBackForwardList) {
1983             // FIXME: Do we have to null check the back forward list item here?
1984             if (WebBackForwardListItem* item = m_backForwardList->currentItem())
1985                 return goToBackForwardItem(item);
1986         }
1987     }
1988
1989     return 0;
1990 }
1991
1992 bool WebPageProxy::supportsTextZoom() const
1993 {
1994     // FIXME (118840): This should also return false for standalone media and plug-in documents.
1995     if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
1996         return false;
1997
1998     return true;
1999 }
2000  
2001 void WebPageProxy::setTextZoomFactor(double zoomFactor)
2002 {
2003     if (!isValid())
2004         return;
2005
2006     if (m_textZoomFactor == zoomFactor)
2007         return;
2008
2009     m_textZoomFactor = zoomFactor;
2010     m_process->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID); 
2011 }
2012
2013 void WebPageProxy::setPageZoomFactor(double zoomFactor)
2014 {
2015     if (!isValid())
2016         return;
2017
2018     if (m_pageZoomFactor == zoomFactor)
2019         return;
2020
2021     m_pageZoomFactor = zoomFactor;
2022     m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 
2023 }
2024
2025 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
2026 {
2027     if (!isValid())
2028         return;
2029
2030     if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
2031         return;
2032
2033     m_pageZoomFactor = pageZoomFactor;
2034     m_textZoomFactor = textZoomFactor;
2035     m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); 
2036 }
2037
2038 void WebPageProxy::scalePage(double scale, const IntPoint& origin)
2039 {
2040     if (!isValid())
2041         return;
2042
2043     m_pageScaleFactor = scale;
2044     m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID);
2045 }
2046
2047 void WebPageProxy::scalePageInViewCoordinates(double scale, const IntPoint& centerInViewCoordinates)
2048 {
2049     if (!isValid())
2050         return;
2051
2052     m_pageScaleFactor = scale;
2053     m_process->send(Messages::WebPage::ScalePageInViewCoordinates(scale, centerInViewCoordinates), m_pageID);
2054 }
2055
2056 void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor)
2057 {
2058     if (m_intrinsicDeviceScaleFactor == scaleFactor)
2059         return;
2060
2061     m_intrinsicDeviceScaleFactor = scaleFactor;
2062
2063     if (m_drawingArea)
2064         m_drawingArea->deviceScaleFactorDidChange();
2065 }
2066
2067 void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID)
2068 {
2069     if (!isValid())
2070         return;
2071
2072     m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID);
2073 }
2074
2075 float WebPageProxy::deviceScaleFactor() const
2076 {
2077     if (m_customDeviceScaleFactor)
2078         return m_customDeviceScaleFactor;
2079     return m_intrinsicDeviceScaleFactor;
2080 }
2081
2082 void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor)
2083 {
2084     if (!isValid())
2085         return;
2086
2087     // FIXME: Remove this once we bump cairo requirements to support HiDPI.
2088     // https://bugs.webkit.org/show_bug.cgi?id=133378
2089 #if USE(CAIRO) && !HAVE(CAIRO_SURFACE_SET_DEVICE_SCALE)
2090     return;
2091 #endif
2092
2093     if (m_customDeviceScaleFactor == customScaleFactor)
2094         return;
2095
2096     float oldScaleFactor = deviceScaleFactor();
2097
2098     m_customDeviceScaleFactor = customScaleFactor;
2099
2100     if (deviceScaleFactor() != oldScaleFactor)
2101         m_drawingArea->deviceScaleFactorDidChange();
2102 }
2103
2104 void WebPageProxy::setUseFixedLayout(bool fixed)
2105 {
2106     if (!isValid())
2107         return;
2108
2109     // This check is fine as the value is initialized in the web
2110     // process as part of the creation parameters.
2111     if (fixed == m_useFixedLayout)
2112         return;
2113
2114     m_useFixedLayout = fixed;
2115     if (!fixed)
2116         m_fixedLayoutSize = IntSize();
2117     m_process->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
2118 }
2119
2120 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
2121 {
2122     if (!isValid())
2123         return;
2124
2125     if (size == m_fixedLayoutSize)
2126         return;
2127
2128     m_fixedLayoutSize = size;
2129     m_process->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
2130 }
2131
2132 void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestones)
2133 {
2134     if (!isValid())
2135         return;
2136     
2137     m_wantsSessionRestorationRenderTreeSizeThresholdEvent = milestones & WebCore::ReachedSessionRestorationRenderTreeSizeThreshold;
2138
2139     m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
2140 }
2141
2142 void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations)
2143 {
2144     if (!isValid())
2145         return;
2146
2147     if (suppressAnimations == m_suppressScrollbarAnimations)
2148         return;
2149
2150     m_suppressScrollbarAnimations = suppressAnimations;
2151     m_process->send(Messages::WebPage::SetSuppressScrollbarAnimations(suppressAnimations), m_pageID);
2152 }
2153
2154 bool WebPageProxy::rubberBandsAtLeft() const
2155 {
2156     return m_rubberBandsAtLeft;
2157 }
2158
2159 void WebPageProxy::setRubberBandsAtLeft(bool rubberBandsAtLeft)
2160 {
2161     m_rubberBandsAtLeft = rubberBandsAtLeft;
2162 }
2163
2164 bool WebPageProxy::rubberBandsAtRight() const
2165 {
2166     return m_rubberBandsAtRight;
2167 }
2168
2169 void WebPageProxy::setRubberBandsAtRight(bool rubberBandsAtRight)
2170 {
2171     m_rubberBandsAtRight = rubberBandsAtRight;
2172 }
2173
2174 bool WebPageProxy::rubberBandsAtTop() const
2175 {
2176     return m_rubberBandsAtTop;
2177 }
2178
2179 void WebPageProxy::setRubberBandsAtTop(bool rubberBandsAtTop)
2180 {
2181     m_rubberBandsAtTop = rubberBandsAtTop;
2182 }
2183
2184 bool WebPageProxy::rubberBandsAtBottom() const
2185 {
2186     return m_rubberBandsAtBottom;
2187 }
2188
2189 void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom)
2190 {
2191     m_rubberBandsAtBottom = rubberBandsAtBottom;
2192 }
2193     
2194 void WebPageProxy::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
2195 {
2196     if (enableVerticalRubberBanding == m_enableVerticalRubberBanding)
2197         return;
2198
2199     m_enableVerticalRubberBanding = enableVerticalRubberBanding;
2200
2201     if (!isValid())
2202         return;
2203     m_process->send(Messages::WebPage::SetEnableVerticalRubberBanding(enableVerticalRubberBanding), m_pageID);
2204 }
2205     
2206 bool WebPageProxy::verticalRubberBandingIsEnabled() const
2207 {
2208     return m_enableVerticalRubberBanding;
2209 }
2210     
2211 void WebPageProxy::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
2212 {
2213     if (enableHorizontalRubberBanding == m_enableHorizontalRubberBanding)
2214         return;
2215
2216     m_enableHorizontalRubberBanding = enableHorizontalRubberBanding;
2217
2218     if (!isValid())
2219         return;
2220     m_process->send(Messages::WebPage::SetEnableHorizontalRubberBanding(enableHorizontalRubberBanding), m_pageID);
2221 }
2222     
2223 bool WebPageProxy::horizontalRubberBandingIsEnabled() const
2224 {
2225     return m_enableHorizontalRubberBanding;
2226 }
2227
2228 void WebPageProxy::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
2229 {
2230     if (backgroundExtendsBeyondPage == m_backgroundExtendsBeyondPage)
2231         return;
2232
2233     m_backgroundExtendsBeyondPage = backgroundExtendsBeyondPage;
2234
2235     if (!isValid())
2236         return;
2237     m_process->send(Messages::WebPage::SetBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage), m_pageID);
2238 }
2239
2240 bool WebPageProxy::backgroundExtendsBeyondPage() const
2241 {
2242     return m_backgroundExtendsBeyondPage;
2243 }
2244
2245 void WebPageProxy::setPaginationMode(WebCore::Pagination::Mode mode)
2246 {
2247     if (mode == m_paginationMode)
2248         return;
2249
2250     m_paginationMode = mode;
2251
2252     if (!isValid())
2253         return;
2254     m_process->send(Messages::WebPage::SetPaginationMode(mode), m_pageID);
2255 }
2256
2257 void WebPageProxy::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
2258 {
2259     if (behavesLikeColumns == m_paginationBehavesLikeColumns)
2260         return;
2261
2262     m_paginationBehavesLikeColumns = behavesLikeColumns;
2263
2264     if (!isValid())
2265         return;
2266     m_process->send(Messages::WebPage::SetPaginationBehavesLikeColumns(behavesLikeColumns), m_pageID);
2267 }
2268
2269 void WebPageProxy::setPageLength(double pageLength)
2270 {
2271     if (pageLength == m_pageLength)
2272         return;
2273
2274     m_pageLength = pageLength;
2275
2276     if (!isValid())
2277         return;
2278     m_process->send(Messages::WebPage::SetPageLength(pageLength), m_pageID);
2279 }
2280
2281 void WebPageProxy::setGapBetweenPages(double gap)
2282 {
2283     if (gap == m_gapBetweenPages)
2284         return;
2285
2286     m_gapBetweenPages = gap;
2287
2288     if (!isValid())
2289         return;
2290     m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID);
2291 }
2292
2293 void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
2294 {
2295     m_pageScaleFactor = scaleFactor;
2296 }
2297
2298 void WebPageProxy::pageZoomFactorDidChange(double zoomFactor)
2299 {
2300     m_pageZoomFactor = zoomFactor;
2301 }
2302
2303 void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2304 {
2305     if (string.isEmpty()) {
2306         didFindStringMatches(string, Vector<Vector<WebCore::IntRect>> (), 0);
2307         return;
2308     }
2309
2310     m_process->send(Messages::WebPage::FindStringMatches(string, options, maxMatchCount), m_pageID);
2311 }
2312
2313 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
2314 {
2315     m_process->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
2316 }
2317
2318 void WebPageProxy::getImageForFindMatch(int32_t matchIndex)
2319 {
2320     m_process->send(Messages::WebPage::GetImageForFindMatch(matchIndex), m_pageID);
2321 }
2322
2323 void WebPageProxy::selectFindMatch(int32_t matchIndex)
2324 {
2325     m_process->send(Messages::WebPage::SelectFindMatch(matchIndex), m_pageID);
2326 }
2327
2328 void WebPageProxy::hideFindUI()
2329 {
2330     m_process->send(Messages::WebPage::HideFindUI(), m_pageID);
2331 }
2332
2333 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
2334 {
2335     if (!isValid())
2336         return;
2337
2338     m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
2339 }
2340
2341 void WebPageProxy::runJavaScriptInMainFrame(const String& script, std::function<void (API::SerializedScriptValue*, CallbackBase::Error)> callbackFunction)
2342 {
2343     if (!isValid()) {
2344         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2345         return;
2346     }
2347
2348     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2349     m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
2350 }
2351
2352 void WebPageProxy::getRenderTreeExternalRepresentation(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2353 {
2354     if (!isValid()) {
2355         callbackFunction(String(), CallbackBase::Error::Unknown);
2356         return;
2357     }
2358     
2359     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2360     m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
2361 }
2362
2363 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2364 {
2365     if (!isValid()) {
2366         callbackFunction(String(), CallbackBase::Error::Unknown);
2367         return;
2368     }
2369     
2370     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2371     m_loadDependentStringCallbackIDs.add(callbackID);
2372     m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
2373 }
2374
2375 void WebPageProxy::getContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2376 {
2377     if (!isValid()) {
2378         callbackFunction(String(), CallbackBase::Error::Unknown);
2379         return;
2380     }
2381     
2382     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2383     m_loadDependentStringCallbackIDs.add(callbackID);
2384     m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
2385 }
2386
2387 void WebPageProxy::getBytecodeProfile(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2388 {
2389     if (!isValid()) {
2390         callbackFunction(String(), CallbackBase::Error::Unknown);
2391         return;
2392     }
2393     
2394     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2395     m_loadDependentStringCallbackIDs.add(callbackID);
2396     m_process->send(Messages::WebPage::GetBytecodeProfile(callbackID), m_pageID);
2397 }
2398     
2399 #if ENABLE(MHTML)
2400 void WebPageProxy::getContentsAsMHTMLData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction, bool useBinaryEncoding)
2401 {
2402     if (!isValid()) {
2403         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2404         return;
2405     }
2406
2407     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2408     m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID);
2409 }
2410 #endif
2411
2412 void WebPageProxy::getSelectionOrContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction)
2413 {
2414     if (!isValid()) {
2415         callbackFunction(String(), CallbackBase::Error::Unknown);
2416         return;
2417     }
2418     
2419     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2420     m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
2421 }
2422
2423 void WebPageProxy::getSelectionAsWebArchiveData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2424 {
2425     if (!isValid()) {
2426         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2427         return;
2428     }
2429     
2430     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2431     m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID);
2432 }
2433
2434 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2435 {
2436     if (!isValid() || !frame) {
2437         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2438         return;
2439     }
2440     
2441     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2442     m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
2443 }
2444
2445 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2446 {
2447     if (!isValid()) {
2448         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2449         return;
2450     }
2451     
2452     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2453     m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
2454 }
2455
2456 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction)
2457 {
2458     if (!isValid()) {
2459         callbackFunction(nullptr, CallbackBase::Error::Unknown);
2460         return;
2461     }
2462     
2463     uint64_t callbackID = m_callbacks.put(WTF::move(callbackFunction), m_process->throttler().backgroundActivityToken());
2464     m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
2465 }
2466
2467 void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback)
2468 {
2469     RefPtr<VoidCallback> callback = prpCallback;
2470     if (!isValid()) {
2471         // FIXME: If the page is invalid we should not call the callback. It'd be better to just return false from forceRepaint.
2472         callback->invalidate(CallbackBase::Error::OwnerWasInvalidated);
2473         return;
2474     }
2475
2476     uint64_t callbackID = callback->callbackID();
2477     m_callbacks.put(callback);
2478     m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
2479     m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID); 
2480 }
2481
2482 void WebPageProxy::preferencesDidChange()
2483 {
2484     if (!isValid())
2485         return;
2486
2487 #if ENABLE(INSPECTOR_SERVER)
2488     if (m_preferences->developerExtrasEnabled())
2489         inspector()->enableRemoteInspection();
2490 #endif
2491
2492     updateProccessSuppressionState();
2493
2494     m_pageClient.preferencesDidChange();
2495
2496     // FIXME: It probably makes more sense to send individual preference changes.
2497     // However, WebKitTestRunner depends on getting a preference change notification
2498     // even if nothing changed in UI process, so that overrides get removed.
2499
2500     // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
2501     m_process->send(Messages::WebPage::PreferencesDidChange(preferencesStore()), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2502 }
2503
2504 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
2505 {
2506     MESSAGE_CHECK(!m_mainFrame);
2507     MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2508
2509     m_mainFrame = WebFrameProxy::create(this, frameID);
2510
2511     // Add the frame to the process wide map.
2512     m_process->frameCreated(frameID, m_mainFrame.get());
2513 }
2514
2515 void WebPageProxy::didCreateSubframe(uint64_t frameID)
2516 {
2517     MESSAGE_CHECK(m_mainFrame);
2518     MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2519     
2520     RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
2521
2522     // Add the frame to the process wide map.
2523     m_process->frameCreated(frameID, subFrame.get());
2524 }
2525
2526 double WebPageProxy::estimatedProgress() const
2527 {
2528     return m_pageLoadState.estimatedProgress();
2529 }
2530
2531 void WebPageProxy::didStartProgress()
2532 {
2533     auto transaction = m_pageLoadState.transaction();
2534     m_pageLoadState.didStartProgress(transaction);
2535
2536     m_pageLoadState.commitChanges();
2537     m_loaderClient->didStartProgress(this);
2538 }
2539
2540 void WebPageProxy::didChangeProgress(double value)
2541 {
2542     auto transaction = m_pageLoadState.transaction();
2543     m_pageLoadState.didChangeProgress(transaction, value);
2544
2545     m_pageLoadState.commitChanges();
2546     m_loaderClient->didChangeProgress(this);
2547 }
2548
2549 void WebPageProxy::didFinishProgress()
2550 {
2551     auto transaction = m_pageLoadState.transaction();
2552     m_pageLoadState.didFinishProgress(transaction);
2553
2554     m_pageLoadState.commitChanges();
2555     m_loaderClient->didFinishProgress(this);
2556 }
2557
2558 void WebPageProxy::setNetworkRequestsInProgress(bool networkRequestsInProgress)
2559 {
2560     auto transaction = m_pageLoadState.transaction();
2561     m_pageLoadState.setNetworkRequestsInProgress(transaction, networkRequestsInProgress);
2562 }
2563
2564 void WebPageProxy::didDestroyNavigation(uint64_t navigationID)
2565 {
2566     m_loaderClient->didDestroyNavigation(this, navigationID);
2567 }
2568
2569 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, const UserData& userData)
2570 {
2571     auto transaction = m_pageLoadState.transaction();
2572
2573     m_pageLoadState.clearPendingAPIRequestURL(transaction);
2574
2575     WebFrameProxy* frame = m_process->webFrame(frameID);
2576     MESSAGE_CHECK(frame);
2577     MESSAGE_CHECK_URL(url);
2578
2579     if (frame->isMainFrame())
2580         m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL);
2581
2582     frame->setUnreachableURL(unreachableURL);
2583     frame->didStartProvisionalLoad(url);
2584
2585     m_pageLoadState.commitChanges();
2586     m_loaderClient->didStartProvisionalLoadForFrame(this, frame, navigationID, m_process->transformHandlesToObjects(userData.object()).get());
2587 }
2588
2589 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const UserData& userData)
2590 {
2591     WebFrameProxy* frame = m_process->webFrame(frameID);
2592     MESSAGE_CHECK(frame);
2593     MESSAGE_CHECK_URL(url);
2594
2595     auto transaction = m_pageLoadState.transaction();
2596
2597     if (frame->isMainFrame())
2598         m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url);
2599
2600     frame->didReceiveServerRedirectForProvisionalLoad(url);
2601
2602     m_pageLoadState.commitChanges();
2603     m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, navigationID, m_process->transformHandlesToObjects(userData.object()).get());
2604 }
2605
2606 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, const UserData& userData)
2607 {
2608     WebFrameProxy* frame = m_process->webFrame(frameID);
2609     MESSAGE_CHECK(frame);
2610
2611     auto transaction = m_pageLoadState.transaction();
2612
2613     if (frame->isMainFrame())
2614         m_pageLoadState.didFailProvisionalLoad(transaction);
2615
2616     frame->didFailProvisionalLoad();
2617
2618     m_pageLoadState.commitChanges();
2619     m_loaderClient->didFailProvisionalLoadWithErrorForFrame(this, frame, navigationID, error, m_process->transformHandlesToObjects(userData.object()).get());
2620 }
2621
2622 void WebPageProxy::clearLoadDependentCallbacks()
2623 {
2624     Vector<uint64_t> callbackIDsCopy;
2625     copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy);
2626     m_loadDependentStringCallbackIDs.clear();
2627
2628     for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
2629         auto callback = m_callbacks.take<StringCallback>(callbackIDsCopy[i]);
2630         if (callback)
2631             callback->invalidate();
2632     }
2633 }
2634
2635 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, const UserData& userData)
2636 {
2637     WebFrameProxy* frame = m_process->webFrame(frameID);
2638     MESSAGE_CHECK(frame);
2639
2640 #if PLATFORM(IOS)
2641     if (frame->isMainFrame()) {
2642         m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = false;
2643         m_firstLayerTreeTransactionIdAfterDidCommitLoad = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).nextLayerTreeTransactionID();
2644     }
2645 #endif
2646
2647     auto transaction = m_pageLoadState.transaction();
2648
2649     if (frame->isMainFrame())
2650         m_pageLoadState.didCommitLoad(transaction);
2651
2652 #if USE(APPKIT)
2653     // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
2654     // FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page.
2655     m_pageClient.resetSecureInputState();
2656     m_pageClient.dismissContentRelativeChildWindows();
2657 #endif
2658
2659     clearLoadDependentCallbacks();
2660
2661     frame->didCommitLoad(mimeType, certificateInfo);
2662
2663     if (frame->isMainFrame()) {
2664         m_mainFrameHasCustomContentProvider = frameHasCustomContentProvider;
2665
2666         if (m_mainFrameHasCustomContentProvider) {
2667             // Always assume that the main frame is pinned here, since the custom representation view will handle
2668             // any wheel events and dispatch them to the WKView when necessary.
2669             m_mainFrameIsPinnedToLeftSide = true;
2670             m_mainFrameIsPinnedToRightSide = true;
2671             m_mainFrameIsPinnedToTopSide = true;
2672             m_mainFrameIsPinnedToBottomSide = true;
2673
2674             m_uiClient->pinnedStateDidChange(*this);
2675         }
2676         m_pageClient.didCommitLoadForMainFrame(mimeType, frameHasCustomContentProvider);
2677     }
2678
2679     // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it),
2680     // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a
2681     // plugin is handling page scaling itself) so we should reset it to the default
2682     // for standard main frame loads.
2683     if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadType::Standard)
2684         m_pageScaleFactor = 1;
2685
2686     m_pageLoadState.commitChanges();
2687     m_loaderClient->didCommitLoadForFrame(this, frame, navigationID, m_process->transformHandlesToObjects(userData.object()).get());
2688 }
2689
2690 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
2691 {
2692     WebFrameProxy* frame = m_process->webFrame(frameID);
2693     MESSAGE_CHECK(frame);
2694
2695     m_loaderClient->didFinishDocumentLoadForFrame(this, frame, navigationID, m_process->transformHandlesToObjects(userData.object()).get());
2696 }
2697
2698 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData)
2699 {
2700     WebFrameProxy* frame = m_process->webFrame(frameID);
2701     MESSAGE_CHECK(frame);
2702
2703     auto transaction = m_pageLoadState.transaction();
2704
2705     bool isMainFrame = frame->isMainFrame();
2706     if (isMainFrame)
2707         m_pageLoadState.didFinishLoad(transaction);
2708
2709     frame->didFinishLoad();
2710
2711     m_pageLoadState.commitChanges();
2712     m_loaderClient->didFinishLoadForFrame(this, frame, navigationID, m_process->transformHandlesToObjects(userData.object()).get());
2713
2714     if (isMainFrame)
2715         m_pageClient.didFinishLoadForMainFrame();
2716 }
2717
2718 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, const UserData& userData)
2719 {
2720     WebFrameProxy* frame = m_process->webFrame(frameID);
2721     MESSAGE_CHECK(frame);
2722
2723     clearLoadDependentCallbacks();
2724
2725     auto transaction = m_pageLoadState.transaction();
2726
2727     if (frame->isMainFrame())
2728         m_pageLoadState.didFailLoad(transaction);
2729
2730     frame->didFailLoad();
2731
2732     m_pageLoadState.commitChanges();
2733     m_loaderClient->didFailLoadWithErrorForFrame(this, frame, navigationID, error, m_process->transformHandlesToObjects(userData.object()).get());
2734 }
2735
2736 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t opaqueSameDocumentNavigationType, const String& url, const UserData& userData)
2737 {
2738     WebFrameProxy* frame = m_process->webFrame(frameID);
2739     MESSAGE_CHECK(frame);
2740     MESSAGE_CHECK_URL(url);
2741
2742     auto transaction = m_pageLoadState.transaction();
2743
2744     bool isMainFrame = frame->isMainFrame();
2745     if (isMainFrame)
2746         m_pageLoadState.didSameDocumentNavigation(transaction, url);
2747
2748     m_pageLoadState.clearPendingAPIRequestURL(transaction);
2749     frame->didSameDocumentNavigation(url);
2750
2751     m_pageLoadState.commitChanges();
2752
2753     SameDocumentNavigationType navigationType = static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType);
2754     m_loaderClient->didSameDocumentNavigationForFrame(this, frame, navigationID, navigationType, m_process->transformHandlesToObjects(userData.object()).get());
2755
2756     if (isMainFrame)
2757         m_pageClient.didSameDocumentNavigationForMainFrame(navigationType);
2758 }
2759
2760 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, const UserData& userData)
2761 {
2762     WebFrameProxy* frame = m_process->webFrame(frameID);
2763     MESSAGE_CHECK(frame);
2764
2765     auto transaction = m_pageLoadState.transaction();
2766
2767     if (frame->isMainFrame())
2768         m_pageLoadState.setTitle(transaction, title);
2769
2770     frame->didChangeTitle(title);
2771     
2772     m_pageLoadState.commitChanges();
2773     m_loaderClient->didReceiveTitleForFrame(this, title, frame, m_process->transformHandlesToObjects(userData.object()).get());
2774 }
2775
2776 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, const UserData& userData)
2777 {
2778     WebFrameProxy* frame = m_process->webFrame(frameID);
2779     MESSAGE_CHECK(frame);
2780
2781     m_loaderClient->didFirstLayoutForFrame(this, frame, m_process->transformHandlesToObjects(userData.object()).get());
2782 }
2783
2784 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, const UserData& userData)
2785 {
2786     WebFrameProxy* frame = m_process->webFrame(frameID);
2787     MESSAGE_CHECK(frame);
2788
2789     m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(this, frame, m_process->transformHandlesToObjects(userData.object()).get());
2790
2791     if (frame->isMainFrame())
2792         m_pageClient.didFirstVisuallyNonEmptyLayoutForMainFrame();
2793 }
2794
2795 void WebPageProxy::didLayout(uint32_t layoutMilestones, const UserData& userData)
2796 {
2797     m_loaderClient->didLayout(this, static_cast<LayoutMilestones>(layoutMilestones), m_process->transformHandlesToObjects(userData.object()).get());
2798 }
2799
2800 void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, const UserData& userData)
2801 {
2802     WebFrameProxy* frame = m_process->webFrame(frameID);
2803     MESSAGE_CHECK(frame);
2804
2805     m_loaderClient->didRemoveFrameFromHierarchy(this, frame, m_process->transformHandlesToObjects(userData.object()).get());
2806 }
2807
2808 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, const UserData& userData)
2809 {
2810     WebFrameProxy* frame = m_process->webFrame(frameID);
2811     MESSAGE_CHECK(frame);
2812
2813     auto transaction = m_pageLoadState.transaction();
2814     m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
2815
2816     m_pageLoadState.commitChanges();
2817     m_loaderClient->didDisplayInsecureContentForFrame(this, frame, m_process->transformHandlesToObjects(userData.object()).get());
2818 }
2819
2820 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, const UserData& userData)
2821 {
2822     WebFrameProxy* frame = m_process->webFrame(frameID);
2823     MESSAGE_CHECK(frame);
2824
2825     auto transaction = m_pageLoadState.transaction();
2826     m_pageLoadState.didDisplayOrRunInsecureContent(transaction);
2827
2828     m_pageLoadState.commitChanges();
2829     m_loaderClient->didRunInsecureContentForFrame(this, frame, m_process->transformHandlesToObjects(userData.object()).get());
2830 }
2831
2832 void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, const UserData& userData)
2833 {
2834     WebFrameProxy* frame = m_process->webFrame(frameID);
2835     MESSAGE_CHECK(frame);
2836
2837     m_loaderClient->didDetectXSSForFrame(this, frame, m_process->transformHandlesToObjects(userData.object()).get());
2838 }
2839
2840 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
2841 {
2842     WebFrameProxy* frame = m_process->webFrame(frameID);
2843     MESSAGE_CHECK(frame);
2844
2845     frame->setIsFrameSet(value);
2846     if (frame->isMainFrame())
2847         m_frameSetLargestFrame = value ? m_mainFrame : 0;
2848 }
2849
2850 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, uint64_t navigationID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& newNavigationID, uint64_t& policyAction, uint64_t& downloadID)
2851 {
2852     auto transaction = m_pageLoadState.transaction();
2853
2854     if (request.url() != m_pageLoadState.pendingAPIRequestURL())
2855         m_pageLoadState.clearPendingAPIRequestURL(transaction);
2856
2857     WebFrameProxy* frame = m_process->webFrame(frameID);
2858     MESSAGE_CHECK(frame);
2859     MESSAGE_CHECK_URL(request.url());
2860     MESSAGE_CHECK_URL(originalRequest.url());
2861
2862     WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameID);
2863     
2864     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2865     if (!navigationID && frame->isMainFrame()) {
2866         newNavigationID = generateNavigationID();
2867         listener->setNavigationID(newNavigationID);
2868     }
2869
2870 #if ENABLE(CONTENT_FILTERING)
2871     if (frame->contentFilterDidHandleNavigationAction(request)) {
2872         receivedPolicyAction = true;
2873         policyAction = PolicyIgnore;
2874         return;
2875     }
2876 #endif
2877
2878     ASSERT(!m_inDecidePolicyForNavigationAction);
2879
2880     m_inDecidePolicyForNavigationAction = true;
2881     m_syncNavigationActionPolicyActionIsValid = false;
2882
2883     m_policyClient->decidePolicyForNavigationAction(this, frame, navigationActionData, originatingFrame, originalRequest, request, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
2884
2885     m_inDecidePolicyForNavigationAction = false;
2886
2887     // Check if we received a policy decision already. If we did, we can just pass it back.
2888     receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
2889     if (m_syncNavigationActionPolicyActionIsValid) {
2890         policyAction = m_syncNavigationActionPolicyAction;
2891         downloadID = m_syncNavigationActionPolicyDownloadID;
2892     }
2893 }
2894
2895 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, const UserData& userData)
2896 {
2897     WebFrameProxy* frame = m_process->webFrame(frameID);
2898     MESSAGE_CHECK(frame);
2899     MESSAGE_CHECK_URL(request.url());
2900
2901     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2902
2903     m_policyClient->decidePolicyForNewWindowAction(this, frame, navigationActionData, request, frameName, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
2904 }
2905
2906 void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData)
2907 {
2908     WebFrameProxy* frame = m_process->webFrame(frameID);
2909     MESSAGE_CHECK(frame);
2910     MESSAGE_CHECK_URL(request.url());
2911     MESSAGE_CHECK_URL(response.url());
2912
2913     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2914
2915     m_policyClient->decidePolicyForResponse(this, frame, response, request, canShowMIMEType, WTF::move(listener), m_process->transformHandlesToObjects(userData.object()).get());
2916 }
2917
2918 void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
2919 {
2920     ASSERT(!m_inDecidePolicyForResponseSync);
2921
2922     m_inDecidePolicyForResponseSync = true;
2923     m_decidePolicyForResponseRequest = &request;
2924     m_syncMimeTypePolicyActionIsValid = false;
2925
2926     decidePolicyForResponse(frameID, response, request, canShowMIMEType, listenerID, userData);
2927
2928     m_inDecidePolicyForResponseSync = false;
2929     m_decidePolicyForResponseRequest = 0;
2930
2931     // Check if we received a policy decision already. If we did, we can just pass it back.
2932     receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
2933     if (m_syncMimeTypePolicyActionIsValid) {
2934         policyAction = m_syncMimeTypePolicyAction;
2935         downloadID = m_syncMimeTypePolicyDownloadID;
2936     }
2937 }
2938
2939 void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, const UserData& userData)
2940 {
2941     WebFrameProxy* frame = m_process->webFrame(frameID);
2942     MESSAGE_CHECK(frame);
2943
2944     m_policyClient->unableToImplementPolicy(this, frame, error, m_process->transformHandlesToObjects(userData.object()).get());
2945 }
2946
2947 // FormClient
2948
2949 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, const UserData& userData)
2950 {
2951     WebFrameProxy* frame = m_process->webFrame(frameID);
2952     MESSAGE_CHECK(frame);
2953
2954     WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID);
2955     MESSAGE_CHECK(sourceFrame);
2956
2957     RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
2958     if (!m_formClient->willSubmitForm(this, frame, sourceFrame, textFieldValues, m_process->transformHandlesToObjects(userData.object()).get(), listener.get()))
2959         listener->continueSubmission();
2960 }
2961
2962 void WebPageProxy::didNavigateWithNavigationData(const WebNavigationDataStore& store, uint64_t frameID) 
2963 {
2964     WebFrameProxy* frame = m_process->webFrame(frameID);
2965     MESSAGE_CHECK(frame);
2966     MESSAGE_CHECK(frame->page() == this);
2967
2968     m_loaderClient->didNavigateWithNavigationData(*this, store, *frame);
2969     process().processPool().historyClient().didNavigateWithNavigationData(process().processPool(), *this, store, *frame);
2970 }
2971
2972 void WebPageProxy::didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
2973 {
2974     if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
2975         return;
2976     
2977     WebFrameProxy* frame = m_process->webFrame(frameID);
2978     MESSAGE_CHECK(frame);
2979     MESSAGE_CHECK(frame->page() == this);
2980
2981     MESSAGE_CHECK_URL(sourceURLString);
2982     MESSAGE_CHECK_URL(destinationURLString);
2983
2984     m_loaderClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString, *frame);
2985     process().processPool().historyClient().didPerformClientRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
2986 }
2987
2988 void WebPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
2989 {
2990     if (sourceURLString.isEmpty() || destinationURLString.isEmpty())
2991         return;
2992     
2993     WebFrameProxy* frame = m_process->webFrame(frameID);
2994     MESSAGE_CHECK(frame);
2995     MESSAGE_CHECK(frame->page() == this);
2996
2997     MESSAGE_CHECK_URL(sourceURLString);
2998     MESSAGE_CHECK_URL(destinationURLString);
2999
3000     m_loaderClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString, *frame);
3001     process().processPool().historyClient().didPerformServerRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame);
3002 }
3003
3004 void WebPageProxy::didUpdateHistoryTitle(const String& title, const String& url, uint64_t frameID)
3005 {
3006     WebFrameProxy* frame = m_process->webFrame(frameID);
3007     MESSAGE_CHECK(frame);
3008     MESSAGE_CHECK(frame->page() == this);
3009
3010     MESSAGE_CHECK_URL(url);
3011
3012     m_loaderClient->didUpdateHistoryTitle(*this, title, url, *frame);
3013     process().processPool().historyClient().didUpdateHistoryTitle(process().processPool(), *this, title, url, *frame);
3014 }
3015
3016 // UIClient
3017
3018 void WebPageProxy::createNewPage(uint64_t frameID, const ResourceRequest& request, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
3019 {
3020     WebFrameProxy* frame = m_process->webFrame(frameID);
3021     MESSAGE_CHECK(frame);
3022
3023     RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, frame, request, windowFeatures, navigationActionData);
3024     if (!newPage) {
3025         newPageID = 0;
3026         return;
3027     }
3028
3029     newPageID = newPage->pageID();
3030     newPageParameters = newPage->creationParameters();
3031     process().processPool().storageManager().cloneSessionStorageNamespace(m_pageID, newPage->pageID());
3032 }
3033     
3034 void WebPageProxy::showPage()
3035 {
3036     m_uiClient->showPage(this);
3037 }
3038
3039 void WebPageProxy::fullscreenMayReturnToInline()
3040 {
3041     m_uiClient->fullscreenMayReturnToInline(this);
3042 }
3043
3044 void WebPageProxy::didEnterFullscreen()
3045 {
3046     m_uiClient->didEnterFullscreen(this);
3047 }
3048
3049 void WebPageProxy::didExitFullscreen()
3050 {
3051     m_uiClient->didExitFullscreen(this);
3052 }
3053
3054 void WebPageProxy::closePage(bool stopResponsivenessTimer)
3055 {
3056     if (stopResponsivenessTimer)
3057         m_process->responsivenessTimer()->stop();
3058
3059     m_pageClient.clearAllEditCommands();
3060     m_uiClient->close(this);
3061 }
3062
3063 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply> reply)
3064 {
3065     WebFrameProxy* frame = m_process->webFrame(frameID);
3066     MESSAGE_CHECK(frame);
3067
3068     // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
3069     m_process->responsivenessTimer()->stop();
3070
3071     m_uiClient->runJavaScriptAlert(this, message, frame, [reply]{ reply->send(); });
3072 }
3073
3074 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, RefPtr<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply> reply)
3075 {
3076     WebFrameProxy* frame = m_process->webFrame(frameID);
3077     MESSAGE_CHECK(frame);
3078
3079     // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
3080     m_process->responsivenessTimer()->stop();
3081
3082     m_uiClient->runJavaScriptConfirm(this, message, frame, [reply](bool result) { reply->send(result); });
3083 }
3084
3085 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, RefPtr<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply> reply)
3086 {
3087     WebFrameProxy* frame = m_process->webFrame(frameID);
3088     MESSAGE_CHECK(frame);
3089
3090     // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
3091     m_process->responsivenessTimer()->stop();
3092
3093     m_uiClient->runJavaScriptPrompt(this, message, defaultValue, frame, [reply](const String& result) { reply->send(result); });
3094 }
3095
3096 void WebPageProxy::shouldInterruptJavaScript(bool& result)
3097 {
3098     // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer.
3099     m_process->responsivenessTimer()->stop();
3100
3101     result = m_uiClient->shouldInterruptJavaScript(this);
3102 }
3103
3104 void WebPageProxy::setStatusText(const String& text)
3105 {
3106     m_uiClient->setStatusText(this, text);
3107 }
3108
3109 void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t opaqueModifiers, const UserData& userData)
3110 {
3111     m_lastMouseMoveHitTestResult = WebHitTestResult::create(hitTestResultData);
3112
3113     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
3114
3115     m_uiClient->mouseDidMoveOverElement(this, hitTestResultData, modifiers, m_process->transformHandlesToObjects(userData.object()).get());
3116 }
3117
3118 void WebPageProxy::didBeginTrackingPotentialLongMousePress(const IntPoint& mouseDownPosition, const WebHitTestResult::Data& hitTestResultData, const UserData& userData)
3119 {
3120     m_uiClient->didBeginTrackingPotentialLongMousePress(this, mouseDownPosition, hitTestResultData, m_process->transformHandlesToObjects(userData.object()).get());
3121 }
3122
3123 void WebPageProxy::didRecognizeLongMousePress(const UserData& userData)
3124 {
3125     m_uiClient->didRecognizeLongMousePress(this, m_process->transformHandlesToObjects(userData.object()).get());
3126 }
3127
3128 void WebPageProxy::didCancelTrackingPotentialLongMousePress(const UserData& userData)
3129 {
3130     m_uiClient->didCancelTrackingPotentialLongMousePress(this, m_process->transformHandlesToObjects(userData.object()).get());
3131 }
3132
3133 void WebPageProxy::connectionWillOpen(IPC::Connection* connection)
3134 {
3135     ASSERT(connection == m_process->connection());
3136
3137     m_process->processPool().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, connection);
3138 }
3139
3140 void WebPageProxy::connectionWillClose(IPC::Connection* connection)
3141 {
3142     ASSERT_UNUSED(connection, connection == m_process->connection());
3143
3144     m_process->processPool().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, 0);
3145 }
3146
3147 void WebPageProxy::processDidFinishLaunching()
3148 {
3149     ASSERT(m_process->state() == WebProcessProxy::State::Running);
3150
3151     if (m_userContentController)
3152         m_process->addWebUserContentControllerProxy(*m_userContentController);
3153     m_process->addVisitedLinkProvider(m_visitedLinkProvider);
3154 }
3155
3156 #if ENABLE(NETSCAPE_PLUGIN_API)
3157 void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString)
3158 {
3159     MESSAGE_CHECK_URL(pluginURLString);
3160     MESSAGE_CHECK_URL(pluginspageAttributeURLString);
3161     MESSAGE_CHECK_URL(frameURLString);
3162     MESSAGE_CHECK_URL(pageURLString);
3163
3164     RefPtr<API::Dictionary> pluginInformation;
3165     String newMimeType = mimeType;
3166     PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString));
3167     pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString);
3168
3169     WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3170     switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) {
3171     case RenderEmbeddedObject::PluginMissing:
3172         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
3173         break;
3174     case RenderEmbeddedObject::InsecurePluginVersion:
3175         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion;
3176         break;
3177     case RenderEmbeddedObject::PluginCrashed:
3178         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed;
3179         break;
3180     case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
3181         ASSERT_NOT_REACHED();
3182     }
3183
3184     m_uiClient->unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get());
3185 }
3186 #endif // ENABLE(NETSCAPE_PLUGIN_API)
3187
3188 #if ENABLE(WEBGL)
3189 void WebPageProxy::webGLPolicyForURL(const String& url, uint32_t& loadPolicy)
3190 {
3191     loadPolicy = static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(this, url));
3192 }
3193
3194 void WebPageProxy::resolveWebGLPolicyForURL(const String& url, uint32_t& loadPolicy)
3195 {
3196     loadPolicy = static_cast<uint32_t>(m_loaderClient->resolveWebGLLoadPolicy(this, url));
3197 }
3198 #endif // ENABLE(WEBGL)
3199
3200 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
3201 {
3202     m_uiClient->setToolbarsAreVisible(this, toolbarsAreVisible);
3203 }
3204
3205 void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible)
3206 {
3207     toolbarsAreVisible = m_uiClient->toolbarsAreVisible(this);
3208 }
3209
3210 void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
3211 {
3212     m_uiClient->setMenuBarIsVisible(this, menuBarIsVisible);
3213 }
3214
3215 void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible)
3216 {
3217     menuBarIsVisible = m_uiClient->menuBarIsVisible(this);
3218 }
3219
3220 void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
3221 {
3222     m_uiClient->setStatusBarIsVisible(this, statusBarIsVisible);
3223 }
3224
3225 void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible)
3226 {
3227     statusBarIsVisible = m_uiClient->statusBarIsVisible(this);
3228 }
3229
3230 void WebPageProxy::setIsResizable(bool isResizable)
3231 {
3232     m_uiClient->setIsResizable(this, isResizable);
3233 }
3234
3235 void WebPageProxy::getIsResizable(bool& isResizable)
3236 {
3237     isResizable = m_uiClient->isResizable(this);
3238 }
3239
3240 void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
3241 {
3242     m_uiClient->setWindowFrame(this, m_pageClient.convertToDeviceSpace(newWindowFrame));
3243 }
3244
3245 void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame)
3246 {
3247     newWindowFrame = m_pageClient.convertToUserSpace(m_uiClient->windowFrame(this));
3248 }
3249     
3250 void WebPageProxy::screenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
3251 {
3252     windowPoint = m_pageClient.screenToRootView(screenPoint);
3253 }
3254     
3255 void WebPageProxy::rootViewToScreen(const IntRect& viewRect, IntRect& result)
3256 {
3257     result = m_pageClient.rootViewToScreen(viewRect);
3258 }
3259     
3260 #if PLATFORM(IOS)
3261 void WebPageProxy::accessibilityScreenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint)
3262 {
3263     windowPoint = m_pageClient.accessibilityScreenToRootView(screenPoint);
3264 }
3265
3266 void WebPageProxy::rootViewToAccessibilityScreen(const IntRect& viewRect, IntRect& result)
3267 {
3268     result = m_pageClient.rootViewToAccessibilityScreen(viewRect);
3269 }
3270 #endif
3271     
3272 void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
3273 {
3274     WebFrameProxy* frame = m_process->webFrame(frameID);
3275     MESSAGE_CHECK(frame);
3276
3277     // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
3278     m_process->responsivenessTimer()->stop();
3279
3280     shouldClose = m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame);
3281 }
3282
3283 #if USE(TILED_BACKING_STORE)
3284 void WebPageProxy::pageDidRequestScroll(const IntPoint& point)
3285 {
3286     m_pageClient.pageDidRequestScroll(point);
3287 }
3288
3289 void WebPageProxy::pageTransitionViewportReady()
3290 {
3291     m_pageClient.pageTransitionViewportReady();
3292 }
3293
3294 void WebPageProxy::didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect)
3295 {
3296     m_pageClient.didRenderFrame(contentsSize, coveredRect);
3297 }
3298
3299 #endif
3300
3301 void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)
3302 {
3303     m_pageClient.didChangeViewportProperties(attr);
3304 }
3305
3306 void WebPageProxy::pageDidScroll()
3307 {
3308     m_uiClient->pageDidScroll(this);
3309 #if PLATFORM(MAC)
3310     m_pageClient.dismissContentRelativeChildWindows();
3311 #endif
3312 }
3313
3314 void WebPageProxy::runOpenPanel(uint64_t frameID, const FileChooserSettings& settings)
3315 {
3316     if (m_openPanelResultListener) {
3317         m_openPanelResultListener->invalidate();
3318         m_openPanelResultListener = 0;
3319     }
3320
3321     WebFrameProxy* frame = m_process->webFrame(frameID);
3322     MESSAGE_CHECK(frame);
3323
3324     RefPtr<WebOpenPanelParameters> parameters = WebOpenPanelParameters::create(settings);
3325     m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
3326
3327     // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
3328     m_process->responsivenessTimer()->stop();
3329
3330     if (!m_uiClient->runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get())) {
3331         if (!m_pageClient.handleRunOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
3332             didCancelForOpenPanel();
3333     }
3334 }
3335
3336 void WebPageProxy::printFrame(uint64_t frameID)
3337 {
3338     ASSERT(!m_isPerformingDOMPrintOperation);
3339     m_isPerformingDOMPrintOperation = true;
3340
3341     WebFrameProxy* frame = m_process->webFrame(frameID);
3342     MESSAGE_CHECK(frame);
3343
3344     m_uiClient->printFrame(this, frame);
3345
3346     endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true.
3347     m_isPerformingDOMPrintOperation = false;
3348 }
3349
3350 void WebPageProxy::printMainFrame()
3351 {
3352     printFrame(m_mainFrame->frameID());
3353 }
3354
3355 void WebPageProxy::setMediaVolume(float volume)
3356 {
3357     if (volume == m_mediaVolume)
3358         return;
3359     
3360     m_mediaVolume = volume;
3361     
3362     if (!isValid())
3363         return;
3364     
3365     m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID);    
3366 }
3367
3368 void WebPageProxy::setMuted(bool muted)
3369 {
3370     if (m_muted == muted)
3371         return;
3372
3373     m_muted = muted;
3374
3375     if (!isValid())
3376         return;
3377
3378     m_process->send(Messages::WebPage::SetMuted(muted), m_pageID);
3379 }
3380
3381 void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia)
3382 {
3383     if (mayStartMedia == m_mayStartMediaWhenInWindow)
3384         return;
3385
3386     m_mayStartMediaWhenInWindow = mayStartMedia;
3387
3388     if (!isValid())
3389         return;
3390
3391     process().send(Messages::WebPage::SetMayStartMediaWhenInWindow(mayStartMedia), m_pageID);
3392 }
3393
3394 void WebPageProxy::handleDownloadRequest(DownloadProxy* download)
3395 {
3396     m_pageClient.handleDownloadRequest(download);
3397 }
3398
3399 #if PLATFORM(EFL)
3400 void WebPageProxy::didChangeContentSize(const IntSize& size)
3401 {
3402     m_pageClient.didChangeContentSize(size);
3403 }
3404 #endif
3405
3406 #if ENABLE(INPUT_TYPE_COLOR)
3407 void WebPageProxy::showColorPicker(const WebCore::Color& initialColor, const IntRect& elementRect)
3408 {
3409 #if ENABLE(INPUT_TYPE_COLOR_POPOVER)
3410     // A new popover color well needs to be created (and the previous one destroyed) for
3411     // each activation of a color element.
3412     m_colorPicker = 0;
3413 #endif
3414     if (!m_colorPicker)
3415         m_colorPicker = m_pageClient.createColorPicker(this, initialColor, elementRect);
3416     m_colorPicker->showColorPicker(initialColor);
3417 }
3418
3419 void WebPageProxy::setColorPickerColor(const WebCore::Color& color)
3420 {
3421     ASSERT(m_colorPicker);
3422
3423     m_colorPicker->setSelectedColor(color);
3424 }
3425
3426 void WebPageProxy::endColorPicker()
3427 {
3428     ASSERT(m_colorPicker);
3429
3430     m_colorPicker->endPicker();
3431 }
3432
3433 void WebPageProxy::didChooseColor(const WebCore::Color& color)
3434 {
3435     if (!isValid())
3436         return;
3437
3438     m_process->send(Messages::WebPage::DidChooseColor(color), m_pageID);
3439 }
3440
3441 void WebPageProxy::didEndColorPicker()
3442 {
3443     if (!isValid())
3444         return;
3445
3446     if (m_colorPicker) {
3447         m_colorPicker->invalidate();
3448         m_colorPicker = nullptr;
3449     }
3450
3451     m_process->send(Messages::WebPage::DidEndColorPicker(), m_pageID);
3452 }
3453 #endif
3454
3455 void WebPageProxy::didDraw()
3456 {
3457     m_uiClient->didDraw(this);
3458 }
3459
3460 // Inspector
3461
3462 #if ENABLE(INSPECTOR)
3463
3464 WebInspectorProxy* WebPageProxy::inspector()
3465 {
3466     if (isClosed() || !isValid())
3467         return 0;
3468     return m_inspector.get();
3469 }
3470
3471 #endif
3472
3473 #if ENABLE(FULLSCREEN_API)
3474 WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
3475 {
3476     return m_fullScreenManager.get();
3477 }
3478 #endif
3479     
3480 #if PLATFORM(IOS)
3481 RefPtr<WebVideoFullscreenManagerProxy> WebPageProxy::videoFullscreenManager()
3482 {
3483     return m_videoFullscreenManager;
3484 }
3485 #endif
3486
3487 // BackForwardList
3488
3489 void WebPageProxy::backForwardAddItem(uint64_t itemID)
3490 {
3491     m_backForwardList->addItem(m_process->webBackForwardItem(itemID));
3492 }
3493
3494 void WebPageProxy::backForwardGoToItem(uint64_t itemID, SandboxExtension::Handle& sandboxExtensionHandle)
3495 {
3496     WebBackForwardListItem* item = m_process->webBackForwardItem(itemID);
3497     if (!item)
3498         return;
3499
3500     bool createdExtension = maybeInitializeSandboxExtensionHandle(URL(URL(), item->url()), sandboxExtensionHandle);
3501     if (createdExtension)
3502         m_process->willAcquireUniversalFileReadSandboxExtension();
3503     m_backForwardList->goToItem(item);
3504 }
3505
3506 void WebPageProxy::backForwardItemAtIndex(int32_t index, uint64_t& itemID)
3507 {
3508     WebBackForwardListItem* item = m_backForwardList->itemAtIndex(index);
3509     itemID = item ? item->itemID() : 0;
3510 }
3511
3512 void WebPageProxy::backForwardBackListCount(int32_t& count)
3513 {
3514     count = m_backForwardList->backListCount();
3515 }
3516
3517 void WebPageProxy::backForwardForwardListCount(int32_t& count)
3518 {
3519     count = m_backForwardList->forwardListCount();
3520 }
3521
3522 void WebPageProxy::editorStateChanged(const EditorState& editorState)
3523 {
3524 #if PLATFORM(COCOA)
3525     bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
3526 #endif
3527 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
3528     bool closedComposition = !editorState.shouldIgnoreCompositionSelectionChange && !editorState.hasComposition && (m_editorState.hasComposition || m_temporarilyClosedComposition);
3529     m_temporarilyClosedComposition = editorState.shouldIgnoreCompositionSelectionChange && (m_temporarilyClosedComposition || m_editorState.hasComposition) && !editorState.hasComposition;
3530     bool editabilityChanged = m_editorState.isContentEditable != editorState.isContentEditable;
3531 #endif
3532
3533     m_editorState = editorState;
3534
3535 #if PLATFORM(COCOA)
3536     // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood).
3537     if (couldChangeSecureInputState && !editorState.selectionIsNone)
3538         m_pageClient.updateSecureInputState();
3539 #endif
3540
3541     if (editorState.shouldIgnoreCompositionSelectionChange)
3542         return;
3543
3544 #if PLATFORM(MAC) && !USE(ASYNC_NSTEXTINPUTCLIENT)
3545     if (closedComposition)
3546         m_pageClient.notifyInputContextAboutDiscardedComposition();
3547     if (editabilityChanged) {
3548         // This is only needed in sync code path, because AppKit automatically refreshes input context for async clients (<rdar://problem/18604360>).
3549         m_pageClient.notifyApplicationAboutInputContextChange();
3550     }
3551     if (editorState.hasComposition) {
3552         // Abandon the current inline input session if selection changed for any other reason but an input method changing the composition.
3553         // FIXME: This logic should be in WebCore, no need to round-trip to UI process to cancel the composition.
3554         cancelComposition();
3555         m_pageClient.notifyInputContextAboutDiscardedComposition();
3556     }
3557 #elif PLATFORM(IOS)
3558     // We always need to notify the client on iOS to make sure the selection is redrawn,
3559     // even during composition to support phrase boundary gesture.
3560     notifyRevealedSelection();
3561 #elif PLATFORM(EFL) || PLATFORM(GTK)
3562     m_pageClient.updateTextInputState();
3563 #endif
3564 }
3565
3566 void WebPageProxy::compositionWasCanceled(const EditorState& editorState)
3567 {
3568 #if PLATFORM(COCOA)
3569     m_pageClient.notifyInputContextAboutDiscardedComposition();
3570 #endif
3571     editorStateChanged(editorState);
3572 }
3573
3574 // Undo management
3575
3576 void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editAction)
3577 {
3578     registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo);
3579 }
3580     
3581 void WebPageProxy::registerInsertionUndoGrouping()
3582 {
3583 #if USE(INSERTION_UNDO_GROUPING)
3584     m_pageClient.registerInsertionUndoGrouping();
3585 #endif
3586 }
3587
3588 void WebPageProxy::canUndoRedo(uint32_t action, bool& result)
3589 {
3590     result = m_pageClient.canUndoRedo(static_cast<UndoOrRedo>(action));
3591 }
3592
3593 void WebPageProxy::executeUndoRedo(uint32_t action, bool& result)
3594 {
3595     m_pageClient.executeUndoRedo(static_cast<UndoOrRedo>(action));
3596     result = true;
3597 }
3598
3599 void WebPageProxy::clearAllEditCommands()
3600 {
3601     m_pageClient.clearAllEditCommands();
3602 }
3603
3604 void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount)
3605 {
3606     m_findClient->didCountStringMatches(this, string, matchCount);
3607 }
3608
3609 void WebPageProxy::didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex)
3610 {
3611     m_findMatchesClient.didGetImageForMatchResult(this, WebImage::create(ShareableBitmap::create(contentImageHandle)).get(), matchIndex);
3612 }
3613
3614 void WebPageProxy::setTextIndicator(const TextIndicatorData& indicatorData, bool fadeOut)
3615 {
3616     m_pageClient.setTextIndicator(TextIndicator::create(indicatorData), fadeOut);
3617 }
3618
3619 void WebPageProxy::clearTextIndicator()
3620 {
3621     m_pageClient.setTextIndicator(nullptr, false);
3622 }
3623
3624 void WebPageProxy::setTextIndicatorAnimationProgress(float progress)
3625 {
3626     m_pageClient.setTextIndicatorAnimationProgress(progress);
3627 }
3628
3629 void WebPageProxy::didFindString(const String& string, uint32_t matchCount, int32_t matchIndex)
3630 {
3631     m_findClient->didFindString(this, string, matchCount, matchIndex);
3632 }
3633
3634 void WebPageProxy::didFindStringMatches(const String& string, const Vector<Vector<WebCore::I