Changeset 245328 in webkit
- Timestamp:
- May 15, 2019 10:40:01 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r245327 r245328 1 2019-05-15 Youenn Fablet <youenn@apple.com> 2 3 Reuse existing WebPageProxy quota handler for NetworkProcessProxy quota requests 4 https://bugs.webkit.org/show_bug.cgi?id=197463 5 <rdar://problem/47403621> 6 7 Reviewed by Alex Christensen. 8 9 Add a getter to know whether websitedatastore client implements the quota delegate. 10 If not, find the most visible page that is the same origin as the quota request 11 and reuse the existing exceededDatabasQuota delegate. 12 This approach allows to call the delegate even if the quota request comes from a service worker. 13 If no such page is found, the quota will not be increased. 14 15 Refactoring to make sure we are calling the delegate once a previous call to that delegate is completed. 16 Covered by API test. 17 18 * UIProcess/API/Cocoa/WKWebsiteDataStore.mm: 19 * UIProcess/Network/NetworkProcessProxy.cpp: 20 (WebKit::NetworkProcessProxy::requestStorageSpace): 21 * UIProcess/WebPageProxy.cpp: 22 (WebKit::StorageRequests::add): 23 (WebKit::StorageRequests::processNext): 24 (WebKit::StorageRequests::areBeingProcessed const): 25 (WebKit::StorageRequests::setAreBeingProcessed): 26 (WebKit::StorageRequests::StorageRequests): 27 (WebKit::StorageRequests::~StorageRequests): 28 (WebKit::StorageRequests::singleton): 29 (WebKit::WebPageProxy::forMostVisibleWebPageIfAny): 30 (WebKit::WebPageProxy::didChangeMainDocument): 31 (WebKit::WebPageProxy::exceededDatabaseQuota): 32 (WebKit::WebPageProxy::requestStorageSpace): 33 (WebKit::WebPageProxy::makeStorageSpaceRequest): 34 * UIProcess/WebPageProxy.h: 35 * UIProcess/WebProcessProxy.cpp: 36 (WebKit::WebProcessProxy::forWebPages): 37 * UIProcess/WebProcessProxy.h: 38 * UIProcess/WebsiteData/WebsiteDataStoreClient.h: 39 (WebKit::WebsiteDataStoreClient::implementsRequestStorageSpaceHandler const): 40 1 41 2019-05-15 Youenn Fablet <youenn@apple.com> 2 42 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
r244572 r245328 44 44 #import <wtf/WeakObjCPtr.h> 45 45 46 class WebsiteDataStoreClient : public WebKit::WebsiteDataStoreClient {46 class WebsiteDataStoreClient final : public WebKit::WebsiteDataStoreClient { 47 47 public: 48 48 explicit WebsiteDataStoreClient(id <_WKWebsiteDataStoreDelegate> delegate) -
trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp
r245025 r245328 1142 1142 #endif 1143 1143 1144 void NetworkProcessProxy::requestStorageSpace(PAL::SessionID sessionID, const WebCore::ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&& completionHandler)1144 void NetworkProcessProxy::requestStorageSpace(PAL::SessionID sessionID, const WebCore::ClientOrigin& origin, uint64_t currentQuota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&& completionHandler) 1145 1145 { 1146 1146 auto* store = websiteDataStoreFromSessionID(sessionID); … … 1151 1151 } 1152 1152 1153 store->client().requestStorageSpace(origin.topOrigin, origin.clientOrigin, quota, currentSize, spaceRequired, WTFMove(completionHandler)); 1153 store->client().requestStorageSpace(origin.topOrigin, origin.clientOrigin, currentQuota, currentSize, spaceRequired, [sessionID, origin, currentQuota, currentSize, spaceRequired, completionHandler = WTFMove(completionHandler)](auto quota) mutable { 1154 if (quota) { 1155 completionHandler(quota); 1156 return; 1157 } 1158 1159 if (origin.topOrigin != origin.clientOrigin) { 1160 completionHandler({ }); 1161 return; 1162 } 1163 1164 WebPageProxy::forMostVisibleWebPageIfAny(sessionID, origin.topOrigin, [completionHandler = WTFMove(completionHandler), origin, currentQuota, currentSize, spaceRequired](auto* page) mutable { 1165 if (!page) { 1166 completionHandler({ }); 1167 return; 1168 } 1169 String name = makeString(FileSystem::encodeForFileName(origin.topOrigin.host), " content"); 1170 page->requestStorageSpace(page->mainFrame()->frameID(), origin.topOrigin.databaseIdentifier(), name, name, currentQuota, currentSize, currentSize, spaceRequired, [completionHandler = WTFMove(completionHandler)](auto quota) mutable { 1171 completionHandler(quota); 1172 }); 1173 }); 1174 }); 1154 1175 } 1155 1176 -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r245255 r245328 265 265 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy")); 266 266 267 class ExceededDatabaseQuotaRecords {268 WTF_MAKE_NONCOPYABLE( ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;269 friend NeverDestroyed< ExceededDatabaseQuotaRecords>;267 class StorageRequests { 268 WTF_MAKE_NONCOPYABLE(StorageRequests); WTF_MAKE_FAST_ALLOCATED; 269 friend NeverDestroyed<StorageRequests>; 270 270 public: 271 struct Record { 272 uint64_t frameID; 273 String originIdentifier; 274 String databaseName; 275 String displayName; 276 uint64_t currentQuota; 277 uint64_t currentOriginUsage; 278 uint64_t currentDatabaseUsage; 279 uint64_t expectedUsage; 280 Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply reply; 281 }; 282 283 static ExceededDatabaseQuotaRecords& singleton(); 284 285 std::unique_ptr<Record> createRecord(uint64_t frameID, String originIdentifier, 286 String databaseName, String displayName, uint64_t currentQuota, 287 uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, 288 Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply&&); 289 290 void add(std::unique_ptr<Record>); 291 bool areBeingProcessed() const { return !!m_currentRecord; } 292 Record* next(); 271 static StorageRequests& singleton(); 272 273 void processOrAppend(CompletionHandler<void()>&& completionHandler) 274 { 275 if (m_requestsAreBeingProcessed) { 276 m_requests.append(WTFMove(completionHandler)); 277 return; 278 } 279 m_requestsAreBeingProcessed = true; 280 completionHandler(); 281 } 282 283 void processNextIfAny() 284 { 285 if (m_requests.isEmpty()) { 286 m_requestsAreBeingProcessed = false; 287 return; 288 } 289 m_requests.takeFirst()(); 290 } 293 291 294 292 private: 295 ExceededDatabaseQuotaRecords() { }296 ~ ExceededDatabaseQuotaRecords() { }297 298 Deque< std::unique_ptr<Record>> m_records;299 std::unique_ptr<Record> m_currentRecord;293 StorageRequests() { } 294 ~StorageRequests() { } 295 296 Deque<CompletionHandler<void()>> m_requests; 297 bool m_requestsAreBeingProcessed { false }; 300 298 }; 301 299 302 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::singleton() 303 { 304 static NeverDestroyed<ExceededDatabaseQuotaRecords> records; 305 return records; 306 } 307 308 std::unique_ptr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord( 309 uint64_t frameID, String originIdentifier, String databaseName, String displayName, 310 uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, 311 uint64_t expectedUsage, Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply&& reply) 312 { 313 auto record = std::make_unique<Record>(); 314 record->frameID = frameID; 315 record->originIdentifier = originIdentifier; 316 record->databaseName = databaseName; 317 record->displayName = displayName; 318 record->currentQuota = currentQuota; 319 record->currentOriginUsage = currentOriginUsage; 320 record->currentDatabaseUsage = currentDatabaseUsage; 321 record->expectedUsage = expectedUsage; 322 record->reply = WTFMove(reply); 323 return record; 324 } 325 326 void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record) 327 { 328 m_records.append(WTFMove(record)); 329 } 330 331 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next() 332 { 333 m_currentRecord = nullptr; 334 if (!m_records.isEmpty()) 335 m_currentRecord = m_records.takeFirst(); 336 return m_currentRecord.get(); 300 StorageRequests& StorageRequests::singleton() 301 { 302 static NeverDestroyed<StorageRequests> requests; 303 return requests; 337 304 } 338 305 … … 395 362 WeakPtr<PageClient> m_pageClient; 396 363 }; 364 365 void WebPageProxy::forMostVisibleWebPageIfAny(PAL::SessionID sessionID, const SecurityOriginData& origin, CompletionHandler<void(WebPageProxy*)>&& completionHandler) 366 { 367 // FIXME: If not finding right away a visible page, we might want to try again for a given period of time when there is a change of visibility. 368 WebPageProxy* selectedPage = nullptr; 369 WebProcessProxy::forWebPagesWithOrigin(sessionID, origin, [&](auto& page) { 370 if (!page.mainFrame()) 371 return; 372 if (page.isViewVisible() && (!selectedPage || !selectedPage->isViewVisible())) { 373 selectedPage = &page; 374 return; 375 } 376 if (page.isViewFocused() && (!selectedPage || !selectedPage->isViewFocused())) { 377 selectedPage = &page; 378 return; 379 } 380 }); 381 completionHandler(selectedPage); 382 } 397 383 398 384 Ref<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, Ref<API::PageConfiguration>&& configuration) … … 4416 4402 UNUSED_PARAM(frameID); 4417 4403 #endif 4404 m_isQuotaIncreaseDenied = false; 4418 4405 } 4419 4406 … … 7264 7251 void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply&& reply) 7265 7252 { 7266 ExceededDatabaseQuotaRecords& records = ExceededDatabaseQuotaRecords::singleton(); 7267 std::unique_ptr<ExceededDatabaseQuotaRecords::Record> newRecord = records.createRecord(frameID, 7268 originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage, 7269 currentDatabaseUsage, expectedUsage, WTFMove(reply)); 7270 records.add(WTFMove(newRecord)); 7271 7272 if (records.areBeingProcessed()) 7273 return; 7274 7275 ExceededDatabaseQuotaRecords::Record* record = records.next(); 7276 while (record) { 7277 WebFrameProxy* frame = m_process->webFrame(record->frameID); 7278 MESSAGE_CHECK(m_process, frame); 7279 7280 auto origin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(record->originIdentifier)->securityOrigin()); 7281 m_uiClient->exceededDatabaseQuota(this, frame, origin.ptr(), record->databaseName, record->displayName, record->currentQuota, record->currentOriginUsage, record->currentDatabaseUsage, record->expectedUsage, WTFMove(record->reply)); 7282 record = records.next(); 7283 } 7253 requestStorageSpace(frameID, originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, [reply = WTFMove(reply)](auto quota) mutable { 7254 reply(quota); 7255 }); 7256 } 7257 7258 void WebPageProxy::requestStorageSpace(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, CompletionHandler<void(uint64_t)>&& completionHandler) 7259 { 7260 StorageRequests::singleton().processOrAppend([this, protectedThis = makeRef(*this), pageURL = currentURL(), frameID, originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, completionHandler = WTFMove(completionHandler)]() mutable { 7261 this->makeStorageSpaceRequest(frameID, originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, [this, protectedThis = WTFMove(protectedThis), pageURL = WTFMove(pageURL), completionHandler = WTFMove(completionHandler), currentQuota](auto quota) mutable { 7262 if (quota <= currentQuota && this->currentURL() == pageURL) 7263 m_isQuotaIncreaseDenied = true; 7264 completionHandler(quota); 7265 StorageRequests::singleton().processNextIfAny(); 7266 }); 7267 }); 7268 } 7269 7270 void WebPageProxy::makeStorageSpaceRequest(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, CompletionHandler<void(uint64_t)>&& completionHandler) 7271 { 7272 if (m_isQuotaIncreaseDenied) { 7273 completionHandler(currentQuota); 7274 return; 7275 } 7276 7277 WebFrameProxy* frame = m_process->webFrame(frameID); 7278 MESSAGE_CHECK(m_process, frame); 7279 7280 auto originData = SecurityOriginData::fromDatabaseIdentifier(originIdentifier); 7281 if (originData != SecurityOriginData::fromURL(URL { { }, currentURL() })) { 7282 completionHandler(currentQuota); 7283 return; 7284 } 7285 7286 auto origin = API::SecurityOrigin::create(originData->securityOrigin()); 7287 m_uiClient->exceededDatabaseQuota(this, frame, origin.ptr(), databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, WTFMove(completionHandler)); 7284 7288 } 7285 7289 -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r245243 r245328 386 386 virtual ~WebPageProxy(); 387 387 388 static void forMostVisibleWebPageIfAny(PAL::SessionID, const WebCore::SecurityOriginData&, CompletionHandler<void(WebPageProxy*)>&&); 389 388 390 const API::PageConfiguration& configuration() const; 389 391 … … 1543 1545 void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; 1544 1546 1547 void requestStorageSpace(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, WTF::CompletionHandler<void(uint64_t)>&&); 1548 1545 1549 private: 1546 1550 WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&); … … 2077 2081 #endif 2078 2082 2083 void makeStorageSpaceRequest(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, CompletionHandler<void(uint64_t)>&&); 2084 2079 2085 WeakPtr<PageClient> m_pageClient; 2080 2086 Ref<API::PageConfiguration> m_configuration; … … 2506 2512 Optional<SpeechSynthesisData> m_speechSynthesisData; 2507 2513 #endif 2514 bool m_isQuotaIncreaseDenied { false }; 2508 2515 }; 2509 2516 -
trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp
r245301 r245328 124 124 } 125 125 126 void WebProcessProxy::forWebPagesWithOrigin(PAL::SessionID sessionID, const SecurityOriginData& origin, const Function<void(WebPageProxy&)>& callback) 127 { 128 for (auto* page : globalPageMap().values()) { 129 if (page->sessionID() != sessionID || SecurityOriginData::fromURL(URL { { }, page->currentURL() }) != origin) 130 continue; 131 callback(*page); 132 } 133 } 134 126 135 Ref<WebProcessProxy> WebProcessProxy::create(WebProcessPool& processPool, WebsiteDataStore* websiteDataStore, IsPrewarmed isPrewarmed, ShouldLaunchProcess shouldLaunchProcess) 127 136 { -
trunk/Source/WebKit/UIProcess/WebProcessProxy.h
r245255 r245328 111 111 ~WebProcessProxy(); 112 112 113 static void forWebPagesWithOrigin(PAL::SessionID, const WebCore::SecurityOriginData&, const Function<void(WebPageProxy&)>&); 114 113 115 WebConnection* webConnection() const { return m_webConnection.get(); } 114 116 -
trunk/Tools/ChangeLog
r245327 r245328 1 2019-05-15 Youenn Fablet <youenn@apple.com> 2 3 Reuse existing WebPageProxy quota handler for NetworkProcessProxy quota requests 4 https://bugs.webkit.org/show_bug.cgi?id=197463 5 <rdar://problem/47403621> 6 7 Reviewed by Alex Christensen. 8 9 * TestWebKitAPI/Tests/WebKitCocoa/StorageQuota.mm: Added. 10 (-[QuotaDelegate init]): 11 (-[QuotaDelegate _webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:]): 12 (-[QuotaDelegate quotaDelegateCalled]): 13 (-[QuotaDelegate grantQuota]): 14 (-[StorageSchemes webView:startURLSchemeTask:]): 15 (-[StorageSchemes webView:stopURLSchemeTask:]): 16 (-[QuotaMessageHandler userContentController:didReceiveScriptMessage:]): 17 (doTest): 18 1 19 2019-05-15 Youenn Fablet <youenn@apple.com> 2 20 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r245214 r245328 181 181 4135FB842011FAA700332139 /* InjectInternals_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4135FB832011FAA300332139 /* InjectInternals_Bundle.cpp */; }; 182 182 4135FB852011FABF00332139 /* libWebCoreTestSupport.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4135FB862011FABF00332139 /* libWebCoreTestSupport.dylib */; }; 183 414AD6862285D1C000777F2D /* StorageQuota.mm in Sources */ = {isa = PBXBuildFile; fileRef = 414AD6852285D1B000777F2D /* StorageQuota.mm */; }; 183 184 41882F0321010C0D002FF288 /* ProcessPreWarming.mm in Sources */ = {isa = PBXBuildFile; fileRef = 41882F0221010A70002FF288 /* ProcessPreWarming.mm */; }; 184 185 4433A396208044140091ED57 /* SynchronousTimeoutTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4433A395208044130091ED57 /* SynchronousTimeoutTests.mm */; }; … … 1580 1581 4135FB832011FAA300332139 /* InjectInternals_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InjectInternals_Bundle.cpp; path = Tests/InjectInternals_Bundle.cpp; sourceTree = SOURCE_ROOT; }; 1581 1582 4135FB862011FABF00332139 /* libWebCoreTestSupport.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libWebCoreTestSupport.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 1583 414AD6852285D1B000777F2D /* StorageQuota.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = StorageQuota.mm; sourceTree = "<group>"; }; 1582 1584 41882F0221010A70002FF288 /* ProcessPreWarming.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ProcessPreWarming.mm; sourceTree = "<group>"; }; 1583 1585 41973B5C1AF22875006C7B36 /* SharedBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedBuffer.cpp; sourceTree = "<group>"; }; … … 2689 2691 2DFF7B6C1DA487AF00814614 /* SnapshotStore.mm */, 2690 2692 CDC0932D21C993440030C4B0 /* StopSuspendResumeAllMedia.mm */, 2693 414AD6852285D1B000777F2D /* StorageQuota.mm */, 2691 2694 515BE1701D428BD100DD7C68 /* StoreBlobThenDelete.mm */, 2692 2695 1C734B5220788C4800F430EA /* SystemColors.mm */, … … 4370 4373 7CCE7ECF1A411A7E00447C4C /* StopLoadingFromDidReceiveResponse.mm in Sources */, 4371 4374 CDC0932E21C993440030C4B0 /* StopSuspendResumeAllMedia.mm in Sources */, 4375 414AD6862285D1C000777F2D /* StorageQuota.mm in Sources */, 4372 4376 515BE1711D428E4B00DD7C68 /* StoreBlobThenDelete.mm in Sources */, 4373 4377 7CCE7ED01A411A7E00447C4C /* StringByEvaluatingJavaScriptFromString.mm in Sources */,
Note: See TracChangeset
for help on using the changeset viewer.