https://bugs.webkit.org/show_bug.cgi?id=191602
Reviewed by Alex Christensen.
Source/WebKit:
Add support for process swapping for a [WKWebView loadHTML:] load by storing
the necessary data on the API::Navigation and doing a loadData() instead of
a loadRequest() after process swapping when this data is present on the
navigation.
* UIProcess/API/APINavigation.cpp:
(API::Navigation::Navigation):
* UIProcess/API/APINavigation.h:
(API::Navigation::create):
(API::Navigation::substituteData const):
* UIProcess/WebNavigationState.cpp:
(WebKit::WebNavigationState::createLoadDataNavigation):
* UIProcess/WebNavigationState.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::loadData):
(WebKit::WebPageProxy::continueNavigationInNewProcess):
Tools:
Add API test coverage.
* TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238179
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2018-11-14 Chris Dumez <cdumez@apple.com>
+
+ WebKit.ApplicationManifestBasic API test is failing when enabling PSON
+ https://bugs.webkit.org/show_bug.cgi?id=191602
+
+ Reviewed by Alex Christensen.
+
+ Add support for process swapping for a [WKWebView loadHTML:] load by storing
+ the necessary data on the API::Navigation and doing a loadData() instead of
+ a loadRequest() after process swapping when this data is present on the
+ navigation.
+
+ * UIProcess/API/APINavigation.cpp:
+ (API::Navigation::Navigation):
+ * UIProcess/API/APINavigation.h:
+ (API::Navigation::create):
+ (API::Navigation::substituteData const):
+ * UIProcess/WebNavigationState.cpp:
+ (WebKit::WebNavigationState::createLoadDataNavigation):
+ * UIProcess/WebNavigationState.h:
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::loadData):
+ (WebKit::WebPageProxy::continueNavigationInNewProcess):
+
2018-11-14 Antti Koivisto <antti@apple.com>
Align Mac WK2 layer flush throttling with iOS
{
}
+Navigation::Navigation(WebKit::WebNavigationState& state, std::unique_ptr<SubstituteData>&& substituteData)
+ : Navigation(state)
+{
+ ASSERT(substituteData);
+ m_substituteData = WTFMove(substituteData);
+}
+
Navigation::~Navigation()
{
}
#pragma once
#include "APIObject.h"
+#include "DataReference.h"
#include "WebBackForwardListItem.h"
#include <WebCore/Process.h>
#include <WebCore/ResourceRequest.h>
namespace API {
+struct SubstituteData {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ SubstituteData(Vector<uint8_t>&& content, const WTF::String& MIMEType, const WTF::String& encoding, const WTF::String& baseURL, API::Object* userData)
+ : content(WTFMove(content))
+ , MIMEType(MIMEType)
+ , encoding(encoding)
+ , baseURL(baseURL)
+ , userData(userData)
+ { }
+
+ Vector<uint8_t> content;
+ WTF::String MIMEType;
+ WTF::String encoding;
+ WTF::String baseURL;
+ RefPtr<API::Object> userData;
+};
+
class Navigation : public ObjectImpl<Object::Type::Navigation> {
WTF_MAKE_NONCOPYABLE(Navigation);
public:
return adoptRef(*new Navigation(state, WTFMove(request), fromItem));
}
+ static Ref<Navigation> create(WebKit::WebNavigationState& state, std::unique_ptr<SubstituteData>&& substituteData)
+ {
+ return adoptRef(*new Navigation(state, WTFMove(substituteData)));
+ }
+
virtual ~Navigation();
uint64_t navigationID() const { return m_navigationID; }
const char* loggingString() const;
#endif
+ const std::unique_ptr<SubstituteData>& substituteData() const { return m_substituteData; }
+
private:
explicit Navigation(WebKit::WebNavigationState&);
Navigation(WebKit::WebNavigationState&, WebCore::ResourceRequest&&, WebKit::WebBackForwardListItem* fromItem);
Navigation(WebKit::WebNavigationState&, WebKit::WebBackForwardListItem& targetItem, WebKit::WebBackForwardListItem* fromItem, WebCore::FrameLoadType);
+ Navigation(WebKit::WebNavigationState&, std::unique_ptr<SubstituteData>&&);
uint64_t m_navigationID;
WebCore::ResourceRequest m_originalRequest;
WebCore::LockHistory m_lockHistory;
WebCore::LockBackForwardList m_lockBackForwardList;
WTF::String m_clientRedirectSourceForHistory;
+ std::unique_ptr<SubstituteData> m_substituteData;
};
} // namespace API
return navigation;
}
-Ref<API::Navigation> WebNavigationState::createLoadDataNavigation()
+Ref<API::Navigation> WebNavigationState::createLoadDataNavigation(std::unique_ptr<API::SubstituteData>&& substituteData)
{
- auto navigation = API::Navigation::create(*this);
+ auto navigation = API::Navigation::create(*this, WTFMove(substituteData));
m_navigations.set(navigation->navigationID(), navigation.ptr());
namespace API {
class Navigation;
+struct SubstituteData;
}
namespace WebCore {
Ref<API::Navigation> createBackForwardNavigation(WebBackForwardListItem& targetItem, WebBackForwardListItem* currentItem, WebCore::FrameLoadType);
Ref<API::Navigation> createLoadRequestNavigation(WebCore::ResourceRequest&&, WebBackForwardListItem* currentItem);
Ref<API::Navigation> createReloadNavigation();
- Ref<API::Navigation> createLoadDataNavigation();
+ Ref<API::Navigation> createLoadDataNavigation(std::unique_ptr<API::SubstituteData>&&);
API::Navigation* navigation(uint64_t navigationID);
RefPtr<API::Navigation> takeNavigation(uint64_t navigationID);
if (m_isClosed)
return nullptr;
- auto navigation = m_navigationState->createLoadDataNavigation();
+ auto navigation = m_navigationState->createLoadDataNavigation(std::make_unique<API::SubstituteData>(data.vector(), MIMEType, encoding, baseURL, userData));
+ loadDataWithNavigation(navigation, data, MIMEType, encoding, baseURL, userData);
+ return WTFMove(navigation);
+}
+
+void WebPageProxy::loadDataWithNavigation(API::Navigation& navigation, const IPC::DataReference& data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData)
+{
+ ASSERT(!m_isClosed);
auto transaction = m_pageLoadState.transaction();
reattachToWebProcess();
LoadParameters loadParameters;
- loadParameters.navigationID = navigation->navigationID();
+ loadParameters.navigationID = navigation.navigationID();
loadParameters.data = data;
loadParameters.MIMEType = MIMEType;
loadParameters.encodingName = encoding;
m_process->assumeReadAccessToBaseURL(baseURL);
m_process->send(Messages::WebPage::LoadData(loadParameters), m_pageID);
m_process->responsivenessTimer().start();
-
- return WTFMove(navigation);
}
void WebPageProxy::loadAlternateHTML(const IPC::DataReference& htmlData, const String& encoding, const WebCore::URL& baseURL, const WebCore::URL& unreachableURL, API::Object* userData, bool forSafeBrowsing)
// FIXME: Work out timing of responding with the last policy delegate, etc
ASSERT(!navigation.currentRequest().isEmpty());
- loadRequestWithNavigation(navigation, ResourceRequest { navigation.currentRequest() }, WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes, nullptr, ShouldTreatAsContinuingLoad::Yes);
+ if (auto& substituteData = navigation.substituteData())
+ loadDataWithNavigation(navigation, { substituteData->content.data(), substituteData->content.size() }, substituteData->MIMEType, substituteData->encoding, substituteData->baseURL, substituteData->userData.get());
+ else
+ loadRequestWithNavigation(navigation, ResourceRequest { navigation.currentRequest() }, WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes, nullptr, ShouldTreatAsContinuingLoad::Yes);
ASSERT(!m_mainFrame);
m_mainFrameCreationHandler = [this, protectedThis = makeRef(*this), navigation = makeRef(navigation), request = navigation.currentRequest(), mainFrameURL, isServerRedirect = navigation.currentRequestIsRedirect()]() mutable {
RefPtr<API::Navigation> reattachToWebProcessForReload();
RefPtr<API::Navigation> reattachToWebProcessWithItem(WebBackForwardListItem&);
+ void loadDataWithNavigation(API::Navigation&, const IPC::DataReference&, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr);
void loadRequestWithNavigation(API::Navigation&, WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData, WebCore::ShouldTreatAsContinuingLoad);
void requestNotificationPermission(uint64_t notificationID, const String& originString);
+2018-11-14 Chris Dumez <cdumez@apple.com>
+
+ WebKit.ApplicationManifestBasic API test is failing when enabling PSON
+ https://bugs.webkit.org/show_bug.cgi?id=191602
+
+ Reviewed by Alex Christensen.
+
+ Add API test coverage.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+
2018-11-14 Jonathan Bedard <jbedard@apple.com>
webkitpy: Refactor port code for devices
EXPECT_WK_STREQ(@"pson://www.webkit.org/main.html", [backForwardList.backItem.URL absoluteString]);
}
+TEST(ProcessSwap, SwapOnLoadHTMLString)
+{
+ auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+ processPoolConfiguration.get().processSwapsOnNavigation = YES;
+ auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+ auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ [webViewConfiguration setProcessPool:processPool.get()];
+ auto handler = adoptNS([[PSONScheme alloc] init]);
+ [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"pson"];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+ auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]];
+ [webView loadRequest:request];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ auto pid1 = [webView _webProcessIdentifier];
+
+ NSString *htmlString = @"<html><body>substituteData</body></html>";
+ [webView loadHTMLString:htmlString baseURL:[NSURL URLWithString:@"http://example.com"]];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ auto pid2 = [webView _webProcessIdentifier];
+ EXPECT_NE(pid1, pid2);
+
+ [webView evaluateJavaScript:@"document.body.innerText" completionHandler:^(id innerText, NSError *error) {
+ EXPECT_WK_STREQ(@"substituteData", (NSString *)innerText);
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+}
+
#if PLATFORM(MAC)
TEST(ProcessSwap, GoBackToSuspendedPageWithMainFrameIDThatIsNotOne)