LEFT | RIGHT |
1 /* | 1 /* |
2 * Copyright (C) 2014-2016 Apple Inc. All rights reserved. | 2 * Copyright (C) 2014-2016 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 #import "WebNavigationState.h" | 60 #import "WebNavigationState.h" |
61 #import "WebPageProxy.h" | 61 #import "WebPageProxy.h" |
62 #import "WebProcessProxy.h" | 62 #import "WebProcessProxy.h" |
63 #import "WebProtectionSpace.h" | 63 #import "WebProtectionSpace.h" |
64 #import "_WKErrorRecoveryAttempting.h" | 64 #import "_WKErrorRecoveryAttempting.h" |
65 #import "_WKFrameHandleInternal.h" | 65 #import "_WKFrameHandleInternal.h" |
66 #import "_WKRenderingProgressEventsInternal.h" | 66 #import "_WKRenderingProgressEventsInternal.h" |
67 #import "_WKSameDocumentNavigationTypeInternal.h" | 67 #import "_WKSameDocumentNavigationTypeInternal.h" |
68 #import "_WKWebsitePoliciesInternal.h" | 68 #import "_WKWebsitePoliciesInternal.h" |
69 #import <WebCore/Credential.h> | 69 #import <WebCore/Credential.h> |
| 70 #import <WebCore/SSLKeyGenerator.h> |
70 #import <WebCore/SecurityOriginData.h> | 71 #import <WebCore/SecurityOriginData.h> |
71 #import <WebCore/SerializedCryptoKeyWrap.h> | 72 #import <WebCore/SerializedCryptoKeyWrap.h> |
72 #import <WebCore/URL.h> | 73 #import <WebCore/URL.h> |
73 #import <wtf/BlockPtr.h> | 74 #import <wtf/BlockPtr.h> |
74 #import <wtf/NeverDestroyed.h> | 75 #import <wtf/NeverDestroyed.h> |
75 | 76 |
76 #if HAVE(APP_LINKS) | 77 #if HAVE(APP_LINKS) |
77 #import <pal/spi/cocoa/LaunchServicesSPI.h> | 78 #import <pal/spi/cocoa/LaunchServicesSPI.h> |
78 #endif | 79 #endif |
79 | 80 |
(...skipping 10 matching lines...) Expand all Loading... |
90 static NeverDestroyed<HashMap<WebPageProxy*, NavigationState*>> navigationSt
ates; | 91 static NeverDestroyed<HashMap<WebPageProxy*, NavigationState*>> navigationSt
ates; |
91 | 92 |
92 return navigationStates; | 93 return navigationStates; |
93 } | 94 } |
94 | 95 |
95 NavigationState::NavigationState(WKWebView *webView) | 96 NavigationState::NavigationState(WKWebView *webView) |
96 : m_webView(webView) | 97 : m_webView(webView) |
97 , m_navigationDelegateMethods() | 98 , m_navigationDelegateMethods() |
98 , m_historyDelegateMethods() | 99 , m_historyDelegateMethods() |
99 #if PLATFORM(IOS) | 100 #if PLATFORM(IOS) |
100 , m_releaseActivityTimer(RunLoop::current(), this, &NavigationState::release
NetworkActivityToken) | 101 , m_releaseActivityTimer(RunLoop::current(), this, &NavigationState::release
NetworkActivityTokenAfterLoadCompletion) |
101 #endif | 102 #endif |
102 { | 103 { |
103 ASSERT(m_webView->_page); | 104 ASSERT(m_webView->_page); |
104 ASSERT(!navigationStates().contains(m_webView->_page.get())); | 105 ASSERT(!navigationStates().contains(m_webView->_page.get())); |
105 | 106 |
106 navigationStates().add(m_webView->_page.get(), this); | 107 navigationStates().add(m_webView->_page.get(), this); |
107 m_webView->_page->pageLoadState().addObserver(*this); | 108 m_webView->_page->pageLoadState().addObserver(*this); |
108 m_safeBrowsingController = std::make_unique<SafeBrowsingController>(webView)
; | 109 m_safeBrowsingController = std::make_unique<SafeBrowsingController>(webView)
; |
109 } | 110 } |
110 | 111 |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 delete localCompletionHandler; | 472 delete localCompletionHandler; |
472 }); | 473 }); |
473 }]; | 474 }]; |
474 #else | 475 #else |
475 completionHandler(false); | 476 completionHandler(false); |
476 #endif | 477 #endif |
477 } | 478 } |
478 | 479 |
479 void NavigationState::NavigationClient::decidePolicyForNavigationAction(WebPageP
roxy& webPageProxy, Ref<API::NavigationAction>&& navigationAction, Ref<WebFrameP
olicyListenerProxy>&& listener, API::Object* userInfo) | 480 void NavigationState::NavigationClient::decidePolicyForNavigationAction(WebPageP
roxy& webPageProxy, Ref<API::NavigationAction>&& navigationAction, Ref<WebFrameP
olicyListenerProxy>&& listener, API::Object* userInfo) |
480 { | 481 { |
| 482 ASSERT(webPageProxy.mainFrame()); |
481 auto policyDecider = [&webPageProxy, navigationAction = navigationAction.cop
yRef(), userInfo, this] (WTF::Function<void(WKNavigationActionPolicy, std::optio
nal<WebsitePoliciesData>&&)>&& completionHandler) mutable { | 483 auto policyDecider = [&webPageProxy, navigationAction = navigationAction.cop
yRef(), userInfo, this] (WTF::Function<void(WKNavigationActionPolicy, std::optio
nal<WebsitePoliciesData>&&)>&& completionHandler) mutable { |
482 decidePolicyForNavigationActionInternal(webPageProxy, WTFMove(navigation
Action), WTFMove(completionHandler), userInfo); | 484 decidePolicyForNavigationActionInternal(webPageProxy, WTFMove(navigation
Action), WTFMove(completionHandler), userInfo); |
483 }; | 485 }; |
484 m_navigationState.m_safeBrowsingController->checkURL(WTFMove(navigationActio
n), WTFMove(policyDecider), WTFMove(listener)); | 486 m_navigationState.m_safeBrowsingController->checkURL(WTFMove(navigationActio
n), WTFMove(policyDecider), WTFMove(listener)); |
485 } | 487 } |
486 | 488 |
487 void NavigationState::NavigationClient::decidePolicyForNavigationActionInternal(
WebPageProxy& webPageProxy, Ref<API::NavigationAction>&& navigationAction, WTF::
Function<void(WKNavigationActionPolicy, std::optional<WebsitePoliciesData>&&)>&&
completionHandler, API::Object* userInfo) | 489 void NavigationState::NavigationClient::decidePolicyForNavigationActionInternal(
WebPageProxy& webPageProxy, Ref<API::NavigationAction>&& navigationAction, WTF::
Function<void(WKNavigationActionPolicy, std::optional<WebsitePoliciesData>&&)>&&
completionHandler, API::Object* userInfo) |
488 { | 490 { |
489 String mainFrameURLString = webPageProxy.mainFrame()->url(); | 491 String mainFrameURLString = webPageProxy.mainFrame()->url(); |
490 bool subframeNavigation = navigationAction->targetFrame() && !navigationActi
on->targetFrame()->isMainFrame(); | 492 bool subframeNavigation = navigationAction->targetFrame() && !navigationActi
on->targetFrame()->isMainFrame(); |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 FALLTHROUGH; | 980 FALLTHROUGH; |
979 case ProcessTerminationReason::RequestedByClient: | 981 case ProcessTerminationReason::RequestedByClient: |
980 return _WKProcessTerminationReasonRequestedByClient; | 982 return _WKProcessTerminationReasonRequestedByClient; |
981 case ProcessTerminationReason::Crash: | 983 case ProcessTerminationReason::Crash: |
982 return _WKProcessTerminationReasonCrash; | 984 return _WKProcessTerminationReasonCrash; |
983 } | 985 } |
984 ASSERT_NOT_REACHED(); | 986 ASSERT_NOT_REACHED(); |
985 return _WKProcessTerminationReasonCrash; | 987 return _WKProcessTerminationReasonCrash; |
986 } | 988 } |
987 | 989 |
988 void NavigationState::NavigationClient::processDidTerminate(WebPageProxy& page,
ProcessTerminationReason reason) | 990 bool NavigationState::NavigationClient::processDidTerminate(WebPageProxy& page,
ProcessTerminationReason reason) |
989 { | 991 { |
990 if (!m_navigationState.m_navigationDelegateMethods.webViewWebContentProcessD
idTerminate | 992 if (!m_navigationState.m_navigationDelegateMethods.webViewWebContentProcessD
idTerminate |
991 && !m_navigationState.m_navigationDelegateMethods.webViewWebContentProce
ssDidTerminateWithReason | 993 && !m_navigationState.m_navigationDelegateMethods.webViewWebContentProce
ssDidTerminateWithReason |
992 && !m_navigationState.m_navigationDelegateMethods.webViewWebProcessDidCr
ash) | 994 && !m_navigationState.m_navigationDelegateMethods.webViewWebProcessDidCr
ash) |
993 return; | 995 return false; |
994 | 996 |
995 auto navigationDelegate = m_navigationState.m_navigationDelegate.get(); | 997 auto navigationDelegate = m_navigationState.m_navigationDelegate.get(); |
996 if (!navigationDelegate) | 998 if (!navigationDelegate) |
997 return; | 999 return false; |
998 | 1000 |
999 if (m_navigationState.m_navigationDelegateMethods.webViewWebContentProcessDi
dTerminateWithReason) { | 1001 if (m_navigationState.m_navigationDelegateMethods.webViewWebContentProcessDi
dTerminateWithReason) { |
1000 [static_cast<id <WKNavigationDelegatePrivate>>(navigationDelegate.get())
_webView:m_navigationState.m_webView webContentProcessDidTerminateWithReason:wk
ProcessTerminationReason(reason)]; | 1002 [static_cast<id <WKNavigationDelegatePrivate>>(navigationDelegate.get())
_webView:m_navigationState.m_webView webContentProcessDidTerminateWithReason:wk
ProcessTerminationReason(reason)]; |
1001 return; | 1003 return true; |
1002 } | 1004 } |
1003 | 1005 |
1004 // We prefer webViewWebContentProcessDidTerminate: over _webViewWebProcessDi
dCrash:. | 1006 // We prefer webViewWebContentProcessDidTerminate: over _webViewWebProcessDi
dCrash:. |
1005 if (m_navigationState.m_navigationDelegateMethods.webViewWebContentProcessDi
dTerminate) { | 1007 if (m_navigationState.m_navigationDelegateMethods.webViewWebContentProcessDi
dTerminate) { |
1006 [navigationDelegate webViewWebContentProcessDidTerminate:m_navigationSta
te.m_webView]; | 1008 [navigationDelegate webViewWebContentProcessDidTerminate:m_navigationSta
te.m_webView]; |
1007 return; | 1009 return true; |
1008 } | 1010 } |
1009 | 1011 |
1010 ASSERT(m_navigationState.m_navigationDelegateMethods.webViewWebProcessDidCra
sh); | 1012 ASSERT(m_navigationState.m_navigationDelegateMethods.webViewWebProcessDidCra
sh); |
1011 [static_cast<id <WKNavigationDelegatePrivate>>(navigationDelegate.get()) _we
bViewWebProcessDidCrash:m_navigationState.m_webView]; | 1013 [static_cast<id <WKNavigationDelegatePrivate>>(navigationDelegate.get()) _we
bViewWebProcessDidCrash:m_navigationState.m_webView]; |
| 1014 return true; |
1012 } | 1015 } |
1013 | 1016 |
1014 void NavigationState::NavigationClient::processDidBecomeResponsive(WebPageProxy&
page) | 1017 void NavigationState::NavigationClient::processDidBecomeResponsive(WebPageProxy&
page) |
1015 { | 1018 { |
1016 if (!m_navigationState.m_navigationDelegateMethods.webViewWebProcessDidBecom
eResponsive) | 1019 if (!m_navigationState.m_navigationDelegateMethods.webViewWebProcessDidBecom
eResponsive) |
1017 return; | 1020 return; |
1018 | 1021 |
1019 auto navigationDelegate = m_navigationState.m_navigationDelegate.get(); | 1022 auto navigationDelegate = m_navigationState.m_navigationDelegate.get(); |
1020 if (!navigationDelegate) | 1023 if (!navigationDelegate) |
1021 return; | 1024 return; |
(...skipping 27 matching lines...) Expand all Loading... |
1049 if (!navigationDelegate) | 1052 if (!navigationDelegate) |
1050 return nullptr; | 1053 return nullptr; |
1051 | 1054 |
1052 RetainPtr<NSData> data = [static_cast<id <WKNavigationDelegatePrivate>>(navi
gationDelegate.get()) _webCryptoMasterKeyForWebView:m_navigationState.m_webView]
; | 1055 RetainPtr<NSData> data = [static_cast<id <WKNavigationDelegatePrivate>>(navi
gationDelegate.get()) _webCryptoMasterKeyForWebView:m_navigationState.m_webView]
; |
1053 | 1056 |
1054 return API::Data::createWithoutCopying((const unsigned char*)[data bytes], [
data length], [] (unsigned char*, const void* data) { | 1057 return API::Data::createWithoutCopying((const unsigned char*)[data bytes], [
data length], [] (unsigned char*, const void* data) { |
1055 [(NSData *)data release]; | 1058 [(NSData *)data release]; |
1056 }, data.leakRef()); | 1059 }, data.leakRef()); |
1057 } | 1060 } |
1058 | 1061 |
| 1062 RefPtr<API::String> NavigationState::NavigationClient::signedPublicKeyAndChallen
geString(WebPageProxy& page, unsigned keySizeIndex, const RefPtr<API::String>& c
hallengeString, const WebCore::URL& url) |
| 1063 { |
| 1064 // WebKitTestRunner uses C API. Hence, no SPI is provided to override the fo
llowing function. |
| 1065 return API::String::create(WebCore::signedPublicKeyAndChallengeString(keySiz
eIndex, challengeString->string(), url)); |
| 1066 } |
| 1067 |
1059 #if USE(QUICK_LOOK) | 1068 #if USE(QUICK_LOOK) |
1060 void NavigationState::NavigationClient::didStartLoadForQuickLookDocumentInMainFr
ame(const String& fileName, const String& uti) | 1069 void NavigationState::NavigationClient::didStartLoadForQuickLookDocumentInMainFr
ame(const String& fileName, const String& uti) |
1061 { | 1070 { |
1062 if (!m_navigationState.m_navigationDelegateMethods.webViewDidStartLoadForQui
ckLookDocumentInMainFrame) | 1071 if (!m_navigationState.m_navigationDelegateMethods.webViewDidStartLoadForQui
ckLookDocumentInMainFrame) |
1063 return; | 1072 return; |
1064 | 1073 |
1065 auto navigationDelegate = m_navigationState.m_navigationDelegate.get(); | 1074 auto navigationDelegate = m_navigationState.m_navigationDelegate.get(); |
1066 if (!navigationDelegate) | 1075 if (!navigationDelegate) |
1067 return; | 1076 return; |
1068 | 1077 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 | 1149 |
1141 [historyDelegate _webView:m_navigationState.m_webView didUpdateHistoryTitle:
title forURL:[NSURL _web_URLWithWTFString:url]]; | 1150 [historyDelegate _webView:m_navigationState.m_webView didUpdateHistoryTitle:
title forURL:[NSURL _web_URLWithWTFString:url]]; |
1142 } | 1151 } |
1143 | 1152 |
1144 void NavigationState::willChangeIsLoading() | 1153 void NavigationState::willChangeIsLoading() |
1145 { | 1154 { |
1146 [m_webView willChangeValueForKey:@"loading"]; | 1155 [m_webView willChangeValueForKey:@"loading"]; |
1147 } | 1156 } |
1148 | 1157 |
1149 #if PLATFORM(IOS) | 1158 #if PLATFORM(IOS) |
1150 void NavigationState::releaseNetworkActivityToken() | 1159 void NavigationState::releaseNetworkActivityToken(NetworkActivityTokenReleaseRea
son reason) |
1151 { | 1160 { |
1152 RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), ProcessSuspensi
on, "%p UIProcess is releasing a background assertion because a page load comple
ted", this); | 1161 if (!m_activityToken) |
1153 ASSERT(m_activityToken); | 1162 return; |
| 1163 |
| 1164 switch (reason) { |
| 1165 case NetworkActivityTokenReleaseReason::LoadCompleted: |
| 1166 RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), ProcessSusp
ension, "%p NavigationState is releasing background process assertion because a
page load completed", this); |
| 1167 break; |
| 1168 case NetworkActivityTokenReleaseReason::ScreenLocked: |
| 1169 RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), ProcessSusp
ension, "%p NavigationState is releasing background process assertion because th
e screen was locked", this); |
| 1170 break; |
| 1171 } |
1154 m_activityToken = nullptr; | 1172 m_activityToken = nullptr; |
| 1173 m_releaseActivityTimer.stop(); |
1155 } | 1174 } |
1156 #endif | 1175 #endif |
1157 | 1176 |
1158 void NavigationState::didChangeIsLoading() | 1177 void NavigationState::didChangeIsLoading() |
1159 { | 1178 { |
1160 #if PLATFORM(IOS) | 1179 #if PLATFORM(IOS) |
1161 if (m_webView->_page->pageLoadState().isLoading()) { | 1180 if (m_webView->_page->pageLoadState().isLoading()) { |
1162 if (m_releaseActivityTimer.isActive()) | 1181 // We do not take a network activity token if a load starts after the sc
reen has been locked. |
| 1182 if ([UIApp isSuspendedUnderLock]) |
| 1183 return; |
| 1184 |
| 1185 if (m_releaseActivityTimer.isActive()) { |
| 1186 RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), Process
Suspension, "%p - NavigationState keeps its process network assertion because a
new page load started", this); |
1163 m_releaseActivityTimer.stop(); | 1187 m_releaseActivityTimer.stop(); |
1164 else { | 1188 } |
1165 RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), Process
Suspension, "%p - UIProcess is taking a background assertion because a page load
started", this); | 1189 if (!m_activityToken) { |
1166 ASSERT(!m_activityToken); | 1190 RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), Process
Suspension, "%p - NavigationState is taking a process network assertion because
a page load started", this); |
1167 m_activityToken = m_webView->_page->process().throttler().background
ActivityToken(); | 1191 m_activityToken = m_webView->_page->process().throttler().background
ActivityToken(); |
1168 } | 1192 } |
1169 } else { | 1193 } else if (m_activityToken) { |
1170 // Delay releasing the background activity for 3 seconds to give the app
lication a chance to start another navigation | 1194 if (m_webView._isBackground) |
1171 // before suspending the WebContent process <rdar://problem/27910964>. | 1195 releaseNetworkActivityTokenAfterLoadCompletion(); |
1172 m_releaseActivityTimer.startOneShot(3_s); | 1196 else { |
| 1197 // The application is visible so we delay releasing the background a
ctivity for 3 seconds to give it a chance to start another navigation |
| 1198 // before suspending the WebContent process <rdar://problem/27910964
>. |
| 1199 RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), Process
Suspension, "%p - NavigationState will release its process network assertion soo
n because the page load completed", this); |
| 1200 m_releaseActivityTimer.startOneShot(3_s); |
| 1201 } |
1173 } | 1202 } |
1174 #endif | 1203 #endif |
1175 | 1204 |
1176 [m_webView didChangeValueForKey:@"loading"]; | 1205 [m_webView didChangeValueForKey:@"loading"]; |
1177 } | 1206 } |
1178 | 1207 |
1179 void NavigationState::willChangeTitle() | 1208 void NavigationState::willChangeTitle() |
1180 { | 1209 { |
1181 [m_webView willChangeValueForKey:@"title"]; | 1210 [m_webView willChangeValueForKey:@"title"]; |
1182 } | 1211 } |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 } | 1293 } |
1265 | 1294 |
1266 void NavigationState::didChangeWebProcessIsResponsive() | 1295 void NavigationState::didChangeWebProcessIsResponsive() |
1267 { | 1296 { |
1268 [m_webView didChangeValueForKey:@"_webProcessIsResponsive"]; | 1297 [m_webView didChangeValueForKey:@"_webProcessIsResponsive"]; |
1269 } | 1298 } |
1270 | 1299 |
1271 } // namespace WebKit | 1300 } // namespace WebKit |
1272 | 1301 |
1273 #endif | 1302 #endif |
LEFT | RIGHT |