Diff
Modified: trunk/Source/WebKit/ChangeLog (255991 => 255992)
--- trunk/Source/WebKit/ChangeLog 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/ChangeLog 2020-02-07 00:44:34 UTC (rev 255992)
@@ -1,5 +1,49 @@
2020-02-06 Chris Dumez <[email protected]>
+ [WK2][iOS] Add WKWebviewConfiguration SPI to run client navigations at foreground priority, even if the view is background
+ https://bugs.webkit.org/show_bug.cgi?id=207341
+ <rdar://problem/59227077>
+
+ Reviewed by Geoff Garen.
+
+ Add WKWebviewConfiguration SPI to run client navigations at foreground priority, even if the view is background,
+ as long as the application itself is foreground. The new SPI is:
+ WKWebViewConfiguration._clientNavigationsRunAtForegroundPriority
+
+ The use case is that the client may choose to load something in an offscreen view and only show the view once the
+ load is complete (to avoid flashing for e.g.). In such cases, it makes sense to use foreground priority for the
+ load since it needs to complete as fast as possible, even though the view is technically background.
+
+ * UIProcess/API/APINavigation.h:
+ (API::Navigation::setForegroundActivity):
+ * UIProcess/API/APIPageConfiguration.cpp:
+ (API::PageConfiguration::copy const):
+ * UIProcess/API/APIPageConfiguration.h:
+ (API::PageConfiguration::clientNavigationsRunAtForegroundPriority const):
+ (API::PageConfiguration::setClientNavigationsRunAtForegroundPriority):
+ (API::PageConfiguration::alwaysRunsAtForegroundPriority const):
+ (API::PageConfiguration::alwaysRunsAtForegroundPriority): Deleted.
+ * UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
+ (-[WKWebViewConfiguration _clientNavigationsRunAtForegroundPriority]):
+ (-[WKWebViewConfiguration _setClientNavigationsRunAtForegroundPriority:]):
+ * UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
+ * UIProcess/PageClient.h:
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::loadRequest):
+ (WebKit::WebPageProxy::loadFile):
+ (WebKit::WebPageProxy::loadData):
+ (WebKit::WebPageProxy::didFailProvisionalLoadForFrameShared):
+ (WebKit::WebPageProxy::didFinishLoadForFrame):
+ (WebKit::WebPageProxy::didFailLoadForFrame):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/PageClientImplIOS.h:
+ * UIProcess/ios/PageClientImplIOS.mm:
+ (WebKit::PageClientImpl::isApplicationVisible):
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::shouldUseForegroundPriorityForClientNavigation const):
+
+2020-02-06 Chris Dumez <[email protected]>
+
REGRESSION (r254706): Crash under WebProcessPool::terminateServiceWorkerProcess()
https://bugs.webkit.org/show_bug.cgi?id=207354
<rdar://problem/59184818>
Modified: trunk/Source/WebKit/UIProcess/API/APINavigation.h (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/API/APINavigation.h 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/API/APINavigation.h 2020-02-07 00:44:34 UTC (rev 255992)
@@ -29,6 +29,7 @@
#include "DataReference.h"
#include "FrameInfoData.h"
#include "NavigationActionData.h"
+#include "ProcessThrottler.h"
#include "WebBackForwardListItem.h"
#include "WebContentMode.h"
#include <WebCore/AdClickAttribution.h>
@@ -153,6 +154,8 @@
const Optional<WebCore::AdClickAttribution>& adClickAttribution() const { return m_lastNavigationAction.adClickAttribution; }
+ void setForegroundActivity(std::unique_ptr<WebKit::ProcessThrottler::ForegroundActivity>&& activity) { m_foregroundActivity = WTFMove(activity); }
+
private:
explicit Navigation(WebKit::WebNavigationState&);
Navigation(WebKit::WebNavigationState&, WebCore::ResourceRequest&&, WebKit::WebBackForwardListItem* fromItem);
@@ -174,6 +177,7 @@
WebCore::SecurityOriginData m_destinationFrameSecurityOrigin;
bool m_userContentExtensionsEnabled { true };
WebKit::WebContentMode m_effectiveContentMode { WebKit::WebContentMode::Recommended };
+ std::unique_ptr<WebKit::ProcessThrottler::ForegroundActivity> m_foregroundActivity;
};
} // namespace API
Modified: trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp 2020-02-07 00:44:34 UTC (rev 255992)
@@ -73,6 +73,7 @@
copy->m_visitedLinkStore = this->m_visitedLinkStore;
copy->m_websiteDataStore = this->m_websiteDataStore;
#if PLATFORM(IOS_FAMILY)
+ copy->m_clientNavigationsRunAtForegroundPriority = this->m_clientNavigationsRunAtForegroundPriority;
copy->m_alwaysRunsAtForegroundPriority = this->m_alwaysRunsAtForegroundPriority;
copy->m_canShowWhileLocked = this->m_canShowWhileLocked;
copy->m_clickInteractionDriverForTesting = this->m_clickInteractionDriverForTesting;
Modified: trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h 2020-02-07 00:44:34 UTC (rev 255992)
@@ -92,7 +92,9 @@
void setDefaultWebsitePolicies(WebsitePolicies*);
#if PLATFORM(IOS_FAMILY)
- bool alwaysRunsAtForegroundPriority() { return m_alwaysRunsAtForegroundPriority; }
+ bool clientNavigationsRunAtForegroundPriority() const { return m_clientNavigationsRunAtForegroundPriority; }
+ void setClientNavigationsRunAtForegroundPriority(bool value) { m_clientNavigationsRunAtForegroundPriority = value; }
+ bool alwaysRunsAtForegroundPriority() const { return m_alwaysRunsAtForegroundPriority; }
void setAlwaysRunsAtForegroundPriority(bool alwaysRunsAtForegroundPriority) { m_alwaysRunsAtForegroundPriority = alwaysRunsAtForegroundPriority; }
bool canShowWhileLocked() const { return m_canShowWhileLocked; }
@@ -153,6 +155,7 @@
RefPtr<WebsitePolicies> m_defaultWebsitePolicies;
#if PLATFORM(IOS_FAMILY)
+ bool m_clientNavigationsRunAtForegroundPriority { false };
bool m_alwaysRunsAtForegroundPriority { false };
bool m_canShowWhileLocked { false };
RetainPtr<_UIClickInteractionDriving> m_clickInteractionDriverForTesting;
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm 2020-02-07 00:44:34 UTC (rev 255992)
@@ -705,6 +705,16 @@
}
#if PLATFORM(IOS_FAMILY)
+- (BOOL)_clientNavigationsRunAtForegroundPriority
+{
+ return _pageConfiguration->clientNavigationsRunAtForegroundPriority();
+}
+
+- (void)_setClientNavigationsRunAtForegroundPriority:(BOOL)clientNavigationsRunAtForegroundPriority
+{
+ _pageConfiguration->setClientNavigationsRunAtForegroundPriority(clientNavigationsRunAtForegroundPriority);
+}
+
- (BOOL)_alwaysRunsAtForegroundPriority
{
return _pageConfiguration->alwaysRunsAtForegroundPriority();
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h 2020-02-07 00:44:34 UTC (rev 255992)
@@ -85,6 +85,7 @@
@property (nonatomic, copy, setter=_setCORSDisablingPatterns:) NSArray<NSString *> *_corsDisablingPatterns WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
#if TARGET_OS_IPHONE
+@property (nonatomic, setter=_setClientNavigationsRunAtForegroundPriority:) BOOL _clientNavigationsRunAtForegroundPriority WK_API_AVAILABLE(ios(WK_IOS_TBA));
@property (nonatomic, setter=_setAlwaysRunsAtForegroundPriority:) BOOL _alwaysRunsAtForegroundPriority WK_API_AVAILABLE(ios(9_0));
@property (nonatomic, setter=_setInlineMediaPlaybackRequiresPlaysInlineAttribute:) BOOL _inlineMediaPlaybackRequiresPlaysInlineAttribute WK_API_AVAILABLE(ios(10.0));
@property (nonatomic, setter=_setAllowsInlineMediaPlaybackAfterFullscreen:) BOOL _allowsInlineMediaPlaybackAfterFullscreen WK_API_AVAILABLE(ios(10.0));
Modified: trunk/Source/WebKit/UIProcess/ApplicationStateTracker.h (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/ApplicationStateTracker.h 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/ApplicationStateTracker.h 2020-02-07 00:44:34 UTC (rev 255992)
@@ -34,6 +34,7 @@
OBJC_CLASS BKSApplicationStateMonitor;
OBJC_CLASS UIView;
+OBJC_CLASS UIWindow;
namespace WebKit {
@@ -64,6 +65,14 @@
id m_willEnterForegroundObserver;
};
+enum class ApplicationType {
+ Application,
+ ViewService,
+ Extension,
+};
+
+ApplicationType applicationType(UIWindow *);
+
}
#endif
Modified: trunk/Source/WebKit/UIProcess/ApplicationStateTracker.mm (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/ApplicationStateTracker.mm 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/ApplicationStateTracker.mm 2020-02-07 00:44:34 UTC (rev 255992)
@@ -50,13 +50,7 @@
namespace WebKit {
-enum class ApplicationType {
- Application,
- ViewService,
- Extension,
-};
-
-static ApplicationType applicationType(UIWindow *window)
+ApplicationType applicationType(UIWindow *window)
{
ASSERT(window);
Modified: trunk/Source/WebKit/UIProcess/PageClient.h (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/PageClient.h 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/PageClient.h 2020-02-07 00:44:34 UTC (rev 255992)
@@ -196,6 +196,11 @@
// Return whether the view is visible.
virtual bool isViewVisible() = 0;
+#if PLATFORM(IOS_FAMILY)
+ // Return whether the application is visible.
+ virtual bool isApplicationVisible() = 0;
+#endif
+
// Return whether the view is visible, or occluded by another window.
virtual bool isViewVisibleOrOccluded() { return isViewVisible(); }
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2020-02-07 00:44:34 UTC (rev 255992)
@@ -1255,6 +1255,10 @@
launchProcess(RegistrableDomain { request.url() }, ProcessLaunchReason::InitialProcess);
auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(request), m_backForwardList->currentItem());
+
+ if (shouldUseForegroundPriorityForClientNavigation())
+ navigation->setForegroundActivity(process().throttler().foregroundActivity("Client navigation"_s).moveToUniquePtr());
+
loadRequestWithNavigationShared(m_process.copyRef(), m_webPageID, navigation.get(), WTFMove(request), shouldOpenExternalURLsPolicy, userData, ShouldTreatAsContinuingLoad::No);
return navigation;
}
@@ -1327,6 +1331,9 @@
auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(fileURL), m_backForwardList->currentItem());
+ if (shouldUseForegroundPriorityForClientNavigation())
+ navigation->setForegroundActivity(process().throttler().foregroundActivity("Client navigation"_s).moveToUniquePtr());
+
auto transaction = m_pageLoadState.transaction();
m_pageLoadState.setPendingAPIRequest(transaction, { navigation->navigationID(), fileURLString }, resourceDirectoryURL);
@@ -1366,6 +1373,10 @@
launchProcess({ }, ProcessLaunchReason::InitialProcess);
auto navigation = m_navigationState->createLoadDataNavigation(makeUnique<API::SubstituteData>(data.vector(), MIMEType, encoding, baseURL, userData));
+
+ if (shouldUseForegroundPriorityForClientNavigation())
+ navigation->setForegroundActivity(process().throttler().foregroundActivity("Client navigation"_s).moveToUniquePtr());
+
loadDataWithNavigationShared(m_process.copyRef(), m_webPageID, navigation, data, MIMEType, encoding, baseURL, userData, ShouldTreatAsContinuingLoad::No, WTF::nullopt, shouldOpenExternalURLsPolicy);
return navigation;
}
@@ -4429,6 +4440,8 @@
reportPageLoadResult(error);
m_pageLoadState.didFailProvisionalLoad(transaction);
pageClient().didFailProvisionalLoadForMainFrame();
+ if (navigation)
+ navigation->setForegroundActivity(nullptr);
}
frame->didFailProvisionalLoad();
@@ -4661,6 +4674,9 @@
reportPageLoadResult();
pageClient().didFinishLoadForMainFrame();
+ if (navigation)
+ navigation->setForegroundActivity(nullptr);
+
resetRecentCrashCountSoon();
notifyProcessPoolToPrewarm();
@@ -4708,6 +4724,8 @@
if (isMainFrame) {
reportPageLoadResult(error);
pageClient().didFailLoadForMainFrame();
+ if (navigation)
+ navigation->setForegroundActivity(nullptr);
}
}
@@ -9815,6 +9833,13 @@
send(Messages::WebPage::SetOverriddenMediaType(mediaType));
}
+#if !PLATFORM(IOS_FAMILY)
+bool WebPageProxy::shouldUseForegroundPriorityForClientNavigation() const
+{
+ return false;
+}
+#endif
+
void WebPageProxy::setOrientationForMediaCapture(uint64_t orientation)
{
#if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-02-07 00:44:34 UTC (rev 255992)
@@ -1692,6 +1692,8 @@
void notifyProcessPoolToPrewarm();
bool shouldUseBackForwardCache() const;
+ bool shouldUseForegroundPriorityForClientNavigation() const;
+
RefPtr<API::Navigation> goToBackForwardItem(WebBackForwardListItem&, WebCore::FrameLoadType);
void updateActivityState(OptionSet<WebCore::ActivityState::Flag> flagsToUpdate = WebCore::ActivityState::allFlags());
Modified: trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h 2020-02-07 00:44:34 UTC (rev 255992)
@@ -63,6 +63,7 @@
bool isViewWindowActive() override;
bool isViewFocused() override;
bool isViewVisible() override;
+ bool isApplicationVisible() override;
bool isViewInWindow() override;
bool isViewVisibleOrOccluded() override;
bool isVisuallyIdle() override;
Modified: trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm 2020-02-07 00:44:34 UTC (rev 255992)
@@ -29,6 +29,8 @@
#if PLATFORM(IOS_FAMILY)
#import "APIData.h"
+#import "ApplicationStateTracker.h"
+#import "AssertionServicesSPI.h"
#import "DataReference.h"
#import "DownloadProxy.h"
#import "DrawingAreaProxy.h"
@@ -68,9 +70,14 @@
#import <WebCore/TextIndicator.h>
#import <WebCore/ValidationBubble.h>
#import <wtf/BlockPtr.h>
+#import <wtf/cocoa/Entitlements.h>
#define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_webView.get()->_page->process().connection())
+@interface UIWindow ()
+- (BOOL)_isHostedInAnotherProcess;
+@end
+
namespace WebKit {
using namespace WebCore;
@@ -141,6 +148,34 @@
return false;
}
+bool PageClientImpl::isApplicationVisible()
+{
+ switch (applicationType([m_webView window])) {
+ case ApplicationType::Application:
+ return [[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground;
+ case ApplicationType::ViewService:
+ case ApplicationType::Extension:
+ break;
+ }
+
+ UIViewController *serviceViewController = nil;
+ for (UIView *view = m_webView.get().get(); view; view = view.superview) {
+ UIViewController *viewController = [UIViewController viewControllerForView:view];
+ if (viewController._hostProcessIdentifier) {
+ serviceViewController = viewController;
+ break;
+ }
+ }
+ ASSERT(serviceViewController);
+ pid_t applicationPID = serviceViewController._hostProcessIdentifier;
+ ASSERT(applicationPID);
+
+ auto applicationStateMonitor = adoptNS([[BKSApplicationStateMonitor alloc] init]);
+ auto applicationState = [applicationStateMonitor mostElevatedApplicationStateForPID:applicationPID];
+ [applicationStateMonitor invalidate];
+ return applicationState != BKSApplicationStateBackgroundRunning && applicationState != BKSApplicationStateBackgroundTaskSuspended;
+}
+
bool PageClientImpl::isViewInWindow()
{
// FIXME: in WebKitTestRunner, m_webView is nil, so check the content view instead.
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (255991 => 255992)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2020-02-06 23:42:06 UTC (rev 255991)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2020-02-07 00:44:34 UTC (rev 255992)
@@ -29,6 +29,7 @@
#if PLATFORM(IOS_FAMILY)
#import "APINavigationAction.h"
+#import "APIPageConfiguration.h"
#import "APIUIClient.h"
#import "APIWebsitePolicies.h"
#import "Connection.h"
@@ -1500,6 +1501,19 @@
return WebContentMode::Desktop;
}
+bool WebPageProxy::shouldUseForegroundPriorityForClientNavigation() const
+{
+ // The client may request that we do client navigations at foreground priority, even if the
+ // view is not visible, as long as the application is foreground.
+ if (!configuration().clientNavigationsRunAtForegroundPriority())
+ return false;
+
+ if (isViewVisible())
+ return false;
+
+ return pageClient().isApplicationVisible();
+}
+
#if PLATFORM(IOS)
void WebPageProxy::grantAccessToAssetServices()
{