Changeset 222431 in webkit


Ignore:
Timestamp:
Sep 23, 2017, 11:22:58 PM (9 years ago)
Author:
achristensen@apple.com
Message:

REGRESSION(r214201): WebProcess hangs during policy decisions
https://bugs.webkit.org/show_bug.cgi?id=177411
<rdar://problem/33362929>

Reviewed by Geoffrey Garen.

Source/WebKit:

decidePolicyForNavigationAction and decidePolicyForNavigationResponse used to have
a shortcut path for if you called the decisionHandler synchronously and a different path
for asynchronous decisionHandler calling. r214201 made it so there is one path but the
WebProcess hangs, which prevents us from executing JavaScript in the WebProcess where we
could before. This patch effectively reverts r214201 on the branch and pipes the WebsitePolicies
through the asynchronous decisionHandler path to be used only for decidePolicyForNavigationAction,
which is the only such callback that can set the WebsitePolicies.

This patch is for the safari-604-branch branch. I'll fix this problem on trunk by making all
policy messages async and using different message types for each policy check, and then I'll
get this same API test working on trunk.

  • UIProcess/API/C/WKPage.cpp:

(WKPageSetPageNavigationClient):

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::receivedPolicyDecision):
(WebKit::WebPageProxy::decidePolicyForNavigationAction):
(WebKit::WebPageProxy::decidePolicyForResponseSync):

  • UIProcess/WebPageProxy.h:
  • UIProcess/WebPageProxy.messages.in:
  • WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:

(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction):
(WebKit::WebFrameLoaderClient::applyToDocumentLoader):
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
(WebKit::WebFrameLoaderClient::dispatchWillSubmitForm):

  • WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
  • WebProcess/WebPage/WebFrame.cpp:

(WebKit::WebFrame::setUpPolicyListener):
(WebKit::WebFrame::invalidatePolicyListener):
(WebKit::WebFrame::didReceivePolicyDecision):

  • WebProcess/WebPage/WebFrame.h:
  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::didReceivePolicyDecision):

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in:

Tools:

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKit2Cocoa/JavaScriptDuringNavigation.mm: Added.

(-[JSNavigationDelegate webView:didFinishNavigation:]):
(-[JSNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
(-[JSNavigationDelegate webView:decidePolicyForNavigationResponse:decisionHandler:]):
(-[JSNavigationDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]):
(TEST):

Location:
branches/safari-604-branch
Files:
1 added
14 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-604-branch/Source/WebKit/ChangeLog

    r222043 r222431  
     12017-09-23  Alex Christensen  <achristensen@webkit.org>
     2
     3        REGRESSION(r214201): WebProcess hangs during policy decisions
     4        https://bugs.webkit.org/show_bug.cgi?id=177411
     5        <rdar://problem/33362929>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        decidePolicyForNavigationAction and decidePolicyForNavigationResponse used to have
     10        a shortcut path for if you called the decisionHandler synchronously and a different path
     11        for asynchronous decisionHandler calling.  r214201 made it so there is one path but the
     12        WebProcess hangs, which prevents us from executing JavaScript in the WebProcess where we
     13        could before.  This patch effectively reverts r214201 on the branch and pipes the WebsitePolicies
     14        through the asynchronous decisionHandler path to be used only for decidePolicyForNavigationAction,
     15        which is the only such callback that can set the WebsitePolicies.
     16       
     17        This patch is for the safari-604-branch branch.  I'll fix this problem on trunk by making all
     18        policy messages async and using different message types for each policy check, and then I'll
     19        get this same API test working on trunk.
     20
     21        * UIProcess/API/C/WKPage.cpp:
     22        (WKPageSetPageNavigationClient):
     23        * UIProcess/WebPageProxy.cpp:
     24        (WebKit::WebPageProxy::receivedPolicyDecision):
     25        (WebKit::WebPageProxy::decidePolicyForNavigationAction):
     26        (WebKit::WebPageProxy::decidePolicyForResponseSync):
     27        * UIProcess/WebPageProxy.h:
     28        * UIProcess/WebPageProxy.messages.in:
     29        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
     30        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForResponse):
     31        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction):
     32        (WebKit::WebFrameLoaderClient::applyToDocumentLoader):
     33        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
     34        (WebKit::WebFrameLoaderClient::dispatchWillSubmitForm):
     35        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
     36        * WebProcess/WebPage/WebFrame.cpp:
     37        (WebKit::WebFrame::setUpPolicyListener):
     38        (WebKit::WebFrame::invalidatePolicyListener):
     39        (WebKit::WebFrame::didReceivePolicyDecision):
     40        * WebProcess/WebPage/WebFrame.h:
     41        * WebProcess/WebPage/WebPage.cpp:
     42        (WebKit::WebPage::didReceivePolicyDecision):
     43        * WebProcess/WebPage/WebPage.h:
     44        * WebProcess/WebPage/WebPage.messages.in:
     45
    1462017-09-14  Jason Marcell  <jmarcell@apple.com>
    247
  • branches/safari-604-branch/Source/WebKit/UIProcess/API/C/WKPage.cpp

    r219106 r222431  
    21602160        void decidePolicyForNavigationAction(WebPageProxy& page, API::NavigationAction& navigationAction, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
    21612161        {
    2162             if (!m_client.decidePolicyForNavigationAction) {
    2163                 listener->use({ });
    2164                 return;
    2165             }
     2162            if (!m_client.decidePolicyForNavigationAction)
     2163                return;
     2164
    21662165            m_client.decidePolicyForNavigationAction(toAPI(&page), toAPI(&navigationAction), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
    21672166        }
     
    21692168        void decidePolicyForNavigationResponse(WebPageProxy& page, API::NavigationResponse& navigationResponse, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) override
    21702169        {
    2171             if (!m_client.decidePolicyForNavigationResponse) {
    2172                 listener->use({ });
    2173                 return;
    2174             }
     2170            if (!m_client.decidePolicyForNavigationResponse)
     2171                return;
     2172
    21752173            m_client.decidePolicyForNavigationResponse(toAPI(&page), toAPI(&navigationResponse), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo);
    21762174        }
  • branches/safari-604-branch/Source/WebKit/UIProcess/WebPageProxy.cpp

    r221619 r222431  
    22612261    if (action == PolicyDownload) {
    22622262        // Create a download proxy.
    2263         DownloadProxy* download = m_process->processPool().createDownloadProxy(m_decidePolicyForResponseRequest);
     2263        const ResourceRequest& downloadRequest = m_decidePolicyForResponseRequest ? *m_decidePolicyForResponseRequest : ResourceRequest();
     2264        DownloadProxy* download = m_process->processPool().createDownloadProxy(downloadRequest);
    22642265        downloadID = download->downloadID();
    22652266        handleDownloadRequest(download);
    2266         m_decidePolicyForResponseRequest = { };
    22672267    }
    22682268
    22692269    // If we received a policy decision while in decidePolicyForResponse the decision will
    22702270    // be sent back to the web process by decidePolicyForResponse.
    2271     if (m_responsePolicyReply) {
    2272         m_responsePolicyReply->send(action, downloadID);
    2273         ASSERT(!m_newNavigationID);
    2274         m_responsePolicyReply = nullptr;
     2271    if (m_inDecidePolicyForResponseSync) {
     2272        m_syncMimeTypePolicyActionIsValid = true;
     2273        m_syncMimeTypePolicyAction = action;
     2274        m_syncMimeTypePolicyDownloadID = downloadID;
    22752275        return;
    22762276    }
     
    22782278    // If we received a policy decision while in decidePolicyForNavigationAction the decision will
    22792279    // be sent back to the web process by decidePolicyForNavigationAction.
    2280     if (m_navigationActionPolicyReply) {
    2281         m_navigationActionPolicyReply->send(m_newNavigationID, action, downloadID, websitePolicies);
    2282         m_newNavigationID = 0;
    2283         m_navigationActionPolicyReply = nullptr;
     2280    if (m_inDecidePolicyForNavigationAction) {
     2281        m_syncNavigationActionPolicyActionIsValid = true;
     2282        m_syncNavigationActionPolicyAction = action;
     2283        m_syncNavigationActionPolicyDownloadID = downloadID;
     2284        m_syncNavigationActionPolicyWebsitePolicies = websitePolicies;
    22842285        return;
    22852286    }
    22862287   
    2287     m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame.frameID(), listenerID, action, navigation ? navigation->navigationID() : 0, downloadID), m_pageID);
     2288    m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame.frameID(), listenerID, action, navigation ? navigation->navigationID() : 0, downloadID, websitePolicies), m_pageID);
    22882289}
    22892290
     
    36283629}
    36293630
    3630 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData& navigationActionData, const FrameInfoData& originatingFrameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, const UserData& userData, Ref<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply>&& reply)
     3631void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData& navigationActionData, const FrameInfoData& originatingFrameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& newNavigationID, uint64_t& policyAction, DownloadID& downloadID, WebsitePolicies& websitePolicies)
    36313632{
    36323633    PageClientProtector protector(m_pageClient);
     
    36433644    MESSAGE_CHECK_URL(originalRequest.url());
    36443645   
    3645     m_newNavigationID = 0;
    36463646    Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
    36473647    if (!navigationID && frame->isMainFrame()) {
    36483648        auto navigation = m_navigationState->createLoadRequestNavigation(request);
    3649         m_newNavigationID = navigation->navigationID();
     3649        newNavigationID = navigation->navigationID();
    36503650        listener->setNavigation(WTFMove(navigation));
    36513651    }
     
    36533653#if ENABLE(CONTENT_FILTERING)
    36543654    if (frame->didHandleContentFilterUnblockNavigation(request)) {
    3655         reply->send(m_newNavigationID, PolicyIgnore, { }, { });
    3656         m_newNavigationID = 0;
    3657         return;
    3658     }
    3659 #endif
    3660 
     3655        receivedPolicyAction = true;
     3656        policyAction = PolicyIgnore;
     3657        return;
     3658    }
     3659#endif
     3660
     3661    ASSERT(!m_inDecidePolicyForNavigationAction);
     3662
     3663    m_inDecidePolicyForNavigationAction = true;
     3664    m_syncNavigationActionPolicyActionIsValid = false;
    36613665#if ENABLE(DOWNLOAD_ATTRIBUTE)
    36623666    m_syncNavigationActionHasDownloadAttribute = !navigationActionData.downloadAttribute.isNull();
    36633667#endif
    3664     m_navigationActionPolicyReply = WTFMove(reply);
    36653668
    36663669    WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameInfoData.frameID);
     
    36843687
    36853688    m_shouldSuppressAppLinksInNextNavigationPolicyDecision = false;
     3689    m_inDecidePolicyForNavigationAction = false;
     3690
     3691    // Check if we received a policy decision already. If we did, we can just pass it back.
     3692    receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
     3693    if (m_syncNavigationActionPolicyActionIsValid) {
     3694        policyAction = m_syncNavigationActionPolicyAction;
     3695        downloadID = m_syncNavigationActionPolicyDownloadID;
     3696        websitePolicies = m_syncNavigationActionPolicyWebsitePolicies;
     3697    }
    36863698}
    36873699
     
    37293741}
    37303742
    3731 void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, Ref<Messages::WebPageProxy::DecidePolicyForResponseSync::DelayedReply>&& reply)
     3743void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& policyAction, DownloadID& downloadID)
    37323744{
    37333745    PageClientProtector protector(m_pageClient);
    37343746
    3735     m_decidePolicyForResponseRequest = request;
    3736     m_responsePolicyReply = WTFMove(reply);
     3747    ASSERT(!m_inDecidePolicyForResponseSync);
     3748   
     3749    m_inDecidePolicyForResponseSync = true;
     3750    m_decidePolicyForResponseRequest = &request;
     3751    m_syncMimeTypePolicyActionIsValid = false;
    37373752
    37383753    decidePolicyForResponse(frameID, frameSecurityOrigin, response, request, canShowMIMEType, listenerID, userData);
     3754   
     3755    m_inDecidePolicyForResponseSync = false;
     3756    m_decidePolicyForResponseRequest = nullptr;
     3757
     3758    // Check if we received a policy decision already. If we did, we can just pass it back.
     3759    receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
     3760    if (m_syncMimeTypePolicyActionIsValid) {
     3761        policyAction = m_syncMimeTypePolicyAction;
     3762        downloadID = m_syncMimeTypePolicyDownloadID;
     3763    }
    37393764}
    37403765
  • branches/safari-604-branch/Source/WebKit/UIProcess/WebPageProxy.h

    r221619 r222431  
    12741274    void didDestroyNavigation(uint64_t navigationID);
    12751275
    1276     void decidePolicyForNavigationAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData&, const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceRequest&, uint64_t listenerID, const UserData&, Ref<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply>&&);
     1276    void decidePolicyForNavigationAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData&, const FrameInfoData&, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceRequest&, uint64_t listenerID, const UserData&, bool& receivedPolicyAction, uint64_t& newNavigationID, uint64_t& policyAction, DownloadID&, WebsitePolicies&);
    12771277    void decidePolicyForNewWindowAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, const NavigationActionData&, const WebCore::ResourceRequest&, const String& frameName, uint64_t listenerID, const UserData&);
    12781278    void decidePolicyForResponse(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&);
    1279     void decidePolicyForResponseSync(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&, Ref<Messages::WebPageProxy::DecidePolicyForResponseSync::DelayedReply>&&);
     1279    void decidePolicyForResponseSync(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&, bool& receivedPolicyAction, uint64_t& policyAction, DownloadID&);
    12801280    void unableToImplementPolicy(uint64_t frameID, const WebCore::ResourceError&, const UserData&);
    12811281
     
    17911791    bool m_isPerformingDOMPrintOperation { false };
    17921792
    1793     RefPtr<Messages::WebPageProxy::DecidePolicyForNavigationAction::DelayedReply> m_navigationActionPolicyReply;
    1794     uint64_t m_newNavigationID { 0 };
    1795     RefPtr<Messages::WebPageProxy::DecidePolicyForResponseSync::DelayedReply> m_responsePolicyReply;
    1796     WebCore::ResourceRequest m_decidePolicyForResponseRequest;
     1793    bool m_inDecidePolicyForResponseSync { false };
     1794    const WebCore::ResourceRequest* m_decidePolicyForResponseRequest { nullptr };
     1795    bool m_syncMimeTypePolicyActionIsValid { false };
     1796    WebCore::PolicyAction m_syncMimeTypePolicyAction { WebCore::PolicyUse };
     1797    DownloadID m_syncMimeTypePolicyDownloadID { 0 };
     1798    bool m_inDecidePolicyForNavigationAction { false };
     1799    bool m_syncNavigationActionPolicyActionIsValid { false };
     1800    WebCore::PolicyAction m_syncNavigationActionPolicyAction { WebCore::PolicyUse };
     1801    DownloadID m_syncNavigationActionPolicyDownloadID { 0 };
     1802    WebsitePolicies m_syncNavigationActionPolicyWebsitePolicies;
    17971803
    17981804    bool m_shouldSuppressAppLinksInNextNavigationPolicyDecision { false };
  • branches/safari-604-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in

    r221619 r222431  
    100100
    101101    # Policy messages
    102     DecidePolicyForResponseSync(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, uint64_t listenerID, WebKit::UserData userData) -> (uint64_t policyAction, WebKit::DownloadID downloadID) Delayed
    103     DecidePolicyForNavigationAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, uint64_t listenerID, WebKit::UserData userData) -> (uint64_t newNavigationID, uint64_t policyAction, WebKit::DownloadID downloadID, struct WebKit::WebsitePolicies websitePolicies) Delayed
     102    DecidePolicyForResponseSync(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, uint64_t listenerID, WebKit::UserData userData) -> (bool receivedPolicyAction,uint64_t policyAction, WebKit::DownloadID downloadID)
     103    DecidePolicyForNavigationAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, struct WebKit::FrameInfoData originatingFrameInfoData, uint64_t originatingPageID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, uint64_t listenerID, WebKit::UserData userData) -> (bool receivedPolicyAction,uint64_t newNavigationID, uint64_t policyAction, WebKit::DownloadID downloadID, struct WebKit::WebsitePolicies websitePolicies)
    104104    DecidePolicyForNewWindowAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, struct WebKit::NavigationActionData navigationActionData, WebCore::ResourceRequest request, String frameName, uint64_t listenerID, WebKit::UserData userData)
    105105    UnableToImplementPolicy(uint64_t frameID, WebCore::ResourceError error, WebKit::UserData userData)
  • branches/safari-604-branch/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp

    r221619 r222431  
    701701    bool canShowMIMEType = webPage->canShowMIMEType(response.mimeType());
    702702
    703     uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
     703    uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function), WebFrame::ForNavigationAction::No);
     704    bool receivedPolicyAction;
    704705    uint64_t policyAction;
    705706    DownloadID downloadID;
     
    707708    Ref<WebFrame> protect(*m_frame);
    708709    WebCore::Frame* coreFrame = m_frame->coreFrame();
    709     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponseSync(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), response, request, canShowMIMEType, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForResponseSync::Reply(policyAction, downloadID), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend)) {
    710         m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { });
     710    if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponseSync(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), response, request, canShowMIMEType, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForResponseSync::Reply(receivedPolicyAction, policyAction, downloadID), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend)) {
     711        m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { }, { });
    711712        return;
    712713    }
    713714
    714715    // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
    715     m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), 0, downloadID);
     716    if (receivedPolicyAction)
     717        m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), 0, downloadID, { });
    716718}
    717719
     
    736738
    737739
    738     uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
     740    uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function), WebFrame::ForNavigationAction::No);
    739741
    740742    NavigationActionData navigationActionData;
     
    753755}
    754756
    755 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, bool didReceiveRedirectResponse, FormState* formState, FramePolicyFunction&& function)
    756 {
    757     WebPage* webPage = m_frame->page();
    758     if (!webPage) {
    759         function(PolicyIgnore);
    760         return;
    761     }
    762 
    763     // Always ignore requests with empty URLs.
    764     if (request.isEmpty()) {
    765         function(PolicyIgnore);
    766         return;
    767     }
    768 
    769     RefPtr<API::Object> userData;
    770 
    771     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
    772 
    773     // Notify the bundle client.
    774     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData);
    775     if (policy == WKBundlePagePolicyActionUse) {
    776         function(PolicyUse);
    777         return;
    778     }
    779    
    780     uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
    781     uint64_t newNavigationID;
    782     uint64_t policyAction;
    783     DownloadID downloadID;
    784 
    785     ASSERT(navigationAction.sourceDocument());
    786     const Document& sourceDocument = *navigationAction.sourceDocument();
    787     RefPtr<WebFrame> originatingFrame = sourceDocument.frame() ? WebFrame::fromCoreFrame(*sourceDocument.frame()) : nullptr;
    788 
    789     FrameInfoData originatingFrameInfoData;
    790     originatingFrameInfoData.isMainFrame = navigationAction.initiatedByMainFrame() == InitiatedByMainFrame::Yes;
    791     originatingFrameInfoData.request = ResourceRequest(sourceDocument.url());
    792     originatingFrameInfoData.securityOrigin = SecurityOriginData::fromSecurityOrigin(sourceDocument.securityOrigin());
    793     if (originatingFrame)
    794         originatingFrameInfoData.frameID = originatingFrame->frameID();
    795 
    796     NavigationActionData navigationActionData;
    797     navigationActionData.navigationType = action->navigationType();
    798     navigationActionData.modifiers = action->modifiers();
    799     navigationActionData.mouseButton = action->mouseButton();
    800     navigationActionData.syntheticClickType = action->syntheticClickType();
    801     navigationActionData.clickLocationInRootViewCoordinates = action->clickLocationInRootViewCoordinates();
    802     navigationActionData.userGestureTokenIdentifier = WebProcess::singleton().userGestureTokenIdentifier(navigationAction.userGestureToken());
    803     navigationActionData.canHandleRequest = webPage->canHandleRequest(request);
    804     navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
    805     navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
    806     navigationActionData.isRedirect = didReceiveRedirectResponse;
    807 
    808     WebCore::Frame* coreFrame = m_frame->coreFrame();
     757void WebFrameLoaderClient::applyToDocumentLoader(const WebsitePolicies& websitePolicies)
     758{
     759    if (!m_frame)
     760        return;
     761    auto* coreFrame = m_frame->coreFrame();
     762    if (!coreFrame)
     763        return;
    809764    WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().policyDocumentLoader());
    810     if (!documentLoader) {
    811         // FIXME: When we receive a redirect after the navigation policy has been decided for the initial request,
    812         // the provisional load's DocumentLoader needs to receive navigation policy decisions. We need a better model for this state.
     765    if (!documentLoader)
    813766        documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().provisionalDocumentLoader());
    814     }
    815767    if (!documentLoader)
    816768        documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader());
    817 
    818     // Notify the UIProcess.
    819     Ref<WebFrame> protect(*m_frame);
    820     WebsitePolicies websitePolicies;
    821     // FIXME: Determine the originating page independently from the originating frame as it may exist even if
    822     // the originating frame does not exist. This can happen if the originating frame was removed from the page.
    823     // See <https://bugs.webkit.org/show_bug.cgi?id=174531>.
    824     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), documentLoader->navigationID(), navigationActionData, originatingFrameInfoData, originatingFrame && originatingFrame->page() ? originatingFrame->page()->pageID() : 0, navigationAction.resourceRequest(), request, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(newNavigationID, policyAction, downloadID, websitePolicies))) {
    825         m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { });
    826         return;
    827     }
     769    if (!documentLoader)
     770        return;
    828771
    829772    // Only setUserContentExtensionsEnabled if it hasn't already been disabled by reloading without content blockers.
    830773    if (documentLoader->userContentExtensionsEnabled())
    831774        documentLoader->setUserContentExtensionsEnabled(websitePolicies.contentBlockersEnabled);
    832 
     775   
    833776    OptionSet<AutoplayQuirk> quirks;
    834777    auto allowedQuirks = websitePolicies.allowedAutoplayQuirks;
    835 
     778   
    836779    if (allowedQuirks.contains(WebsiteAutoplayQuirk::InheritedUserGestures))
    837780        quirks |= AutoplayQuirk::InheritedUserGestures;
    838 
     781   
    839782    if (allowedQuirks.contains(WebsiteAutoplayQuirk::SynthesizedPauseEvents))
    840783        quirks |= AutoplayQuirk::SynthesizedPauseEvents;
    841 
     784   
    842785    documentLoader->setAllowedAutoplayQuirks(quirks);
    843 
     786   
    844787    switch (websitePolicies.autoplayPolicy) {
    845788    case WebsiteAutoplayPolicy::Default:
     
    856799        break;
    857800    }
     801}
     802
     803void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, bool didReceiveRedirectResponse, FormState* formState, FramePolicyFunction&& function)
     804{
     805    WebPage* webPage = m_frame->page();
     806    if (!webPage) {
     807        function(PolicyIgnore);
     808        return;
     809    }
     810
     811    // Always ignore requests with empty URLs.
     812    if (request.isEmpty()) {
     813        function(PolicyIgnore);
     814        return;
     815    }
     816
     817    RefPtr<API::Object> userData;
     818
     819    RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
     820
     821    // Notify the bundle client.
     822    WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData);
     823    if (policy == WKBundlePagePolicyActionUse) {
     824        function(PolicyUse);
     825        return;
     826    }
     827   
     828    uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function), WebFrame::ForNavigationAction::Yes);
     829    bool receivedPolicyAction;
     830    uint64_t newNavigationID;
     831    uint64_t policyAction;
     832    DownloadID downloadID;
     833
     834    ASSERT(navigationAction.sourceDocument());
     835    const Document& sourceDocument = *navigationAction.sourceDocument();
     836    RefPtr<WebFrame> originatingFrame = sourceDocument.frame() ? WebFrame::fromCoreFrame(*sourceDocument.frame()) : nullptr;
     837
     838    FrameInfoData originatingFrameInfoData;
     839    originatingFrameInfoData.isMainFrame = navigationAction.initiatedByMainFrame() == InitiatedByMainFrame::Yes;
     840    originatingFrameInfoData.request = ResourceRequest(sourceDocument.url());
     841    originatingFrameInfoData.securityOrigin = SecurityOriginData::fromSecurityOrigin(sourceDocument.securityOrigin());
     842    if (originatingFrame)
     843        originatingFrameInfoData.frameID = originatingFrame->frameID();
     844
     845    NavigationActionData navigationActionData;
     846    navigationActionData.navigationType = action->navigationType();
     847    navigationActionData.modifiers = action->modifiers();
     848    navigationActionData.mouseButton = action->mouseButton();
     849    navigationActionData.syntheticClickType = action->syntheticClickType();
     850    navigationActionData.clickLocationInRootViewCoordinates = action->clickLocationInRootViewCoordinates();
     851    navigationActionData.userGestureTokenIdentifier = WebProcess::singleton().userGestureTokenIdentifier(navigationAction.userGestureToken());
     852    navigationActionData.canHandleRequest = webPage->canHandleRequest(request);
     853    navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
     854    navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
     855    navigationActionData.isRedirect = didReceiveRedirectResponse;
     856
     857    WebCore::Frame* coreFrame = m_frame->coreFrame();
     858    WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().policyDocumentLoader());
     859    if (!documentLoader) {
     860        // FIXME: When we receive a redirect after the navigation policy has been decided for the initial request,
     861        // the provisional load's DocumentLoader needs to receive navigation policy decisions. We need a better model for this state.
     862        documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().provisionalDocumentLoader());
     863    }
     864    if (!documentLoader)
     865        documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader());
     866
     867    // Notify the UIProcess.
     868    Ref<WebFrame> protect(*m_frame);
     869    WebsitePolicies websitePolicies;
     870    // FIXME: Determine the originating page independently from the originating frame as it may exist even if
     871    // the originating frame does not exist. This can happen if the originating frame was removed from the page.
     872    // See <https://bugs.webkit.org/show_bug.cgi?id=174531>.
     873    if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), documentLoader->navigationID(), navigationActionData, originatingFrameInfoData, originatingFrame && originatingFrame->page() ? originatingFrame->page()->pageID() : 0, navigationAction.resourceRequest(), request, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, newNavigationID, policyAction, downloadID, websitePolicies))) {
     874        m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { }, { });
     875        return;
     876    }
    858877
    859878    // We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply.
    860     m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), newNavigationID, downloadID);
     879    if (receivedPolicyAction)
     880        m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), newNavigationID, downloadID, websitePolicies);
    861881}
    862882
     
    912932    webPage->injectedBundleFormClient().willSubmitForm(webPage, &form, m_frame, sourceFrame, values, userData);
    913933
    914     uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
     934    uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function), WebFrame::ForNavigationAction::No);
    915935
    916936    webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), values, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
  • branches/safari-604-branch/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h

    r221619 r222431  
    3636class PluginView;
    3737class WebFrame;
     38struct WebsitePolicies;
    3839   
    3940class WebFrameLoaderClient final : public WebCore::FrameLoaderClient {
     
    4849
    4950    void setUseIconLoadingClient(bool useIconLoadingClient) { m_useIconLoadingClient = useIconLoadingClient; }
     51
     52    void applyToDocumentLoader(const WebsitePolicies&);
    5053
    5154private:
  • branches/safari-604-branch/Source/WebKit/WebProcess/WebPage/WebFrame.cpp

    r218501 r222431  
    210210}
    211211
    212 uint64_t WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction&& policyFunction)
     212uint64_t WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction&& policyFunction, ForNavigationAction forNavigationAction)
    213213{
    214214    // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
     
    218218    m_policyListenerID = generateListenerID();
    219219    m_policyFunction = WTFMove(policyFunction);
     220    m_policyFunctionForNavigationAction = forNavigationAction;
    220221    return m_policyListenerID;
    221222}
     
    229230    m_policyListenerID = 0;
    230231    m_policyFunction = nullptr;
    231 }
    232 
    233 void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t navigationID, DownloadID downloadID)
     232    m_policyFunctionForNavigationAction = ForNavigationAction::No;
     233}
     234
     235void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t navigationID, DownloadID downloadID, const WebsitePolicies& websitePolicies)
    234236{
    235237    if (!m_coreFrame)
     
    246248    FramePolicyFunction function = WTFMove(m_policyFunction);
    247249
     250    bool forNavigationAction = m_policyFunctionForNavigationAction == ForNavigationAction::Yes;
     251   
    248252    invalidatePolicyListener();
    249253
     254    if (forNavigationAction && m_frameLoaderClient)
     255        m_frameLoaderClient->applyToDocumentLoader(websitePolicies);
     256   
    250257    m_policyDownloadID = downloadID;
    251258    if (navigationID) {
  • branches/safari-604-branch/Source/WebKit/WebProcess/WebPage/WebFrame.h

    r218501 r222431  
    6262class WebPage;
    6363struct FrameInfoData;
     64struct WebsitePolicies;
    6465
    6566class WebFrame : public API::ObjectImpl<API::Object::Type::BundleFrame> {
     
    8081    uint64_t frameID() const { return m_frameID; }
    8182
    82     uint64_t setUpPolicyListener(WebCore::FramePolicyFunction&&);
     83    enum class ForNavigationAction { No, Yes };
     84    uint64_t setUpPolicyListener(WebCore::FramePolicyFunction&&, ForNavigationAction);
    8385    void invalidatePolicyListener();
    84     void didReceivePolicyDecision(uint64_t listenerID, WebCore::PolicyAction, uint64_t navigationID, DownloadID);
     86    void didReceivePolicyDecision(uint64_t listenerID, WebCore::PolicyAction, uint64_t navigationID, DownloadID, const WebsitePolicies&);
    8587
    8688    void startDownload(const WebCore::ResourceRequest&, const String& suggestedName = { });
     
    172174    uint64_t m_policyListenerID { 0 };
    173175    WebCore::FramePolicyFunction m_policyFunction;
     176    ForNavigationAction m_policyFunctionForNavigationAction { ForNavigationAction::No };
    174177    DownloadID m_policyDownloadID { 0 };
    175178
  • branches/safari-604-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r220062 r222431  
    27242724}
    27252725
    2726 void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t navigationID, const DownloadID& downloadID)
     2726void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t navigationID, const DownloadID& downloadID, WebsitePolicies&& websitePolicies)
    27272727{
    27282728    WebFrame* frame = WebProcess::singleton().webFrame(frameID);
    27292729    if (!frame)
    27302730        return;
    2731     frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), navigationID, downloadID);
     2731    frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), navigationID, downloadID, websitePolicies);
    27322732}
    27332733
  • branches/safari-604-branch/Source/WebKit/WebProcess/WebPage/WebPage.h

    r220062 r222431  
    11281128    void updatePreferences(const WebPreferencesStore&);
    11291129
    1130     void didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t navigationID, const DownloadID&);
     1130    void didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t navigationID, const DownloadID&, WebsitePolicies&&);
    11311131    void setUserAgent(const String&);
    11321132    void setCustomTextEncodingName(const String&);
  • branches/safari-604-branch/Source/WebKit/WebProcess/WebPage/WebPage.messages.in

    r219934 r222431  
    151151
    152152    UpdateWebsitePolicies(struct WebKit::WebsitePolicies websitePolicies)
    153     DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t navigationID, WebKit::DownloadID downloadID)
     153    DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t navigationID, WebKit::DownloadID downloadID, struct WebKit::WebsitePolicies websitePolicies)
    154154
    155155    ClearSelection()
  • branches/safari-604-branch/Tools/ChangeLog

    r222299 r222431  
     12017-09-23  Alex Christensen  <achristensen@webkit.org>
     2
     3        REGRESSION(r214201): WebProcess hangs during policy decisions
     4        https://bugs.webkit.org/show_bug.cgi?id=177411
     5        <rdar://problem/33362929>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     10        * TestWebKitAPI/Tests/WebKit2Cocoa/JavaScriptDuringNavigation.mm: Added.
     11        (-[JSNavigationDelegate webView:didFinishNavigation:]):
     12        (-[JSNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
     13        (-[JSNavigationDelegate webView:decidePolicyForNavigationResponse:decisionHandler:]):
     14        (-[JSNavigationDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]):
     15        (TEST):
     16
    1172017-09-20  Jason Marcell  <jmarcell@apple.com>
    218
  • branches/safari-604-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r220749 r222431  
    215215                5C2936931D5BF70D00DEAB1E /* CookieAcceptPolicy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C2936911D5BF63E00DEAB1E /* CookieAcceptPolicy.mm */; };
    216216                5C2936961D5C00ED00DEAB1E /* CookieMessage.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5C2936941D5BFD1900DEAB1E /* CookieMessage.html */; };
     217                5C5731051F76D85000081388 /* JavaScriptDuringNavigation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C5731041F76D81F00081388 /* JavaScriptDuringNavigation.mm */; };
    217218                5C6E65441D5CEFD400F7862E /* URLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C6E65411D5CEF8500F7862E /* URLParser.cpp */; };
    218219                5C726D6F1D3EE06E00C5E1A1 /* InstanceMethodSwizzler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C726D6E1D3EE06800C5E1A1 /* InstanceMethodSwizzler.mm */; };
     
    12651266                5C2936911D5BF63E00DEAB1E /* CookieAcceptPolicy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CookieAcceptPolicy.mm; sourceTree = "<group>"; };
    12661267                5C2936941D5BFD1900DEAB1E /* CookieMessage.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = CookieMessage.html; sourceTree = "<group>"; };
     1268                5C5731041F76D81F00081388 /* JavaScriptDuringNavigation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JavaScriptDuringNavigation.mm; sourceTree = "<group>"; };
    12671269                5C5E633D1D0B67940085A025 /* UniqueRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UniqueRef.cpp; sourceTree = "<group>"; };
    12681270                5C6E65411D5CEF8500F7862E /* URLParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLParser.cpp; sourceTree = "<group>"; };
     
    18721874                                5198A23F1EA7E595008910B7 /* InitialWarmedProcessUsed.mm */,
    18731875                                2DB0232E1E4E871800707123 /* InteractionDeadlockAfterCrash.mm */,
     1876                                5C5731041F76D81F00081388 /* JavaScriptDuringNavigation.mm */,
    18741877                                C25CCA051E51380B0026CB8A /* LineBreaking.mm */,
    18751878                                37D36ED61AF42ECD00BAF5D9 /* LoadAlternateHTMLString.mm */,
     
    31213124                                7C83E0BE1D0A651300FEBCF3 /* IndexedDBMultiProcess.mm in Sources */,
    31223125                                7C83E0BF1D0A652200FEBCF3 /* IndexedDBPersistence.mm in Sources */,
     3126                                5C5731051F76D85000081388 /* JavaScriptDuringNavigation.mm in Sources */,
    31233127                                7CCE7EFB1A411AE600447C4C /* InjectedBundleBasic.cpp in Sources */,
    31243128                                7CCE7EFC1A411AE600447C4C /* InjectedBundleFrameHitTest.cpp in Sources */,
Note: See TracChangeset for help on using the changeset viewer.