Some improvements on web storage
https://bugs.webkit.org/show_bug.cgi?id=200373
Reviewed by Geoffrey Garen.
Source/WebCore:
Remove storage type EphemeralLocalStorage, which is used for localStorage in ephemeral session, and use
LocalStorage instead.
Add SessionID to StorageNamespace to make StorageNamespace session-specific.
No new test, updating existing tests for new behavior.
* loader/EmptyClients.cpp:
(WebCore::EmptyStorageNamespaceProvider::createLocalStorageNamespace):
(WebCore::EmptyStorageNamespaceProvider::createTransientLocalStorageNamespace):
(WebCore::EmptyStorageNamespaceProvider::createEphemeralLocalStorageNamespace): Deleted.
* page/Chrome.cpp:
(WebCore::Chrome::createWindow const): ephemeral localStorage of different windows will connect to the same
StorageArea in network process, so no need to copy from parent window to child window.
* page/DOMWindow.cpp:
(WebCore::DOMWindow::prewarmLocalStorageIfNecessary): localStorage will be prewarmed in network process in the
initialization of StorageAreaMap.
* page/Page.cpp:
(WebCore::m_applicationManifest):
(WebCore::Page::~Page):
(WebCore::Page::setSessionID):
(WebCore::Page::ephemeralLocalStorage): Deleted.
(WebCore::Page::setEphemeralLocalStorage): Deleted.
(WebCore::Page::setStorageNamespaceProvider): Deleted.
* page/Page.h:
(WebCore::Page::storageNamespaceProvider):
* storage/Storage.cpp:
(WebCore::Storage::prewarm): Deleted.
* storage/Storage.h:
* storage/StorageArea.h:
(WebCore::StorageArea::closeDatabaseIfIdle):
(WebCore::StorageArea::prewarm): Deleted.
* storage/StorageNamespace.h:
* storage/StorageNamespaceProvider.cpp:
(WebCore::StorageNamespaceProvider::~StorageNamespaceProvider):
(WebCore::StorageNamespaceProvider::localStorageArea):
(WebCore::StorageNamespaceProvider::localStorageNamespace):
(WebCore::StorageNamespaceProvider::transientLocalStorageNamespace):
(WebCore::StorageNamespaceProvider::enableLegacyPrivateBrowsingForTesting): change SessionID of storageNamespace
and update every StorageArea in this namespace.
(WebCore::StorageNamespaceProvider::addPage): Deleted.
(WebCore::StorageNamespaceProvider::removePage): Deleted.
* storage/StorageNamespaceProvider.h:
* storage/StorageType.h:
(WebCore::isLocalStorage):
Source/WebKit:
Fix some issues in web storage architecture. For example, sessionStorageNameSpace for web page is prepared and
destroyed in the network process when the page comes and goes, even though the page may not use sessionStorage
at all. The messages about page state sent from web process to network process can be waste.
Here are some general ideas of this patch:
1. Network process owns the web storage, and web process keeps a small local copy (based on session and
origins that are visited). There is a virtual connection from the local copy in the web process to the original
copy in the network process. The connection is created by web process when some page asks for web storage.
2. If connection is lost because network process is gone, storage in memory will be lost. The local copy in web
processs will be discarded.
3. (SessionID, StorageNamespaceID, SecurityOrigin) is used to identify a storage area. If session is changed in
web process (like enabling private browsing in layout test now), a re-connection with different sessionID would
suffice to load another copy of storage.
4. localStorage in ephemeral session has the same behavior as localStorage instead of sessionStorage, which
means different pages in the same ephemeral session share the same localStorage.
Also, this patch introduces StorageManagerSet to network process. It handles web storage stuff, including
receiving storage messages from web process, on one background thread. Previously each session has its own
StorageManager and each StorageManager has its own WorkQueue.
* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* NetworkProcess/NetworkConnectionToWebProcess.cpp: remove message handlers that are no longer needed. Network
process no longer needs to know page states from web process.
(WebKit::NetworkConnectionToWebProcess::didClose):
(WebKit::NetworkConnectionToWebProcess::webPageWasAdded): Deleted.
(WebKit::NetworkConnectionToWebProcess::webPageWasRemoved): Deleted.
(WebKit::NetworkConnectionToWebProcess::webProcessSessionChanged): Deleted.
* NetworkProcess/NetworkConnectionToWebProcess.h:
* NetworkProcess/NetworkConnectionToWebProcess.messages.in:
* NetworkProcess/NetworkProcess.cpp: NetworkProcess uses StorageManagerSet instead of StorageManager from
different sessions to deal with web storage.
(WebKit::NetworkProcess::NetworkProcess):
(WebKit::NetworkProcess::initializeNetworkProcess):
(WebKit::NetworkProcess::createNetworkConnectionToWebProcess): StorageManagerSet starts handling
StorageManagerSet messages from the new connection.
(WebKit::NetworkProcess::addWebsiteDataStore):
(WebKit::NetworkProcess::destroySession):
(WebKit::NetworkProcess::hasLocalStorage):
(WebKit::NetworkProcess::fetchWebsiteData):
(WebKit::NetworkProcess::deleteWebsiteData):
(WebKit::NetworkProcess::deleteWebsiteDataForOrigins):
(WebKit::NetworkProcess::deleteWebsiteDataForRegistrableDomains):
(WebKit::NetworkProcess::actualPrepareToSuspend):
(WebKit::NetworkProcess::resume):
(WebKit::NetworkProcess::syncLocalStorage):
(WebKit::NetworkProcess::clearLegacyPrivateBrowsingLocalStorage): added for clearing in-memory ephemeral
localStorage.
(WebKit::NetworkProcess::getLocalStorageOriginDetails):
(WebKit::NetworkProcess::connectionToWebProcessClosed):
(WebKit::NetworkProcess::webPageWasAdded): Deleted.
(WebKit::NetworkProcess::webPageWasRemoved): Deleted.
(WebKit::NetworkProcess::webProcessWasDisconnected): Deleted.
(WebKit::NetworkProcess::webProcessSessionChanged): Deleted.
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* NetworkProcess/NetworkSession.cpp: StorageManager is moved out of NetworkSession. It is now managed by
StorageManagerSet.
(WebKit::NetworkSession::NetworkSession):
(WebKit::NetworkSession::~NetworkSession):
* NetworkProcess/NetworkSession.h:
(WebKit::NetworkSession::storageManager): Deleted.
* NetworkProcess/NetworkSessionCreationParameters.cpp: creation parameters of StorageManager is moved out of
NetworkSessionCreationParameters.
(WebKit::NetworkSessionCreationParameters::privateSessionParameters):
(WebKit::NetworkSessionCreationParameters::encode const):
(WebKit::NetworkSessionCreationParameters::decode):
* NetworkProcess/NetworkSessionCreationParameters.h:
* NetworkProcess/WebStorage/LocalStorageDatabase.cpp:
(WebKit::LocalStorageDatabase::updateDatabase): remove an assertion that is no longer true as we can force an
update with syncLocalStorage now.
* NetworkProcess/WebStorage/LocalStorageDatabase.h: make updateDatabase public for syncLocalStorage.
* NetworkProcess/WebStorage/LocalStorageDatabaseTracker.cpp: LocalStorageDatabaseTracker is created on the
background thread now, so it does not hold WorkQueue to do the file operation.
(WebKit::LocalStorageDatabaseTracker::create):
(WebKit::LocalStorageDatabaseTracker::LocalStorageDatabaseTracker):
(WebKit::LocalStorageDatabaseTracker::~LocalStorageDatabaseTracker):
* NetworkProcess/WebStorage/LocalStorageDatabaseTracker.h:
* NetworkProcess/WebStorage/LocalStorageNamespace.cpp:
(WebKit::LocalStorageNamespace::getOrCreateStorageArea):
(WebKit::LocalStorageNamespace::cloneTo): Deleted.
* NetworkProcess/WebStorage/LocalStorageNamespace.h:
* NetworkProcess/WebStorage/SessionStorageNamespace.cpp:
(WebKit::SessionStorageNamespace::getOrCreateStorageArea):
(WebKit::SessionStorageNamespace::addAllowedConnection): Deleted.
(WebKit::SessionStorageNamespace::removeAllowedConnection): Deleted.
* NetworkProcess/WebStorage/SessionStorageNamespace.h:
(WebKit::SessionStorageNamespace::allowedConnections const): Deleted.
* NetworkProcess/WebStorage/StorageArea.cpp:
(WebKit::generateStorageAreaIdentifier): each StorageArea has an identifier. StorageAreaMap in web process uses
this identifier to indicate which StorageArea it is connecting to.
(WebKit::StorageArea::StorageArea):
(WebKit::StorageArea::~StorageArea): StorageArea may still have listeners because StorageArea should be
destroyed by requests from UI process, and listeners are connections to web processses.
(WebKit::StorageArea::addListener): load localStorageDatabase in advance if there is some connection to this
LocalStorage area.
(WebKit::StorageArea::removeListener):
(WebKit::StorageArea::hasListener const):
(WebKit::StorageArea::clear):
(WebKit::StorageArea::openDatabaseAndImportItemsIfNeeded const):
(WebKit::StorageArea::dispatchEvents const):
(WebKit::StorageArea::syncToDatabase):
(WebKit::StorageArea::setItems): Deleted. Stop syncing from web process to network process after network process
is relaunched.
* NetworkProcess/WebStorage/StorageArea.h:
(WebKit::StorageArea::identifier):
(WebKit::StorageArea::setWorkQueue):
* NetworkProcess/WebStorage/StorageManager.cpp: StorageManager should be accessed by only background thread now.
(WebKit::StorageManager::StorageManager):
(WebKit::StorageManager::~StorageManager):
(WebKit::StorageManager::createSessionStorageNamespace):
(WebKit::StorageManager::destroySessionStorageNamespace): this is not used now but keep it for future
improvement to remove in-memory sessionStorage in network process if we know some web page is gone forever.
(WebKit::StorageManager::cloneSessionStorageNamespace): previously each page had its own ephemeral
localStorageNamespace and now all pages in the same session share one localStorage, so we don't need to clone
localStorageNamespace.
(WebKit::StorageManager::getSessionStorageOrigins):
(WebKit::StorageManager::deleteSessionStorageOrigins):
(WebKit::StorageManager::deleteSessionStorageEntriesForOrigins):
(WebKit::StorageManager::getLocalStorageOrigins):
(WebKit::StorageManager::getLocalStorageOriginDetails):
(WebKit::StorageManager::deleteLocalStorageOriginsModifiedSince):
(WebKit::StorageManager::deleteLocalStorageEntriesForOrigins):
(WebKit::StorageManager::createLocalStorageArea):
(WebKit::StorageManager::createTransientLocalStorageArea):
(WebKit::StorageManager::createSessionStorageArea):
(WebKit::StorageManager::getOrCreateLocalStorageNamespace):
(WebKit::StorageManager::getOrCreateTransientLocalStorageNamespace):
(WebKit::StorageManager::getOrCreateSessionStorageNamespace):
(WebKit::StorageManager::clearStorageNamespaces):
(WebKit::StorageManager::addAllowedSessionStorageNamespaceConnection): Deleted.
(WebKit::StorageManager::removeAllowedSessionStorageNamespaceConnection): Deleted.
(WebKit::StorageManager::processDidCloseConnection): Deleted.
(WebKit::StorageManager::deleteLocalStorageEntriesForOrigin): Deleted.
(WebKit::StorageManager::createLocalStorageMap): Deleted.
(WebKit::StorageManager::createTransientLocalStorageMap): Deleted.
(WebKit::StorageManager::createSessionStorageMap): Deleted.
(WebKit::StorageManager::destroyStorageMap): Deleted.
(WebKit::StorageManager::prewarm): Deleted.
(WebKit::StorageManager::getValues): Deleted.
(WebKit::StorageManager::setItem): Deleted.
(WebKit::StorageManager::setItems): Deleted.
(WebKit::StorageManager::removeItem): Deleted.
(WebKit::StorageManager::clear): Deleted.
(WebKit::StorageManager::waitUntilTasksFinished): Deleted.
(WebKit::StorageManager::suspend): Deleted.
(WebKit::StorageManager::resume): Deleted.
(WebKit::StorageManager::findStorageArea const): Deleted.
* NetworkProcess/WebStorage/StorageManager.h:
(WebKit::StorageManager::workQueue const): Deleted.
(): Deleted.
* NetworkProcess/WebStorage/StorageManager.messages.in: Removed. Moved to StorageManagerSet.messages.in.
* NetworkProcess/WebStorage/StorageManagerSet.cpp: Added.
(WebKit::StorageManagerSet::create):
(WebKit::StorageManagerSet::StorageManagerSet):
(WebKit::StorageManagerSet::~StorageManagerSet):
(WebKit::StorageManagerSet::add):
(WebKit::StorageManagerSet::remove):
(WebKit::StorageManagerSet::contains):
(WebKit::StorageManagerSet::addConnection):
(WebKit::StorageManagerSet::removeConnection):
(WebKit::StorageManagerSet::waitUntilTasksFinished):
(WebKit::StorageManagerSet::waitUntilSyncingLocalStorageFinished):
(WebKit::StorageManagerSet::suspend):
(WebKit::StorageManagerSet::resume):
(WebKit::StorageManagerSet::getSessionStorageOrigins):
(WebKit::StorageManagerSet::deleteSessionStorage):
(WebKit::StorageManagerSet::deleteSessionStorageForOrigins):
(WebKit::StorageManagerSet::getLocalStorageOrigins):
(WebKit::StorageManagerSet::deleteLocalStorageModifiedSince):
(WebKit::StorageManagerSet::deleteLocalStorageForOrigins):
(WebKit::StorageManagerSet::getLocalStorageOriginDetails):
(WebKit::StorageManagerSet::connectToLocalStorageArea):
(WebKit::StorageManagerSet::connectToTransientLocalStorageArea):
(WebKit::StorageManagerSet::connectToSessionStorageArea):
(WebKit::StorageManagerSet::disconnectFromStorageArea):
(WebKit::StorageManagerSet::getValues):
(WebKit::StorageManagerSet::setItem):
(WebKit::StorageManagerSet::removeItem):
(WebKit::StorageManagerSet::clear):
(WebKit::StorageManagerSet::cloneSessionStorageNamespace):
* NetworkProcess/WebStorage/StorageManagerSet.h: Added.
* NetworkProcess/WebStorage/StorageManagerSet.messages.in: Added.
* Shared/WebsiteDataStoreParameters.cpp: creation parameters of StorageManager are moved to
WebsiteDataStoreParameters.
(WebKit::WebsiteDataStoreParameters::encode const):
(WebKit::WebsiteDataStoreParameters::decode):
(WebKit::WebsiteDataStoreParameters::privateSessionParameters):
* Shared/WebsiteDataStoreParameters.h:
* Sources.txt:
* UIProcess/API/C/WKContext.cpp: add SPI for tests.
(WKContextSyncLocalStorage):
(WKContextClearLegacyPrivateBrowsingLocalStorage):
* UIProcess/API/C/WKContextPrivate.h:
* UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
(WKWebsiteDataStoreRemoveLocalStorage):
* UIProcess/API/C/WKWebsiteDataStoreRef.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::ensureNetworkProcess):
(WebKit::WebProcessPool::syncLocalStorage):
(WebKit::WebProcessPool::clearLegacyPrivateBrowsingLocalStorage):
* UIProcess/WebProcessPool.h:
* UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
(WebKit::WebsiteDataStore::parameters):
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::parameters):
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/InjectedBundle/InjectedBundle.cpp: session change of web storage is done via
WebStorageNamespaceProvider instead of WebProcess now.
(WebKit::InjectedBundle::setPrivateBrowsingEnabled):
* WebProcess/WebProcess.cpp: web process no longer sends messsages about page state to network process.
(WebKit::WebProcess::createWebPage):
(WebKit::WebProcess::removeWebPage):
(WebKit::WebProcess::ensureNetworkProcessConnection):
(WebKit::WebProcess::networkProcessConnectionClosed):
(WebKit::WebProcess::storageAreaMap const):
(WebKit::WebProcess::enablePrivateBrowsingForTesting): Deleted. This was used for changing session via
WebProcess.
* WebProcess/WebProcess.h:
* WebProcess/WebStorage/StorageAreaImpl.cpp:
(WebKit::StorageAreaImpl::StorageAreaImpl):
(WebKit::StorageAreaImpl::length):
(WebKit::StorageAreaImpl::key):
(WebKit::StorageAreaImpl::item):
(WebKit::StorageAreaImpl::setItem):
(WebKit::StorageAreaImpl::removeItem):
(WebKit::StorageAreaImpl::clear):
(WebKit::StorageAreaImpl::contains):
(WebKit::StorageAreaImpl::storageType const):
(WebKit::StorageAreaImpl::incrementAccessCount):
(WebKit::StorageAreaImpl::decrementAccessCount):
(WebKit::StorageAreaImpl::prewarm): Deleted.
(WebKit::StorageAreaImpl::securityOrigin const): Deleted.
* WebProcess/WebStorage/StorageAreaImpl.h: make StorageAreaImpl hold a weak reference to StorageAreaMap and
StorageNamespaceImpl hold a strong reference. In this way lifeime of localStorage StorageAreraMap stays align
with StorageNameSpaceProvider and Page.
* WebProcess/WebStorage/StorageAreaMap.cpp: identifier of StorageAreaMap is the same as identifier of
StorageArea it connects to. If the identifier is 0, it means the StorageAreaMap is disconnected.
(WebKit::StorageAreaMap::StorageAreaMap):
(WebKit::StorageAreaMap::~StorageAreaMap):
(WebKit::StorageAreaMap::setItem):
(WebKit::StorageAreaMap::removeItem):
(WebKit::StorageAreaMap::clear):
(WebKit::StorageAreaMap::resetValues):
(WebKit::StorageAreaMap::loadValuesIfNeeded):
(WebKit::StorageAreaMap::applyChange):
(WebKit::StorageAreaMap::dispatchStorageEvent):
(WebKit::StorageAreaMap::dispatchSessionStorageEvent):
(WebKit::StorageAreaMap::dispatchLocalStorageEvent):
(WebKit::StorageAreaMap::connect):
(WebKit::StorageAreaMap::disconnect):
(WebKit::generateStorageMapID): Deleted.
(WebKit::StorageAreaMap::prewarm): Deleted.
(WebKit::StorageAreaMap::didGetValues): Deleted. This is useless as GetValues is a synchronous operation.
* WebProcess/WebStorage/StorageAreaMap.h:
(): Deleted.
* WebProcess/WebStorage/StorageAreaMap.messages.in: there are two synchronous messages, one for connection and
one for getting values. We may merge them into one in future improvement.
* WebProcess/WebStorage/StorageNamespaceImpl.cpp:
(WebKit::StorageNamespaceImpl::createSessionStorageNamespace):
(WebKit::StorageNamespaceImpl::createLocalStorageNamespace):
(WebKit::StorageNamespaceImpl::createTransientLocalStorageNamespace):
(WebKit::StorageNamespaceImpl::StorageNamespaceImpl):
(WebKit::StorageNamespaceImpl::storageArea):
(WebKit::StorageNamespaceImpl::copy):
(WebKit::StorageNamespaceImpl::setSessionIDForTesting):
(WebKit::StorageNamespaceImpl::createEphemeralLocalStorageNamespace): Deleted.
* WebProcess/WebStorage/StorageNamespaceImpl.h:
* WebProcess/WebStorage/WebStorageNamespaceProvider.cpp:
(WebKit::WebStorageNamespaceProvider::createSessionStorageNamespace):
(WebKit::WebStorageNamespaceProvider::createLocalStorageNamespace):
(WebKit::WebStorageNamespaceProvider::createTransientLocalStorageNamespace):
(WebKit::WebStorageNamespaceProvider::createEphemeralLocalStorageNamespace): Deleted.
* WebProcess/WebStorage/WebStorageNamespaceProvider.h:
Source/WebKitLegacy:
Do some clean-up and add support for session change of web storage in layout tests.
* Storage/StorageAreaImpl.cpp:
(WebKit::StorageAreaImpl::sessionChanged):
* Storage/StorageAreaImpl.h:
(): Deleted.
* Storage/StorageAreaSync.h: make sure StorageAreaSync is destructed on the main thread, as it can be
dereferenced in StorageAreaImpl::sessionChanged and its last reference for final sync could be released on the
background thread.
* Storage/StorageNamespaceImpl.cpp: replace EphemeralLocalStorage with LocalStorage, and store SessionID in
StorageNamespace.
(WebKit::StorageNamespaceImpl::createSessionStorageNamespace):
(WebKit::StorageNamespaceImpl::getOrCreateLocalStorageNamespace):
(WebKit::StorageNamespaceImpl::StorageNamespaceImpl):
(WebKit::StorageNamespaceImpl::copy):
(WebKit::StorageNamespaceImpl::close):
(WebKit::StorageNamespaceImpl::setSessionIDForTesting):
(WebKit::StorageNamespaceImpl::createEphemeralLocalStorageNamespace): Deleted.
* Storage/StorageNamespaceImpl.h:
* Storage/WebStorageNamespaceProvider.cpp:
(WebKit::WebStorageNamespaceProvider::createSessionStorageNamespace):
(WebKit::WebStorageNamespaceProvider::createLocalStorageNamespace):
(WebKit::WebStorageNamespaceProvider::createTransientLocalStorageNamespace):
(WebKit::WebStorageNamespaceProvider::createEphemeralLocalStorageNamespace): Deleted.
* Storage/WebStorageNamespaceProvider.h:
Source/WebKitLegacy/mac:
* WebView/WebView.mm:
(-[WebView _preferencesChanged:]): notify storageNamespaceProvider about session change.
Tools:
* TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm:
(TEST): update expectation for behavior change.
* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: new SPI to synchronously flush localStorage to
database file.
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::syncLocalStorage):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp: clear local storage between test runs to make each test isolated.
(WTR::TestController::resetStateToConsistentValues):
(WTR::StorageVoidCallbackContext::StorageVoidCallbackContext):
(WTR::StorageVoidCallback):
(WTR::TestController::clearIndexedDatabases):
(WTR::TestController::clearLocalStorage):
(WTR::TestController::syncLocalStorage):
(WTR::RemoveAllIndexedDatabasesCallbackContext::RemoveAllIndexedDatabasesCallbackContext): Deleted. Replaced
with StorageVoidCallbackContext for general usage.
(WTR::RemoveAllIndexedDatabasesCallback): Deleted. Replaced with StorageVoidCallback.
(WTR::TestController::ClearIndexedDatabases): Deleted. Use lowercase for consistent style.
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle): add handler for new message
SyncLocalStorage.
LayoutTests:
Modify tests for a behavior change: sessionStorage will be lost when network process crashes.
For tests which use sessionStorage to store items, crash network process, then read from sessionStorage and
expect items to be in sessionStorage, replace sessionStorage with localStorage. Also, to make sure localStorage
is stored persistently before network process gets terminated, adopt a newly introduced SPI to
synchronously flush localStorage content to disk before terminating network process.
* platform/ios-simulator-wk2/TestExpectations:
* platform/mac-wk2/TestExpectations:
* storage/domstorage/localstorage/private-browsing-affects-storage-expected.txt:
* storage/indexeddb/IDBObject-leak.html:
* storage/indexeddb/modern/opendatabase-after-storage-crash-expected.txt:
* storage/indexeddb/modern/opendatabase-after-storage-crash.html:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@248734 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 0cf3fb0..39586b9 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,24 @@
+2019-08-15 Sihui Liu <sihui_liu@apple.com>
+
+ Some improvements on web storage
+ https://bugs.webkit.org/show_bug.cgi?id=200373
+
+ Reviewed by Geoffrey Garen.
+
+ Modify tests for a behavior change: sessionStorage will be lost when network process crashes.
+
+ For tests which use sessionStorage to store items, crash network process, then read from sessionStorage and
+ expect items to be in sessionStorage, replace sessionStorage with localStorage. Also, to make sure localStorage
+ is stored persistently before network process gets terminated, adopt a newly introduced SPI to
+ synchronously flush localStorage content to disk before terminating network process.
+
+ * platform/ios-simulator-wk2/TestExpectations:
+ * platform/mac-wk2/TestExpectations:
+ * storage/domstorage/localstorage/private-browsing-affects-storage-expected.txt:
+ * storage/indexeddb/IDBObject-leak.html:
+ * storage/indexeddb/modern/opendatabase-after-storage-crash-expected.txt:
+ * storage/indexeddb/modern/opendatabase-after-storage-crash.html:
+
2019-08-15 Wenson Hsieh <wenson_hsieh@apple.com>
Occasional hang under -[UIKeyboardTaskQueue lockWhenReadyForMainThread] when long-pressing non-editable text
diff --git a/LayoutTests/platform/ios-simulator-wk2/TestExpectations b/LayoutTests/platform/ios-simulator-wk2/TestExpectations
index 9e8666a..974977a 100644
--- a/LayoutTests/platform/ios-simulator-wk2/TestExpectations
+++ b/LayoutTests/platform/ios-simulator-wk2/TestExpectations
@@ -66,7 +66,7 @@
http/wpt/cache-storage/a-cache-open.https.html [ Slow ]
http/wpt/cache-storage/cache-quota-add.any.html [ Slow ]
-webkit.org/b/196376 [ Debug ] storage/domstorage/localstorage/private-browsing-affects-storage.html [ Pass Failure ]
+webkit.org/b/196376 [ Debug ] storage/domstorage/localstorage/private-browsing-affects-storage.html [ Pass ]
webkit.org/b/196403 imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop.html [ Pass Failure ]
diff --git a/LayoutTests/platform/mac-wk2/TestExpectations b/LayoutTests/platform/mac-wk2/TestExpectations
index 6a8270f..d22d787 100644
--- a/LayoutTests/platform/mac-wk2/TestExpectations
+++ b/LayoutTests/platform/mac-wk2/TestExpectations
@@ -922,7 +922,7 @@
webkit.org/b/194916 fast/mediastream/MediaStream-video-element.html [ Pass Failure ]
-webkit.org/b/196376 storage/domstorage/localstorage/private-browsing-affects-storage.html [ Pass Failure ]
+webkit.org/b/196376 storage/domstorage/localstorage/private-browsing-affects-storage.html [ Pass ]
webkit.org/b/196400 fast/mediastream/MediaStreamTrack-getSettings.html [ Pass Failure ]
diff --git a/LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage-expected.txt b/LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage-expected.txt
index 2ca9557..f9840de 100644
--- a/LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage-expected.txt
+++ b/LayoutTests/storage/domstorage/localstorage/private-browsing-affects-storage-expected.txt
@@ -8,7 +8,7 @@
ALERT: The item in new window starts out as: ChangedValue
ALERT: The item in new window is now: NewWindowValue
ALERT: Back in parent window, localStorage's length is: 1
-ALERT: Back in parent window, testItem is: ChangedValue
+ALERT: Back in parent window, testItem is: NewWindowValue
ALERT: Final window, localStorage's length is: 1
ALERT: Final window, item is: Persistent item!
diff --git a/LayoutTests/storage/indexeddb/IDBObject-leak.html b/LayoutTests/storage/indexeddb/IDBObject-leak.html
index e18b68b..6aa8ab6 100644
--- a/LayoutTests/storage/indexeddb/IDBObject-leak.html
+++ b/LayoutTests/storage/indexeddb/IDBObject-leak.html
@@ -13,7 +13,7 @@
return;
}
- if (sessionStorage.doneFirstLoad) {
+ if (localStorage.doneFirstLoad) {
gc();
shouldBeEqualToNumber("internals.numberOfIDBTransactions()", 0);
finishJSTest();
@@ -23,16 +23,21 @@
var dbname = setDBNameFromPath() + Date();
var request = window.indexedDB.open(dbname);
request.onupgradeneeded = function(evt) {
- sessionStorage.doneFirstLoad = true;
+ localStorage.doneFirstLoad = true;
if (!window.testRunner || !testRunner.terminateNetworkProcess) {
testFailed('This test requires access to the TestRunner object and terminateNetworkProcess() function');
finishJSTest();
return;
}
+
+ // Make sure localStorage is flushed to disk before crashing network process.
+ testRunner.syncLocalStorage();
testRunner.terminateNetworkProcess();
- setTimeout((()=> {
- location.reload();
- }), 0);
+ evt.target.result.onerror = function(e) {
+ setTimeout((()=> {
+ location.reload();
+ }), 0);
+ }
}
}
diff --git a/LayoutTests/storage/indexeddb/modern/opendatabase-after-storage-crash-expected.txt b/LayoutTests/storage/indexeddb/modern/opendatabase-after-storage-crash-expected.txt
index 47b8727..f9978a0 100644
--- a/LayoutTests/storage/indexeddb/modern/opendatabase-after-storage-crash-expected.txt
+++ b/LayoutTests/storage/indexeddb/modern/opendatabase-after-storage-crash-expected.txt
@@ -1,2 +1,2 @@
-PASS sessionStorage[storageKey] is "Made it"
+PASS localStorage[storageKey] is "Made it"
Successfully opened database with version 3.
diff --git a/LayoutTests/storage/indexeddb/modern/opendatabase-after-storage-crash.html b/LayoutTests/storage/indexeddb/modern/opendatabase-after-storage-crash.html
index d2458f6..9a0912e 100644
--- a/LayoutTests/storage/indexeddb/modern/opendatabase-after-storage-crash.html
+++ b/LayoutTests/storage/indexeddb/modern/opendatabase-after-storage-crash.html
@@ -20,31 +20,31 @@
request.onerror = function(e) {
// Good, we received an expected error.
// Now reload to see if a new document connects successfully
- if (sessionStorage[storageKey]) {
+ if (localStorage[storageKey]) {
document.body.innerHTML = "Received error more than once unexpectedly. Database: name " + dbname + ", version 2.";
if (window.testRunner)
testRunner.notifyDone();
return;
}
- sessionStorage[storageKey] = "Made it";
+ localStorage[storageKey] = "Made it";
location.reload();
}
request.onsuccess = function(e) {
- document.body.innerHTML = "Unexpected upgradeneeded after storage process termination. Database: name " + dbname + ", version 2. SessionStorage value: " + sessionStorage[storageKey] + ".";
+ document.body.innerHTML = "Unexpected upgradeneeded after storage process termination. Database: name " + dbname + ", version 2. localStorage value: " + sessionStorage[storageKey] + ".";
if (window.testRunner)
testRunner.notifyDone();
}
}
-var versionToOpen = sessionStorage.doneFirstLoad ? 3 : 1;
+var versionToOpen = localStorage.doneFirstLoad ? 3 : 1;
var request = window.indexedDB.open(dbname, versionToOpen);
request.onupgradeneeded = function(e) {
- if (sessionStorage.doneFirstLoad) {
+ if (localStorage.doneFirstLoad) {
document.body.innerHTML = "Successfully opened database with version " + versionToOpen + ".";
- shouldBeEqualToString('sessionStorage[storageKey]', 'Made it');
+ shouldBeEqualToString('localStorage[storageKey]', 'Made it');
if (window.testRunner) {
testRunner.notifyDone();
@@ -52,7 +52,7 @@
}
}
- sessionStorage.doneFirstLoad = true;
+ localStorage.doneFirstLoad = true;
// Set an error handler on the database connection so once the storage process terminates we know to continue the test
e.target.result.onerror = function(e) {
@@ -61,6 +61,8 @@
if (window.testRunner) {
testRunner.waitUntilDone();
+ // Make sure localStorage is flushed to disk before crashing network process.
+ testRunner.syncLocalStorage();
testRunner.terminateNetworkProcess();
}
}
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index f958e5b..3bb2646 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,59 @@
+2019-08-15 Sihui Liu <sihui_liu@apple.com>
+
+ Some improvements on web storage
+ https://bugs.webkit.org/show_bug.cgi?id=200373
+
+ Reviewed by Geoffrey Garen.
+
+ Remove storage type EphemeralLocalStorage, which is used for localStorage in ephemeral session, and use
+ LocalStorage instead.
+
+ Add SessionID to StorageNamespace to make StorageNamespace session-specific.
+
+ No new test, updating existing tests for new behavior.
+
+ * loader/EmptyClients.cpp:
+ (WebCore::EmptyStorageNamespaceProvider::createLocalStorageNamespace):
+ (WebCore::EmptyStorageNamespaceProvider::createTransientLocalStorageNamespace):
+ (WebCore::EmptyStorageNamespaceProvider::createEphemeralLocalStorageNamespace): Deleted.
+
+ * page/Chrome.cpp:
+ (WebCore::Chrome::createWindow const): ephemeral localStorage of different windows will connect to the same
+ StorageArea in network process, so no need to copy from parent window to child window.
+
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::prewarmLocalStorageIfNecessary): localStorage will be prewarmed in network process in the
+ initialization of StorageAreaMap.
+
+ * page/Page.cpp:
+ (WebCore::m_applicationManifest):
+ (WebCore::Page::~Page):
+ (WebCore::Page::setSessionID):
+ (WebCore::Page::ephemeralLocalStorage): Deleted.
+ (WebCore::Page::setEphemeralLocalStorage): Deleted.
+ (WebCore::Page::setStorageNamespaceProvider): Deleted.
+ * page/Page.h:
+ (WebCore::Page::storageNamespaceProvider):
+ * storage/Storage.cpp:
+ (WebCore::Storage::prewarm): Deleted.
+ * storage/Storage.h:
+ * storage/StorageArea.h:
+ (WebCore::StorageArea::closeDatabaseIfIdle):
+ (WebCore::StorageArea::prewarm): Deleted.
+ * storage/StorageNamespace.h:
+ * storage/StorageNamespaceProvider.cpp:
+ (WebCore::StorageNamespaceProvider::~StorageNamespaceProvider):
+ (WebCore::StorageNamespaceProvider::localStorageArea):
+ (WebCore::StorageNamespaceProvider::localStorageNamespace):
+ (WebCore::StorageNamespaceProvider::transientLocalStorageNamespace):
+ (WebCore::StorageNamespaceProvider::enableLegacyPrivateBrowsingForTesting): change SessionID of storageNamespace
+ and update every StorageArea in this namespace.
+ (WebCore::StorageNamespaceProvider::addPage): Deleted.
+ (WebCore::StorageNamespaceProvider::removePage): Deleted.
+ * storage/StorageNamespaceProvider.h:
+ * storage/StorageType.h:
+ (WebCore::isLocalStorage):
+
2019-08-15 Saam Barati <sbarati@apple.com>
[WHLSL] Make length, clamp, operator+, operator-, operator*, operator/, operator[], operator[]=, operator.xy, operator.xy=, native
diff --git a/Source/WebCore/loader/EmptyClients.cpp b/Source/WebCore/loader/EmptyClients.cpp
index c450c08..0453d7e 100644
--- a/Source/WebCore/loader/EmptyClients.cpp
+++ b/Source/WebCore/loader/EmptyClients.cpp
@@ -390,18 +390,19 @@
bool contains(const String&) final { return false; }
StorageType storageType() const final { return StorageType::Local; }
size_t memoryBytesUsedByCache() final { return 0; }
- const SecurityOriginData& securityOrigin() const final { static NeverDestroyed<SecurityOriginData> origin; return origin.get(); }
};
struct EmptyStorageNamespace final : public StorageNamespace {
Ref<StorageArea> storageArea(const SecurityOriginData&) final { return adoptRef(*new EmptyStorageArea); }
Ref<StorageNamespace> copy(Page*) final { return adoptRef(*new EmptyStorageNamespace); }
+ PAL::SessionID sessionID() const { return PAL::SessionID::emptySessionID(); }
+ void setSessionIDForTesting(PAL::SessionID) { };
};
Ref<StorageNamespace> createSessionStorageNamespace(Page&, unsigned) final;
- Ref<StorageNamespace> createLocalStorageNamespace(unsigned) final;
- Ref<StorageNamespace> createEphemeralLocalStorageNamespace(Page&, unsigned) final;
- Ref<StorageNamespace> createTransientLocalStorageNamespace(SecurityOrigin&, unsigned) final;
+ Ref<StorageNamespace> createLocalStorageNamespace(unsigned, PAL::SessionID) final;
+ Ref<StorageNamespace> createTransientLocalStorageNamespace(SecurityOrigin&, unsigned, PAL::SessionID) final;
+
};
class EmptyUserContentProvider final : public UserContentProvider {
@@ -525,17 +526,12 @@
return adoptRef(*new EmptyStorageNamespace);
}
-Ref<StorageNamespace> EmptyStorageNamespaceProvider::createLocalStorageNamespace(unsigned)
+Ref<StorageNamespace> EmptyStorageNamespaceProvider::createLocalStorageNamespace(unsigned, PAL::SessionID)
{
return adoptRef(*new EmptyStorageNamespace);
}
-Ref<StorageNamespace> EmptyStorageNamespaceProvider::createEphemeralLocalStorageNamespace(Page&, unsigned)
-{
- return adoptRef(*new EmptyStorageNamespace);
-}
-
-Ref<StorageNamespace> EmptyStorageNamespaceProvider::createTransientLocalStorageNamespace(SecurityOrigin&, unsigned)
+Ref<StorageNamespace> EmptyStorageNamespaceProvider::createTransientLocalStorageNamespace(SecurityOrigin&, unsigned, PAL::SessionID)
{
return adoptRef(*new EmptyStorageNamespace);
}
diff --git a/Source/WebCore/page/Chrome.cpp b/Source/WebCore/page/Chrome.cpp
index 9758329..73fee07 100644
--- a/Source/WebCore/page/Chrome.cpp
+++ b/Source/WebCore/page/Chrome.cpp
@@ -189,8 +189,6 @@
if (auto* oldSessionStorage = m_page.sessionStorage(false))
newPage->setSessionStorage(oldSessionStorage->copy(newPage));
- if (auto* oldEphemeralLocalStorage = m_page.ephemeralLocalStorage(false))
- newPage->setEphemeralLocalStorage(oldEphemeralLocalStorage->copy(newPage));
return newPage;
}
diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp
index 17cba5e..3074b18 100644
--- a/Source/WebCore/page/DOMWindow.cpp
+++ b/Source/WebCore/page/DOMWindow.cpp
@@ -442,8 +442,7 @@
if (!localStorage)
return;
- if (localStorage->prewarm())
- page->mainFrame().didPrewarmLocalStorage();
+ page->mainFrame().didPrewarmLocalStorage();
}
DOMWindow::~DOMWindow()
diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
index 4d4a49c..395d2f0 100644
--- a/Source/WebCore/page/Page.cpp
+++ b/Source/WebCore/page/Page.cpp
@@ -289,7 +289,6 @@
updateTimerThrottlingState();
m_pluginInfoProvider->addPage(*this);
- m_storageNamespaceProvider->addPage(*this);
m_userContentProvider->addPage(*this);
m_visitedLinkStore->addPage(*this);
@@ -367,7 +366,6 @@
#endif
m_pluginInfoProvider->removePage(*this);
- m_storageNamespaceProvider->removePage(*this);
m_userContentProvider->removePage(*this);
m_visitedLinkStore->removePage(*this);
}
@@ -1510,19 +1508,6 @@
m_sessionStorage = WTFMove(newStorage);
}
-StorageNamespace* Page::ephemeralLocalStorage(bool optionalCreate)
-{
- if (!m_ephemeralLocalStorage && optionalCreate)
- m_ephemeralLocalStorage = m_storageNamespaceProvider->createEphemeralLocalStorageNamespace(*this, m_settings->sessionStorageQuota());
-
- return m_ephemeralLocalStorage.get();
-}
-
-void Page::setEphemeralLocalStorage(RefPtr<StorageNamespace>&& newStorage)
-{
- m_ephemeralLocalStorage = WTFMove(newStorage);
-}
-
bool Page::hasCustomHTMLTokenizerTimeDelay() const
{
return m_settings->maxParseDuration() != -1;
@@ -2470,15 +2455,6 @@
invalidateInjectedStyleSheetCacheInAllFrames();
}
-void Page::setStorageNamespaceProvider(Ref<StorageNamespaceProvider>&& storageNamespaceProvider)
-{
- m_storageNamespaceProvider->removePage(*this);
- m_storageNamespaceProvider = WTFMove(storageNamespaceProvider);
- m_storageNamespaceProvider->addPage(*this);
-
- // This needs to reset all the local storage namespaces of all the pages.
-}
-
VisitedLinkStore& Page::visitedLinkStore()
{
return m_visitedLinkStore;
@@ -2507,6 +2483,9 @@
m_idbConnectionToServer = nullptr;
#endif
+ if (sessionID != m_sessionID && m_sessionStorage)
+ m_sessionStorage->setSessionIDForTesting(sessionID);
+
bool privateBrowsingStateChanged = (sessionID.isEphemeral() != m_sessionID.isEphemeral());
m_sessionID = sessionID;
diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h
index c440234..7c86502 100644
--- a/Source/WebCore/page/Page.h
+++ b/Source/WebCore/page/Page.h
@@ -507,9 +507,6 @@
StorageNamespace* sessionStorage(bool optionalCreate = true);
void setSessionStorage(RefPtr<StorageNamespace>&&);
- StorageNamespace* ephemeralLocalStorage(bool optionalCreate = true);
- void setEphemeralLocalStorage(RefPtr<StorageNamespace>&&);
-
bool hasCustomHTMLTokenizerTimeDelay() const;
double customHTMLTokenizerTimeDelay() const;
@@ -599,7 +596,6 @@
CookieJar& cookieJar() { return m_cookieJar.get(); }
StorageNamespaceProvider& storageNamespaceProvider() { return m_storageNamespaceProvider.get(); }
- void setStorageNamespaceProvider(Ref<StorageNamespaceProvider>&&);
PluginInfoProvider& pluginInfoProvider();
@@ -877,7 +873,6 @@
bool m_canStartMedia { true };
RefPtr<StorageNamespace> m_sessionStorage;
- RefPtr<StorageNamespace> m_ephemeralLocalStorage;
TimerThrottlingState m_timerThrottlingState { TimerThrottlingState::Disabled };
MonotonicTime m_timerThrottlingStateLastChangedTime;
diff --git a/Source/WebCore/storage/Storage.cpp b/Source/WebCore/storage/Storage.cpp
index 9197b60..47dbb17 100644
--- a/Source/WebCore/storage/Storage.cpp
+++ b/Source/WebCore/storage/Storage.cpp
@@ -97,11 +97,6 @@
return { };
}
-bool Storage::prewarm()
-{
- return m_storageArea->prewarm();
-}
-
ExceptionOr<void> Storage::clear()
{
auto* frame = this->frame();
diff --git a/Source/WebCore/storage/Storage.h b/Source/WebCore/storage/Storage.h
index 5215f47..28aa9ab 100644
--- a/Source/WebCore/storage/Storage.h
+++ b/Source/WebCore/storage/Storage.h
@@ -46,7 +46,6 @@
ExceptionOr<void> removeItem(const String& key);
ExceptionOr<void> clear();
bool contains(const String& key) const;
- bool prewarm();
// Bindings support functions.
bool isSupportedPropertyName(const String&) const;
diff --git a/Source/WebCore/storage/StorageArea.h b/Source/WebCore/storage/StorageArea.h
index f39ccd7..5a9ffff 100644
--- a/Source/WebCore/storage/StorageArea.h
+++ b/Source/WebCore/storage/StorageArea.h
@@ -58,9 +58,6 @@
virtual void incrementAccessCount() { }
virtual void decrementAccessCount() { }
virtual void closeDatabaseIfIdle() { }
- virtual bool prewarm() { return false; }
-
- virtual const SecurityOriginData& securityOrigin() const = 0;
};
} // namespace WebCore
diff --git a/Source/WebCore/storage/StorageNamespace.h b/Source/WebCore/storage/StorageNamespace.h
index 55c6628..75b8b05 100644
--- a/Source/WebCore/storage/StorageNamespace.h
+++ b/Source/WebCore/storage/StorageNamespace.h
@@ -28,6 +28,10 @@
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
+namespace PAL {
+class SessionID;
+}
+
namespace WebCore {
class Page;
@@ -39,6 +43,9 @@
virtual ~StorageNamespace() = default;
virtual Ref<StorageArea> storageArea(const SecurityOriginData&) = 0;
virtual Ref<StorageNamespace> copy(Page* newPage) = 0;
+
+ virtual PAL::SessionID sessionID() const = 0;
+ virtual void setSessionIDForTesting(PAL::SessionID) = 0;
};
} // namespace WebCore
diff --git a/Source/WebCore/storage/StorageNamespaceProvider.cpp b/Source/WebCore/storage/StorageNamespaceProvider.cpp
index 5939aff..6c5a8de 100644
--- a/Source/WebCore/storage/StorageNamespaceProvider.cpp
+++ b/Source/WebCore/storage/StorageNamespaceProvider.cpp
@@ -43,21 +43,6 @@
StorageNamespaceProvider::~StorageNamespaceProvider()
{
- ASSERT(m_pages.isEmpty());
-}
-
-void StorageNamespaceProvider::addPage(Page& page)
-{
- ASSERT(!m_pages.contains(&page));
-
- m_pages.add(&page);
-}
-
-void StorageNamespaceProvider::removePage(Page& page)
-{
- ASSERT(m_pages.contains(&page));
-
- m_pages.remove(&page);
}
Ref<StorageArea> StorageNamespaceProvider::localStorageArea(Document& document)
@@ -66,36 +51,47 @@
// so the Document had better still actually have a Page.
ASSERT(document.page());
- bool ephemeral = document.page()->usesEphemeralSession();
bool transient = !document.securityOrigin().canAccessLocalStorage(&document.topOrigin());
RefPtr<StorageNamespace> storageNamespace;
if (transient)
- storageNamespace = &transientLocalStorageNamespace(document.topOrigin());
- else if (ephemeral)
- storageNamespace = document.page()->ephemeralLocalStorage();
+ storageNamespace = &transientLocalStorageNamespace(document.topOrigin(), document.page()->sessionID());
else
- storageNamespace = &localStorageNamespace();
+ storageNamespace = &localStorageNamespace(document.page()->sessionID());
return storageNamespace->storageArea(document.securityOrigin().data());
}
-StorageNamespace& StorageNamespaceProvider::localStorageNamespace()
+StorageNamespace& StorageNamespaceProvider::localStorageNamespace(PAL::SessionID sessionID)
{
if (!m_localStorageNamespace)
- m_localStorageNamespace = createLocalStorageNamespace(localStorageDatabaseQuotaInBytes);
+ m_localStorageNamespace = createLocalStorageNamespace(localStorageDatabaseQuotaInBytes, sessionID);
+ ASSERT(m_localStorageNamespace->sessionID() == sessionID);
return *m_localStorageNamespace;
}
-StorageNamespace& StorageNamespaceProvider::transientLocalStorageNamespace(SecurityOrigin& securityOrigin)
+StorageNamespace& StorageNamespaceProvider::transientLocalStorageNamespace(SecurityOrigin& securityOrigin, PAL::SessionID sessionID)
{
- auto& slot = m_transientLocalStorageMap.add(&securityOrigin, nullptr).iterator->value;
+ auto& slot = m_transientLocalStorageNamespaces.add(securityOrigin.data(), nullptr).iterator->value;
if (!slot)
- slot = createTransientLocalStorageNamespace(securityOrigin, localStorageDatabaseQuotaInBytes);
+ slot = createTransientLocalStorageNamespace(securityOrigin, localStorageDatabaseQuotaInBytes, sessionID);
+ ASSERT(slot->sessionID() == sessionID);
return *slot;
}
+void StorageNamespaceProvider::enableLegacyPrivateBrowsingForTesting(bool enabled)
+{
+ auto newSessionID = enabled ? PAL::SessionID::legacyPrivateSessionID() : PAL::SessionID::defaultSessionID();
+ if (m_localStorageNamespace && newSessionID != m_localStorageNamespace->sessionID())
+ m_localStorageNamespace->setSessionIDForTesting(newSessionID);
+
+ for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values()) {
+ if (newSessionID != transientLocalStorageNamespace->sessionID())
+ m_localStorageNamespace->setSessionIDForTesting(newSessionID);
+ }
+}
+
}
diff --git a/Source/WebCore/storage/StorageNamespaceProvider.h b/Source/WebCore/storage/StorageNamespaceProvider.h
index dd7f9a4..01d064b 100644
--- a/Source/WebCore/storage/StorageNamespaceProvider.h
+++ b/Source/WebCore/storage/StorageNamespaceProvider.h
@@ -31,6 +31,10 @@
#include <wtf/HashSet.h>
#include <wtf/RefCounted.h>
+namespace PAL {
+class SessionID;
+}
+
namespace WebCore {
class Document;
@@ -45,27 +49,23 @@
WEBCORE_EXPORT virtual ~StorageNamespaceProvider();
virtual Ref<StorageNamespace> createSessionStorageNamespace(Page&, unsigned quota) = 0;
- virtual Ref<StorageNamespace> createEphemeralLocalStorageNamespace(Page&, unsigned quota) = 0;
Ref<StorageArea> localStorageArea(Document&);
- void addPage(Page&);
- void removePage(Page&);
+ WEBCORE_EXPORT void enableLegacyPrivateBrowsingForTesting(bool enabled);
protected:
StorageNamespace* optionalLocalStorageNamespace() { return m_localStorageNamespace.get(); }
private:
- StorageNamespace& localStorageNamespace();
- StorageNamespace& transientLocalStorageNamespace(SecurityOrigin&);
+ StorageNamespace& localStorageNamespace(PAL::SessionID);
+ StorageNamespace& transientLocalStorageNamespace(SecurityOrigin&, PAL::SessionID);
- virtual Ref<StorageNamespace> createLocalStorageNamespace(unsigned quota) = 0;
- virtual Ref<StorageNamespace> createTransientLocalStorageNamespace(SecurityOrigin&, unsigned quota) = 0;
-
- HashSet<Page*> m_pages;
+ virtual Ref<StorageNamespace> createLocalStorageNamespace(unsigned quota, PAL::SessionID) = 0;
+ virtual Ref<StorageNamespace> createTransientLocalStorageNamespace(SecurityOrigin&, unsigned quota, PAL::SessionID) = 0;
RefPtr<StorageNamespace> m_localStorageNamespace;
- HashMap<RefPtr<SecurityOrigin>, RefPtr<StorageNamespace>> m_transientLocalStorageMap;
+ HashMap<SecurityOriginData, RefPtr<StorageNamespace>> m_transientLocalStorageNamespaces;
};
} // namespace WebCore
diff --git a/Source/WebCore/storage/StorageType.h b/Source/WebCore/storage/StorageType.h
index 58133f8..fe70025 100644
--- a/Source/WebCore/storage/StorageType.h
+++ b/Source/WebCore/storage/StorageType.h
@@ -30,13 +30,12 @@
enum class StorageType {
Session,
Local,
- EphemeralLocal,
TransientLocal,
};
inline bool isLocalStorage(StorageType storageType)
{
- return storageType == StorageType::Local || storageType == StorageType::TransientLocal || storageType == StorageType::EphemeralLocal;
+ return storageType == StorageType::Local || storageType == StorageType::TransientLocal;
}
inline bool isPersistentLocalStorage(StorageType storageType)
diff --git a/Source/WebKit/CMakeLists.txt b/Source/WebKit/CMakeLists.txt
index 6f79c86..d88aa83 100644
--- a/Source/WebKit/CMakeLists.txt
+++ b/Source/WebKit/CMakeLists.txt
@@ -118,7 +118,7 @@
NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in
NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in
- NetworkProcess/WebStorage/StorageManager.messages.in
+ NetworkProcess/WebStorage/StorageManagerSet.messages.in
NetworkProcess/cache/CacheStorageEngineConnection.messages.in
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 780ec25..fd5ee7a 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,303 @@
+2019-08-15 Sihui Liu <sihui_liu@apple.com>
+
+ Some improvements on web storage
+ https://bugs.webkit.org/show_bug.cgi?id=200373
+
+ Reviewed by Geoffrey Garen.
+
+ Fix some issues in web storage architecture. For example, sessionStorageNameSpace for web page is prepared and
+ destroyed in the network process when the page comes and goes, even though the page may not use sessionStorage
+ at all. The messages about page state sent from web process to network process can be waste.
+
+ Here are some general ideas of this patch:
+ 1. Network process owns the web storage, and web process keeps a small local copy (based on session and
+ origins that are visited). There is a virtual connection from the local copy in the web process to the original
+ copy in the network process. The connection is created by web process when some page asks for web storage.
+ 2. If connection is lost because network process is gone, storage in memory will be lost. The local copy in web
+ processs will be discarded.
+ 3. (SessionID, StorageNamespaceID, SecurityOrigin) is used to identify a storage area. If session is changed in
+ web process (like enabling private browsing in layout test now), a re-connection with different sessionID would
+ suffice to load another copy of storage.
+ 4. localStorage in ephemeral session has the same behavior as localStorage instead of sessionStorage, which
+ means different pages in the same ephemeral session share the same localStorage.
+
+ Also, this patch introduces StorageManagerSet to network process. It handles web storage stuff, including
+ receiving storage messages from web process, on one background thread. Previously each session has its own
+ StorageManager and each StorageManager has its own WorkQueue.
+
+ * CMakeLists.txt:
+ * DerivedSources-input.xcfilelist:
+ * DerivedSources-output.xcfilelist:
+ * DerivedSources.make:
+
+ * NetworkProcess/NetworkConnectionToWebProcess.cpp: remove message handlers that are no longer needed. Network
+ process no longer needs to know page states from web process.
+ (WebKit::NetworkConnectionToWebProcess::didClose):
+ (WebKit::NetworkConnectionToWebProcess::webPageWasAdded): Deleted.
+ (WebKit::NetworkConnectionToWebProcess::webPageWasRemoved): Deleted.
+ (WebKit::NetworkConnectionToWebProcess::webProcessSessionChanged): Deleted.
+ * NetworkProcess/NetworkConnectionToWebProcess.h:
+ * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
+
+ * NetworkProcess/NetworkProcess.cpp: NetworkProcess uses StorageManagerSet instead of StorageManager from
+ different sessions to deal with web storage.
+ (WebKit::NetworkProcess::NetworkProcess):
+ (WebKit::NetworkProcess::initializeNetworkProcess):
+ (WebKit::NetworkProcess::createNetworkConnectionToWebProcess): StorageManagerSet starts handling
+ StorageManagerSet messages from the new connection.
+ (WebKit::NetworkProcess::addWebsiteDataStore):
+ (WebKit::NetworkProcess::destroySession):
+ (WebKit::NetworkProcess::hasLocalStorage):
+ (WebKit::NetworkProcess::fetchWebsiteData):
+ (WebKit::NetworkProcess::deleteWebsiteData):
+ (WebKit::NetworkProcess::deleteWebsiteDataForOrigins):
+ (WebKit::NetworkProcess::deleteWebsiteDataForRegistrableDomains):
+ (WebKit::NetworkProcess::actualPrepareToSuspend):
+ (WebKit::NetworkProcess::resume):
+ (WebKit::NetworkProcess::syncLocalStorage):
+ (WebKit::NetworkProcess::clearLegacyPrivateBrowsingLocalStorage): added for clearing in-memory ephemeral
+ localStorage.
+ (WebKit::NetworkProcess::getLocalStorageOriginDetails):
+ (WebKit::NetworkProcess::connectionToWebProcessClosed):
+ (WebKit::NetworkProcess::webPageWasAdded): Deleted.
+ (WebKit::NetworkProcess::webPageWasRemoved): Deleted.
+ (WebKit::NetworkProcess::webProcessWasDisconnected): Deleted.
+ (WebKit::NetworkProcess::webProcessSessionChanged): Deleted.
+ * NetworkProcess/NetworkProcess.h:
+ * NetworkProcess/NetworkProcess.messages.in:
+
+ * NetworkProcess/NetworkSession.cpp: StorageManager is moved out of NetworkSession. It is now managed by
+ StorageManagerSet.
+ (WebKit::NetworkSession::NetworkSession):
+ (WebKit::NetworkSession::~NetworkSession):
+ * NetworkProcess/NetworkSession.h:
+ (WebKit::NetworkSession::storageManager): Deleted.
+
+ * NetworkProcess/NetworkSessionCreationParameters.cpp: creation parameters of StorageManager is moved out of
+ NetworkSessionCreationParameters.
+ (WebKit::NetworkSessionCreationParameters::privateSessionParameters):
+ (WebKit::NetworkSessionCreationParameters::encode const):
+ (WebKit::NetworkSessionCreationParameters::decode):
+ * NetworkProcess/NetworkSessionCreationParameters.h:
+
+ * NetworkProcess/WebStorage/LocalStorageDatabase.cpp:
+ (WebKit::LocalStorageDatabase::updateDatabase): remove an assertion that is no longer true as we can force an
+ update with syncLocalStorage now.
+ * NetworkProcess/WebStorage/LocalStorageDatabase.h: make updateDatabase public for syncLocalStorage.
+
+ * NetworkProcess/WebStorage/LocalStorageDatabaseTracker.cpp: LocalStorageDatabaseTracker is created on the
+ background thread now, so it does not hold WorkQueue to do the file operation.
+ (WebKit::LocalStorageDatabaseTracker::create):
+ (WebKit::LocalStorageDatabaseTracker::LocalStorageDatabaseTracker):
+ (WebKit::LocalStorageDatabaseTracker::~LocalStorageDatabaseTracker):
+ * NetworkProcess/WebStorage/LocalStorageDatabaseTracker.h:
+ * NetworkProcess/WebStorage/LocalStorageNamespace.cpp:
+ (WebKit::LocalStorageNamespace::getOrCreateStorageArea):
+ (WebKit::LocalStorageNamespace::cloneTo): Deleted.
+ * NetworkProcess/WebStorage/LocalStorageNamespace.h:
+ * NetworkProcess/WebStorage/SessionStorageNamespace.cpp:
+ (WebKit::SessionStorageNamespace::getOrCreateStorageArea):
+ (WebKit::SessionStorageNamespace::addAllowedConnection): Deleted.
+ (WebKit::SessionStorageNamespace::removeAllowedConnection): Deleted.
+ * NetworkProcess/WebStorage/SessionStorageNamespace.h:
+ (WebKit::SessionStorageNamespace::allowedConnections const): Deleted.
+
+ * NetworkProcess/WebStorage/StorageArea.cpp:
+ (WebKit::generateStorageAreaIdentifier): each StorageArea has an identifier. StorageAreaMap in web process uses
+ this identifier to indicate which StorageArea it is connecting to.
+ (WebKit::StorageArea::StorageArea):
+ (WebKit::StorageArea::~StorageArea): StorageArea may still have listeners because StorageArea should be
+ destroyed by requests from UI process, and listeners are connections to web processses.
+ (WebKit::StorageArea::addListener): load localStorageDatabase in advance if there is some connection to this
+ LocalStorage area.
+ (WebKit::StorageArea::removeListener):
+ (WebKit::StorageArea::hasListener const):
+ (WebKit::StorageArea::clear):
+ (WebKit::StorageArea::openDatabaseAndImportItemsIfNeeded const):
+ (WebKit::StorageArea::dispatchEvents const):
+ (WebKit::StorageArea::syncToDatabase):
+ (WebKit::StorageArea::setItems): Deleted. Stop syncing from web process to network process after network process
+ is relaunched.
+ * NetworkProcess/WebStorage/StorageArea.h:
+ (WebKit::StorageArea::identifier):
+ (WebKit::StorageArea::setWorkQueue):
+
+ * NetworkProcess/WebStorage/StorageManager.cpp: StorageManager should be accessed by only background thread now.
+ (WebKit::StorageManager::StorageManager):
+ (WebKit::StorageManager::~StorageManager):
+ (WebKit::StorageManager::createSessionStorageNamespace):
+ (WebKit::StorageManager::destroySessionStorageNamespace): this is not used now but keep it for future
+ improvement to remove in-memory sessionStorage in network process if we know some web page is gone forever.
+ (WebKit::StorageManager::cloneSessionStorageNamespace): previously each page had its own ephemeral
+ localStorageNamespace and now all pages in the same session share one localStorage, so we don't need to clone
+ localStorageNamespace.
+ (WebKit::StorageManager::getSessionStorageOrigins):
+ (WebKit::StorageManager::deleteSessionStorageOrigins):
+ (WebKit::StorageManager::deleteSessionStorageEntriesForOrigins):
+ (WebKit::StorageManager::getLocalStorageOrigins):
+ (WebKit::StorageManager::getLocalStorageOriginDetails):
+ (WebKit::StorageManager::deleteLocalStorageOriginsModifiedSince):
+ (WebKit::StorageManager::deleteLocalStorageEntriesForOrigins):
+ (WebKit::StorageManager::createLocalStorageArea):
+ (WebKit::StorageManager::createTransientLocalStorageArea):
+ (WebKit::StorageManager::createSessionStorageArea):
+ (WebKit::StorageManager::getOrCreateLocalStorageNamespace):
+ (WebKit::StorageManager::getOrCreateTransientLocalStorageNamespace):
+ (WebKit::StorageManager::getOrCreateSessionStorageNamespace):
+ (WebKit::StorageManager::clearStorageNamespaces):
+ (WebKit::StorageManager::addAllowedSessionStorageNamespaceConnection): Deleted.
+ (WebKit::StorageManager::removeAllowedSessionStorageNamespaceConnection): Deleted.
+ (WebKit::StorageManager::processDidCloseConnection): Deleted.
+ (WebKit::StorageManager::deleteLocalStorageEntriesForOrigin): Deleted.
+ (WebKit::StorageManager::createLocalStorageMap): Deleted.
+ (WebKit::StorageManager::createTransientLocalStorageMap): Deleted.
+ (WebKit::StorageManager::createSessionStorageMap): Deleted.
+ (WebKit::StorageManager::destroyStorageMap): Deleted.
+ (WebKit::StorageManager::prewarm): Deleted.
+ (WebKit::StorageManager::getValues): Deleted.
+ (WebKit::StorageManager::setItem): Deleted.
+ (WebKit::StorageManager::setItems): Deleted.
+ (WebKit::StorageManager::removeItem): Deleted.
+ (WebKit::StorageManager::clear): Deleted.
+ (WebKit::StorageManager::waitUntilTasksFinished): Deleted.
+ (WebKit::StorageManager::suspend): Deleted.
+ (WebKit::StorageManager::resume): Deleted.
+ (WebKit::StorageManager::findStorageArea const): Deleted.
+ * NetworkProcess/WebStorage/StorageManager.h:
+ (WebKit::StorageManager::workQueue const): Deleted.
+ (): Deleted.
+
+ * NetworkProcess/WebStorage/StorageManager.messages.in: Removed. Moved to StorageManagerSet.messages.in.
+
+ * NetworkProcess/WebStorage/StorageManagerSet.cpp: Added.
+ (WebKit::StorageManagerSet::create):
+ (WebKit::StorageManagerSet::StorageManagerSet):
+ (WebKit::StorageManagerSet::~StorageManagerSet):
+ (WebKit::StorageManagerSet::add):
+ (WebKit::StorageManagerSet::remove):
+ (WebKit::StorageManagerSet::contains):
+ (WebKit::StorageManagerSet::addConnection):
+ (WebKit::StorageManagerSet::removeConnection):
+ (WebKit::StorageManagerSet::waitUntilTasksFinished):
+ (WebKit::StorageManagerSet::waitUntilSyncingLocalStorageFinished):
+ (WebKit::StorageManagerSet::suspend):
+ (WebKit::StorageManagerSet::resume):
+ (WebKit::StorageManagerSet::getSessionStorageOrigins):
+ (WebKit::StorageManagerSet::deleteSessionStorage):
+ (WebKit::StorageManagerSet::deleteSessionStorageForOrigins):
+ (WebKit::StorageManagerSet::getLocalStorageOrigins):
+ (WebKit::StorageManagerSet::deleteLocalStorageModifiedSince):
+ (WebKit::StorageManagerSet::deleteLocalStorageForOrigins):
+ (WebKit::StorageManagerSet::getLocalStorageOriginDetails):
+ (WebKit::StorageManagerSet::connectToLocalStorageArea):
+ (WebKit::StorageManagerSet::connectToTransientLocalStorageArea):
+ (WebKit::StorageManagerSet::connectToSessionStorageArea):
+ (WebKit::StorageManagerSet::disconnectFromStorageArea):
+ (WebKit::StorageManagerSet::getValues):
+ (WebKit::StorageManagerSet::setItem):
+ (WebKit::StorageManagerSet::removeItem):
+ (WebKit::StorageManagerSet::clear):
+ (WebKit::StorageManagerSet::cloneSessionStorageNamespace):
+ * NetworkProcess/WebStorage/StorageManagerSet.h: Added.
+ * NetworkProcess/WebStorage/StorageManagerSet.messages.in: Added.
+
+ * Shared/WebsiteDataStoreParameters.cpp: creation parameters of StorageManager are moved to
+ WebsiteDataStoreParameters.
+ (WebKit::WebsiteDataStoreParameters::encode const):
+ (WebKit::WebsiteDataStoreParameters::decode):
+ (WebKit::WebsiteDataStoreParameters::privateSessionParameters):
+ * Shared/WebsiteDataStoreParameters.h:
+ * Sources.txt:
+
+ * UIProcess/API/C/WKContext.cpp: add SPI for tests.
+ (WKContextSyncLocalStorage):
+ (WKContextClearLegacyPrivateBrowsingLocalStorage):
+ * UIProcess/API/C/WKContextPrivate.h:
+ * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
+ (WKWebsiteDataStoreRemoveLocalStorage):
+ * UIProcess/API/C/WKWebsiteDataStoreRef.h:
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::ensureNetworkProcess):
+ (WebKit::WebProcessPool::syncLocalStorage):
+ (WebKit::WebProcessPool::clearLegacyPrivateBrowsingLocalStorage):
+ * UIProcess/WebProcessPool.h:
+ * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
+ (WebKit::WebsiteDataStore::parameters):
+ * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+ (WebKit::WebsiteDataStore::parameters):
+ * WebKit.xcodeproj/project.pbxproj:
+
+ * WebProcess/InjectedBundle/InjectedBundle.cpp: session change of web storage is done via
+ WebStorageNamespaceProvider instead of WebProcess now.
+ (WebKit::InjectedBundle::setPrivateBrowsingEnabled):
+ * WebProcess/WebProcess.cpp: web process no longer sends messsages about page state to network process.
+ (WebKit::WebProcess::createWebPage):
+ (WebKit::WebProcess::removeWebPage):
+ (WebKit::WebProcess::ensureNetworkProcessConnection):
+ (WebKit::WebProcess::networkProcessConnectionClosed):
+ (WebKit::WebProcess::storageAreaMap const):
+ (WebKit::WebProcess::enablePrivateBrowsingForTesting): Deleted. This was used for changing session via
+ WebProcess.
+ * WebProcess/WebProcess.h:
+ * WebProcess/WebStorage/StorageAreaImpl.cpp:
+ (WebKit::StorageAreaImpl::StorageAreaImpl):
+ (WebKit::StorageAreaImpl::length):
+ (WebKit::StorageAreaImpl::key):
+ (WebKit::StorageAreaImpl::item):
+ (WebKit::StorageAreaImpl::setItem):
+ (WebKit::StorageAreaImpl::removeItem):
+ (WebKit::StorageAreaImpl::clear):
+ (WebKit::StorageAreaImpl::contains):
+ (WebKit::StorageAreaImpl::storageType const):
+ (WebKit::StorageAreaImpl::incrementAccessCount):
+ (WebKit::StorageAreaImpl::decrementAccessCount):
+ (WebKit::StorageAreaImpl::prewarm): Deleted.
+ (WebKit::StorageAreaImpl::securityOrigin const): Deleted.
+
+ * WebProcess/WebStorage/StorageAreaImpl.h: make StorageAreaImpl hold a weak reference to StorageAreaMap and
+ StorageNamespaceImpl hold a strong reference. In this way lifeime of localStorage StorageAreraMap stays align
+ with StorageNameSpaceProvider and Page.
+
+ * WebProcess/WebStorage/StorageAreaMap.cpp: identifier of StorageAreaMap is the same as identifier of
+ StorageArea it connects to. If the identifier is 0, it means the StorageAreaMap is disconnected.
+ (WebKit::StorageAreaMap::StorageAreaMap):
+ (WebKit::StorageAreaMap::~StorageAreaMap):
+ (WebKit::StorageAreaMap::setItem):
+ (WebKit::StorageAreaMap::removeItem):
+ (WebKit::StorageAreaMap::clear):
+ (WebKit::StorageAreaMap::resetValues):
+ (WebKit::StorageAreaMap::loadValuesIfNeeded):
+ (WebKit::StorageAreaMap::applyChange):
+ (WebKit::StorageAreaMap::dispatchStorageEvent):
+ (WebKit::StorageAreaMap::dispatchSessionStorageEvent):
+ (WebKit::StorageAreaMap::dispatchLocalStorageEvent):
+ (WebKit::StorageAreaMap::connect):
+ (WebKit::StorageAreaMap::disconnect):
+ (WebKit::generateStorageMapID): Deleted.
+ (WebKit::StorageAreaMap::prewarm): Deleted.
+ (WebKit::StorageAreaMap::didGetValues): Deleted. This is useless as GetValues is a synchronous operation.
+ * WebProcess/WebStorage/StorageAreaMap.h:
+ (): Deleted.
+
+ * WebProcess/WebStorage/StorageAreaMap.messages.in: there are two synchronous messages, one for connection and
+ one for getting values. We may merge them into one in future improvement.
+ * WebProcess/WebStorage/StorageNamespaceImpl.cpp:
+ (WebKit::StorageNamespaceImpl::createSessionStorageNamespace):
+ (WebKit::StorageNamespaceImpl::createLocalStorageNamespace):
+ (WebKit::StorageNamespaceImpl::createTransientLocalStorageNamespace):
+ (WebKit::StorageNamespaceImpl::StorageNamespaceImpl):
+ (WebKit::StorageNamespaceImpl::storageArea):
+ (WebKit::StorageNamespaceImpl::copy):
+ (WebKit::StorageNamespaceImpl::setSessionIDForTesting):
+ (WebKit::StorageNamespaceImpl::createEphemeralLocalStorageNamespace): Deleted.
+ * WebProcess/WebStorage/StorageNamespaceImpl.h:
+ * WebProcess/WebStorage/WebStorageNamespaceProvider.cpp:
+ (WebKit::WebStorageNamespaceProvider::createSessionStorageNamespace):
+ (WebKit::WebStorageNamespaceProvider::createLocalStorageNamespace):
+ (WebKit::WebStorageNamespaceProvider::createTransientLocalStorageNamespace):
+ (WebKit::WebStorageNamespaceProvider::createEphemeralLocalStorageNamespace): Deleted.
+ * WebProcess/WebStorage/WebStorageNamespaceProvider.h:
+
2019-08-15 Wenson Hsieh <wenson_hsieh@apple.com>
Occasional hang under -[UIKeyboardTaskQueue lockWhenReadyForMainThread] when long-pressing non-editable text
diff --git a/Source/WebKit/DerivedSources-input.xcfilelist b/Source/WebKit/DerivedSources-input.xcfilelist
index 0fb8423..2e47660 100644
--- a/Source/WebKit/DerivedSources-input.xcfilelist
+++ b/Source/WebKit/DerivedSources-input.xcfilelist
@@ -25,7 +25,7 @@
$(PROJECT_DIR)/NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.messages.in
$(PROJECT_DIR)/NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in
$(PROJECT_DIR)/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.messages.in
-$(PROJECT_DIR)/NetworkProcess/WebStorage/StorageManager.messages.in
+$(PROJECT_DIR)/NetworkProcess/WebStorage/StorageManagerSet.messages.in
$(PROJECT_DIR)/NetworkProcess/cache/CacheStorageEngineConnection.messages.in
$(PROJECT_DIR)/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in
$(PROJECT_DIR)/NetworkProcess/webrtc/NetworkMDNSRegister.messages.in
@@ -83,7 +83,6 @@
$(PROJECT_DIR)/UIProcess/WebPasteboardProxy.messages.in
$(PROJECT_DIR)/UIProcess/WebProcessPool.messages.in
$(PROJECT_DIR)/UIProcess/WebProcessProxy.messages.in
-$(PROJECT_DIR)/UIProcess/WebStorage/StorageManager.messages.in
$(PROJECT_DIR)/UIProcess/ios/EditableImageController.messages.in
$(PROJECT_DIR)/UIProcess/ios/SmartMagnificationController.messages.in
$(PROJECT_DIR)/UIProcess/mac/SecItemShimProxy.messages.in
diff --git a/Source/WebKit/DerivedSources-output.xcfilelist b/Source/WebKit/DerivedSources-output.xcfilelist
index fe0a6c0..bd9dd7f 100644
--- a/Source/WebKit/DerivedSources-output.xcfilelist
+++ b/Source/WebKit/DerivedSources-output.xcfilelist
@@ -88,8 +88,8 @@
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/SmartMagnificationControllerMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/StorageAreaMapMessageReceiver.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/StorageAreaMapMessages.h
-$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/StorageManagerMessageReceiver.cpp
-$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/StorageManagerMessages.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/StorageManagerSetMessageReceiver.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/StorageManagerSetMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/TextCheckingControllerProxyMessageReceiver.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/TextCheckingControllerProxyMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/UserMediaCaptureManagerMessageReceiver.cpp
diff --git a/Source/WebKit/DerivedSources.make b/Source/WebKit/DerivedSources.make
index 5393c5b..9de7042 100644
--- a/Source/WebKit/DerivedSources.make
+++ b/Source/WebKit/DerivedSources.make
@@ -136,7 +136,7 @@
ServiceWorkerFetchTask \
SmartMagnificationController \
StorageAreaMap \
- StorageManager \
+ StorageManagerSet \
TextCheckingControllerProxy \
UserMediaCaptureManager \
UserMediaCaptureManagerProxy \
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
index 0c2c976..bbe9a9a 100644
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp
@@ -49,7 +49,6 @@
#include "PingLoad.h"
#include "PreconnectTask.h"
#include "ServiceWorkerFetchTaskMessages.h"
-#include "StorageManager.h"
#include "WebCoreArgumentCoders.h"
#include "WebErrors.h"
#include "WebIDBConnectionToClient.h"
@@ -299,7 +298,7 @@
// root activity trackers.
stopAllNetworkActivityTracking();
- m_networkProcess->webProcessWasDisconnected(connection);
+ m_networkProcess->connectionToWebProcessClosed(connection);
m_networkProcess->removeNetworkConnectionToWebProcess(*this);
@@ -915,19 +914,4 @@
}
#endif
-void NetworkConnectionToWebProcess::webPageWasAdded(PAL::SessionID sessionID, PageIdentifier pageID, WebCore::PageIdentifier oldPageID)
-{
- m_networkProcess->webPageWasAdded(m_connection.get(), sessionID, pageID, oldPageID);
-}
-
-void NetworkConnectionToWebProcess::webPageWasRemoved(PAL::SessionID sessionID, PageIdentifier pageID)
-{
- m_networkProcess->webPageWasRemoved(m_connection.get(), sessionID, pageID);
-}
-
-void NetworkConnectionToWebProcess::webProcessSessionChanged(PAL::SessionID newSessionID, const Vector<PageIdentifier>& pages)
-{
- m_networkProcess->webProcessSessionChanged(m_connection.get(), newSessionID, pages);
-}
-
} // namespace WebKit
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
index 255084f..0aa02d3 100644
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h
@@ -141,10 +141,6 @@
Vector<RefPtr<WebCore::BlobDataFileReference>> resolveBlobReferences(const NetworkResourceLoadParameters&);
- void webPageWasAdded(PAL::SessionID, WebCore::PageIdentifier, WebCore::PageIdentifier oldPageID);
- void webPageWasRemoved(PAL::SessionID, WebCore::PageIdentifier);
- void webProcessSessionChanged(PAL::SessionID newSessionID, const Vector<WebCore::PageIdentifier>& pages);
-
void removeSocketChannel(uint64_t identifier);
private:
diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
index 99abd07..fd4b248 100644
--- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
+++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in
@@ -86,8 +86,4 @@
#if ENABLE(SERVICE_WORKER)
EstablishSWServerConnection(PAL::SessionID sessionID) -> (WebCore::SWServerConnectionIdentifier serverConnectionIdentifier) Synchronous
#endif
-
- WebPageWasAdded(PAL::SessionID sessionID, WebCore::PageIdentifier pageID, WebCore::PageIdentifier oldPageID)
- WebPageWasRemoved(PAL::SessionID sessionID, WebCore::PageIdentifier pageID)
- WebProcessSessionChanged(PAL::SessionID newSessionID, Vector<WebCore::PageIdentifier> pages)
}
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
index e820b29..fbe8e68 100644
--- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp
@@ -53,8 +53,7 @@
#include "ShouldGrandfatherStatistics.h"
#include "StatisticsData.h"
#include "StorageAccessStatus.h"
-#include "StorageManager.h"
-#include "StorageManagerMessages.h"
+#include "StorageManagerSet.h"
#include "WebCookieManager.h"
#include "WebPageProxyMessages.h"
#include "WebProcessPoolMessages.h"
@@ -133,6 +132,7 @@
NetworkProcess::NetworkProcess(AuxiliaryProcessInitializationParameters&& parameters)
: m_downloadManager(*this)
+ , m_storageManagerSet(StorageManagerSet::create())
#if ENABLE(CONTENT_EXTENSIONS)
, m_networkContentRuleListManager(*this)
#endif
@@ -336,6 +336,8 @@
#endif
initializeStorageQuota(parameters.defaultDataStoreParameters);
+ m_storageManagerSet->add(sessionID, parameters.defaultDataStoreParameters.localStorageDirectory, parameters.defaultDataStoreParameters.localStorageDirectoryExtensionHandle);
+
auto* defaultSession = networkSession(PAL::SessionID::defaultSessionID());
auto* defaultStorageSession = defaultSession->networkStorageSession();
for (const auto& cookie : parameters.defaultDataStoreParameters.pendingCookies)
@@ -447,6 +449,8 @@
UNUSED_PARAM(isServiceWorkerProcess);
UNUSED_PARAM(registrableDomain);
#endif
+
+ m_storageManagerSet->addConnection(m_webProcessConnections.last()->connection());
}
void NetworkProcess::clearCachedCredentials()
@@ -469,6 +473,8 @@
addServiceWorkerSession(parameters.networkSessionParameters.sessionID, parameters.serviceWorkerRegistrationDirectory, parameters.serviceWorkerRegistrationDirectoryExtensionHandle);
#endif
+ m_storageManagerSet->add(parameters.networkSessionParameters.sessionID, parameters.localStorageDirectory, parameters.localStorageDirectoryExtensionHandle);
+
initializeStorageQuota(parameters);
RemoteNetworkingContext::ensureWebsiteDataStoreSession(*this, WTFMove(parameters));
@@ -609,6 +615,8 @@
m_swDatabasePaths.remove(sessionID);
#endif
+ m_storageManagerSet->remove(sessionID);
+
m_storageQuotaManagers.remove(sessionID);
}
@@ -1050,8 +1058,8 @@
void NetworkProcess::hasLocalStorage(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
{
- if (auto* session = networkSession(sessionID)) {
- session->storageManager().getLocalStorageOrigins([domain, completionHandler = WTFMove(completionHandler)](auto&& origins) mutable {
+ if (m_storageManagerSet->contains(sessionID)) {
+ m_storageManagerSet->getLocalStorageOrigins(sessionID, [domain, completionHandler = WTFMove(completionHandler)](auto&& origins) mutable {
completionHandler(WTF::anyOf(origins, [&domain](auto& origin) {
return domain.matches(origin);
}));
@@ -1340,16 +1348,15 @@
});
}
- auto* session = networkSession(sessionID);
- if (websiteDataTypes.contains(WebsiteDataType::SessionStorage) && session) {
- session->storageManager().getSessionStorageOrigins([callbackAggregator = callbackAggregator.copyRef()](auto&& origins) {
+ if (websiteDataTypes.contains(WebsiteDataType::SessionStorage) && m_storageManagerSet->contains(sessionID)) {
+ m_storageManagerSet->getSessionStorageOrigins(sessionID, [callbackAggregator = callbackAggregator.copyRef()](auto&& origins) {
while (!origins.isEmpty())
callbackAggregator->m_websiteData.entries.append(WebsiteData::Entry { origins.takeAny(), WebsiteDataType::SessionStorage, 0 });
});
}
- if (websiteDataTypes.contains(WebsiteDataType::LocalStorage) && session) {
- session->storageManager().getLocalStorageOrigins([callbackAggregator = callbackAggregator.copyRef()](auto&& origins) {
+ if (websiteDataTypes.contains(WebsiteDataType::LocalStorage) && m_storageManagerSet->contains(sessionID)) {
+ m_storageManagerSet->getLocalStorageOrigins(sessionID, [callbackAggregator = callbackAggregator.copyRef()](auto&& origins) {
while (!origins.isEmpty())
callbackAggregator->m_websiteData.entries.append(WebsiteData::Entry { origins.takeAny(), WebsiteDataType::LocalStorage, 0 });
});
@@ -1424,12 +1431,11 @@
if (websiteDataTypes.contains(WebsiteDataType::DOMCache))
CacheStorage::Engine::clearAllCaches(*this, sessionID, [clearTasksHandler = clearTasksHandler.copyRef()] { });
- auto* session = networkSession(sessionID);
- if (websiteDataTypes.contains(WebsiteDataType::SessionStorage) && session)
- session->storageManager().deleteSessionStorageOrigins([clearTasksHandler = clearTasksHandler.copyRef()] { });
+ if (websiteDataTypes.contains(WebsiteDataType::SessionStorage) && m_storageManagerSet->contains(sessionID))
+ m_storageManagerSet->deleteSessionStorage(sessionID, [clearTasksHandler = clearTasksHandler.copyRef()] { });
- if (websiteDataTypes.contains(WebsiteDataType::LocalStorage) && session)
- session->storageManager().deleteLocalStorageOriginsModifiedSince(modifiedSince, [clearTasksHandler = clearTasksHandler.copyRef()] { });
+ if (websiteDataTypes.contains(WebsiteDataType::LocalStorage) && m_storageManagerSet->contains(sessionID))
+ m_storageManagerSet->deleteLocalStorageModifiedSince(sessionID, modifiedSince, [clearTasksHandler = clearTasksHandler.copyRef()] { });
#if ENABLE(INDEXED_DATABASE)
if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases) && !sessionID.isEphemeral())
@@ -1524,12 +1530,11 @@
CacheStorage::Engine::clearCachesForOrigin(*this, sessionID, SecurityOriginData { originData }, [clearTasksHandler = clearTasksHandler.copyRef()] { });
}
- auto* session = networkSession(sessionID);
- if (websiteDataTypes.contains(WebsiteDataType::SessionStorage) && session)
- session->storageManager().deleteSessionStorageEntriesForOrigins(originDatas, [clearTasksHandler = clearTasksHandler.copyRef()] { });
+ if (websiteDataTypes.contains(WebsiteDataType::SessionStorage) && m_storageManagerSet->contains(sessionID))
+ m_storageManagerSet->deleteSessionStorageForOrigins(sessionID, originDatas, [clearTasksHandler = clearTasksHandler.copyRef()] { });
- if (websiteDataTypes.contains(WebsiteDataType::LocalStorage) && session)
- session->storageManager().deleteLocalStorageEntriesForOrigins(originDatas, [clearTasksHandler = clearTasksHandler.copyRef()] { });
+ if (websiteDataTypes.contains(WebsiteDataType::LocalStorage) && m_storageManagerSet->contains(sessionID))
+ m_storageManagerSet->deleteLocalStorageForOrigins(sessionID, originDatas, [clearTasksHandler = clearTasksHandler.copyRef()] { });
#if ENABLE(INDEXED_DATABASE)
if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases) && !sessionID.isEphemeral())
@@ -1726,20 +1731,18 @@
});
}
- auto* session = networkSession(sessionID);
- if (session) {
- auto& storageManager = session->storageManager();
+ if (m_storageManagerSet->contains(sessionID)) {
if (websiteDataTypes.contains(WebsiteDataType::SessionStorage)) {
- storageManager.getSessionStorageOrigins([storageManager = makeRefPtr(storageManager), callbackAggregator = callbackAggregator.copyRef(), domainsToDeleteAllButCookiesFor](auto&& origins) {
+ m_storageManagerSet->getSessionStorageOrigins(sessionID, [protectedThis = makeRef(*this), this, sessionID, callbackAggregator = callbackAggregator.copyRef(), domainsToDeleteAllButCookiesFor](auto&& origins) {
auto originsToDelete = filterForRegistrableDomains(origins, domainsToDeleteAllButCookiesFor, callbackAggregator->m_domains);
- storageManager->deleteSessionStorageEntriesForOrigins(originsToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
+ m_storageManagerSet->deleteSessionStorageForOrigins(sessionID, originsToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
});
}
if (websiteDataTypes.contains(WebsiteDataType::LocalStorage)) {
- storageManager.getLocalStorageOrigins([storageManager = makeRefPtr(storageManager), callbackAggregator = callbackAggregator.copyRef(), domainsToDeleteAllButCookiesFor](auto&& origins) {
+ m_storageManagerSet->getLocalStorageOrigins(sessionID, [protectedThis = makeRef(*this), this, sessionID, callbackAggregator = callbackAggregator.copyRef(), domainsToDeleteAllButCookiesFor](auto&& origins) {
auto originsToDelete = filterForRegistrableDomains(origins, domainsToDeleteAllButCookiesFor, callbackAggregator->m_domains);
- storageManager->deleteLocalStorageEntriesForOrigins(originsToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
+ m_storageManagerSet->deleteLocalStorageForOrigins(sessionID, originsToDelete, [callbackAggregator = callbackAggregator.copyRef()] { });
});
}
}
@@ -2111,9 +2114,7 @@
}
#endif
- forEachNetworkSession([&callbackAggregator](auto& session) {
- session.storageManager().suspend([callbackAggregator] { });
- });
+ m_storageManagerSet->suspend([callbackAggregator] { });
}
void NetworkProcess::processWillSuspendImminently()
@@ -2189,9 +2190,7 @@
server->resume();
#endif
- forEachNetworkSession([](auto& session) {
- session.storageManager().resume();
- });
+ m_storageManagerSet->resume();
}
void NetworkProcess::prefetchDNS(const String& hostname)
@@ -2396,6 +2395,18 @@
}
#endif // ENABLE(INDEXED_DATABASE)
+void NetworkProcess::syncLocalStorage(CompletionHandler<void()>&& completionHandler)
+{
+ m_storageManagerSet->waitUntilSyncingLocalStorageFinished();
+ completionHandler();
+}
+
+void NetworkProcess::clearLegacyPrivateBrowsingLocalStorage()
+{
+ if (m_storageManagerSet->contains(PAL::SessionID::legacyPrivateSessionID()))
+ m_storageManagerSet->deleteLocalStorageModifiedSince(PAL::SessionID::legacyPrivateSessionID(), -WallTime::infinity(), []() { });
+}
+
void NetworkProcess::updateQuotaBasedOnSpaceUsageForTesting(PAL::SessionID sessionID, const ClientOrigin& origin)
{
auto& manager = storageQuotaManager(sessionID, origin);
@@ -2703,80 +2714,21 @@
session->removeKeptAliveLoad(loader);
}
-void NetworkProcess::webPageWasAdded(IPC::Connection& connection, PAL::SessionID sessionID, PageIdentifier pageID, PageIdentifier oldPageID)
-{
- if (!pageID || !oldPageID) {
- LOG_ERROR("Cannot add page with invalid id");
- return;
- }
-
- auto* session = networkSession(sessionID);
- if (!session) {
- LOG_ERROR("Cannot add page to an unknown session");
- return;
- }
- auto& storageManager = session->storageManager();
-
- auto addResult = m_sessionByConnection.add(connection.uniqueID(), sessionID);
- ASSERT_UNUSED(addResult, addResult.iterator->value == sessionID);
-
- storageManager.createSessionStorageNamespace(pageID.toUInt64(), std::numeric_limits<unsigned>::max());
- storageManager.addAllowedSessionStorageNamespaceConnection(pageID.toUInt64(), connection);
- if (pageID != oldPageID)
- storageManager.cloneSessionStorageNamespace(oldPageID.toUInt64(), pageID.toUInt64());
-}
-
-void NetworkProcess::webPageWasRemoved(IPC::Connection& connection, PAL::SessionID sessionID, PageIdentifier pageID)
-{
- if (!pageID) {
- LOG_ERROR("Cannot remove page with invalid id");
- return;
- }
-
- auto* session = networkSession(sessionID);
- // Session can be destroyed before page gets removed.
- if (!session)
- return;
-
- auto& storageManager = session->storageManager();
- storageManager.removeAllowedSessionStorageNamespaceConnection(pageID.toUInt64(), connection);
- storageManager.destroySessionStorageNamespace(pageID.toUInt64());
-}
-
-void NetworkProcess::webProcessWasDisconnected(IPC::Connection& connection)
-{
- auto sessionID = m_sessionByConnection.take(connection.uniqueID());
- if (!sessionID.isValid())
- return;
-
- if (auto* session = networkSession(sessionID))
- session->storageManager().processDidCloseConnection(connection);
-}
-
-void NetworkProcess::webProcessSessionChanged(IPC::Connection& connection, PAL::SessionID newSessionID, const Vector<PageIdentifier>& pageIDs)
-{
- auto connectionID = connection.uniqueID();
- ASSERT(m_sessionByConnection.contains(connectionID));
- if (m_sessionByConnection.get(connectionID) == newSessionID)
- return;
-
- webProcessWasDisconnected(connection);
- for (auto& pageID : pageIDs)
- webPageWasAdded(connection, newSessionID, pageID, pageID);
-}
-
void NetworkProcess::getLocalStorageOriginDetails(PAL::SessionID sessionID, CompletionHandler<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&& completionHandler)
{
- auto* session = networkSession(sessionID);
- if (!session) {
+ if (!m_storageManagerSet->contains(sessionID)) {
LOG_ERROR("Cannot get local storage information for an unknown session");
return;
}
- auto& storageManager = session->storageManager();
- storageManager.getLocalStorageOriginDetails([completionHandler = WTFMove(completionHandler)](auto&& details) mutable {
+ m_storageManagerSet->getLocalStorageOriginDetails(sessionID, [completionHandler = WTFMove(completionHandler)](auto&& details) mutable {
completionHandler(WTFMove(details));
});
}
+void NetworkProcess::connectionToWebProcessClosed(IPC::Connection& connection)
+{
+ m_storageManagerSet->removeConnection(connection);
+}
+
} // namespace WebKit
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h
index 6121bad..3211e90 100644
--- a/Source/WebKit/NetworkProcess/NetworkProcess.h
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.h
@@ -97,6 +97,7 @@
class NetworkProcessSupplement;
class NetworkProximityManager;
class NetworkResourceLoader;
+class StorageManagerSet;
class WebSWServerConnection;
class WebSWServerToContextConnection;
enum class ShouldGrandfatherStatistics : bool;
@@ -269,10 +270,7 @@
void setSessionIsControlledByAutomation(PAL::SessionID, bool);
bool sessionIsControlledByAutomation(PAL::SessionID) const;
- void webPageWasAdded(IPC::Connection&, PAL::SessionID, WebCore::PageIdentifier, WebCore::PageIdentifier);
- void webPageWasRemoved(IPC::Connection&, PAL::SessionID, WebCore::PageIdentifier);
- void webProcessWasDisconnected(IPC::Connection&);
- void webProcessSessionChanged(IPC::Connection&, PAL::SessionID, const Vector<WebCore::PageIdentifier>&);
+ void connectionToWebProcessClosed(IPC::Connection&);
void getLocalStorageOriginDetails(PAL::SessionID, CompletionHandler<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&&);
#if ENABLE(CONTENT_EXTENSIONS)
@@ -285,6 +283,10 @@
void accessToTemporaryFileComplete(const String& path) final;
void setIDBPerOriginQuota(uint64_t);
#endif
+
+ void syncLocalStorage(CompletionHandler<void()>&&);
+ void clearLegacyPrivateBrowsingLocalStorage();
+
void updateQuotaBasedOnSpaceUsageForTesting(PAL::SessionID, const WebCore::ClientOrigin&);
#if ENABLE(SANDBOX_EXTENSIONS)
@@ -499,6 +501,8 @@
HashMap<PAL::SessionID, std::unique_ptr<WebCore::NetworkStorageSession>> m_networkStorageSessions;
mutable std::unique_ptr<WebCore::NetworkStorageSession> m_defaultNetworkStorageSession;
+ RefPtr<StorageManagerSet> m_storageManagerSet;
+
#if PLATFORM(COCOA)
void platformInitializeNetworkProcessCocoa(const NetworkProcessCreationParameters&);
void setStorageAccessAPIEnabled(bool);
diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
index b76daa1..c553a88 100644
--- a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
+++ b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
@@ -163,6 +163,10 @@
#if ENABLE(INDEXED_DATABASE)
SetIDBPerOriginQuota(uint64_t quota)
#endif
+
+ SyncLocalStorage() -> () Synchronous
+ ClearLegacyPrivateBrowsingLocalStorage()
+
UpdateQuotaBasedOnSpaceUsageForTesting(PAL::SessionID sessionID, struct WebCore::ClientOrigin origin)
StoreAdClickAttribution(PAL::SessionID sessionID, WebCore::AdClickAttribution adClickAttribution)
diff --git a/Source/WebKit/NetworkProcess/NetworkSession.cpp b/Source/WebKit/NetworkProcess/NetworkSession.cpp
index 488b929..1a13962 100644
--- a/Source/WebKit/NetworkProcess/NetworkSession.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkSession.cpp
@@ -33,7 +33,6 @@
#include "NetworkResourceLoadParameters.h"
#include "NetworkResourceLoader.h"
#include "PingLoad.h"
-#include "StorageManager.h"
#include "WebPageProxy.h"
#include "WebPageProxyMessages.h"
#include "WebProcessProxy.h"
@@ -85,7 +84,6 @@
, m_enableResourceLoadStatisticsLogTestingEvent(parameters.enableResourceLoadStatisticsLogTestingEvent)
#endif
, m_adClickAttribution(makeUniqueRef<AdClickAttributionManager>(parameters.sessionID))
- , m_storageManager(StorageManager::create(String(parameters.localStorageDirectory)))
{
if (!m_sessionID.isEphemeral()) {
String networkCacheDirectory = parameters.networkCacheDirectory;
@@ -99,7 +97,6 @@
RELEASE_LOG_ERROR(NetworkCache, "Failed to initialize the WebKit network disk cache");
}
- SandboxExtension::consumePermanently(parameters.localStorageDirectoryExtensionHandle);
m_adClickAttribution->setPingLoadFunction([this, weakThis = makeWeakPtr(this)](NetworkResourceLoadParameters&& loadParameters, CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&)>&& completionHandler) {
if (!weakThis)
return;
@@ -113,9 +110,6 @@
#if ENABLE(RESOURCE_LOAD_STATISTICS)
destroyResourceLoadStatistics();
#endif
-
- m_storageManager->resume();
- m_storageManager->waitUntilTasksFinished();
}
#if ENABLE(RESOURCE_LOAD_STATISTICS)
diff --git a/Source/WebKit/NetworkProcess/NetworkSession.h b/Source/WebKit/NetworkProcess/NetworkSession.h
index 506e7ff..6849b30 100644
--- a/Source/WebKit/NetworkProcess/NetworkSession.h
+++ b/Source/WebKit/NetworkProcess/NetworkSession.h
@@ -52,7 +52,6 @@
class NetworkDataTask;
class NetworkProcess;
class NetworkResourceLoader;
-class StorageManager;
class NetworkSocketChannel;
class WebResourceLoadStatisticsStore;
class WebSocketTask;
@@ -81,8 +80,6 @@
void registerNetworkDataTask(NetworkDataTask& task) { m_dataTaskSet.add(&task); }
void unregisterNetworkDataTask(NetworkDataTask& task) { m_dataTaskSet.remove(&task); }
- StorageManager& storageManager() { return m_storageManager.get(); }
-
#if ENABLE(RESOURCE_LOAD_STATISTICS)
WebResourceLoadStatisticsStore* resourceLoadStatistics() const { return m_resourceLoadStatistics.get(); }
void setResourceLoadStatisticsEnabled(bool);
@@ -145,7 +142,6 @@
PrefetchCache m_prefetchCache;
- Ref<StorageManager> m_storageManager;
#if !ASSERT_DISABLED
bool m_isInvalidated { false };
#endif
diff --git a/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp b/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp
index c1b977c..b29f493 100644
--- a/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp
+++ b/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp
@@ -50,7 +50,7 @@
#if USE(CURL)
, { }, { }
#endif
- , { }, { }, false, false, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
+ , { }, { }, false, false, { }, { }, { }, { }, { }, { }, { }, { }
};
}
@@ -86,7 +86,6 @@
encoder << resourceLoadStatisticsManualPrevalentResource;
encoder << enableResourceLoadStatisticsNSURLSessionSwitching;
- encoder << localStorageDirectory << localStorageDirectoryExtensionHandle;
encoder << networkCacheDirectory << networkCacheDirectoryExtensionHandle;
encoder << deviceManagementRestrictionsEnabled;
@@ -214,16 +213,6 @@
decoder >> enableResourceLoadStatisticsNSURLSessionSwitching;
if (!enableResourceLoadStatisticsNSURLSessionSwitching)
return WTF::nullopt;
-
- Optional<String> localStorageDirectory;
- decoder >> localStorageDirectory;
- if (!localStorageDirectory)
- return WTF::nullopt;
-
- Optional<SandboxExtension::Handle> localStorageDirectoryExtensionHandle;
- decoder >> localStorageDirectoryExtensionHandle;
- if (!localStorageDirectoryExtensionHandle)
- return WTF::nullopt;
Optional<String> networkCacheDirectory;
decoder >> networkCacheDirectory;
@@ -277,8 +266,6 @@
, WTFMove(*deviceManagementRestrictionsEnabled)
, WTFMove(*allLoadsBlockedByDeviceManagementRestrictionsForTesting)
, WTFMove(*resourceLoadStatisticsManualPrevalentResource)
- , WTFMove(*localStorageDirectory)
- , WTFMove(*localStorageDirectoryExtensionHandle)
, WTFMove(*networkCacheDirectory)
, WTFMove(*networkCacheDirectoryExtensionHandle)
}};
diff --git a/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h b/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h
index 1833e46..50be30e 100644
--- a/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h
+++ b/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h
@@ -92,8 +92,6 @@
bool allLoadsBlockedByDeviceManagementRestrictionsForTesting { false };
WebCore::RegistrableDomain resourceLoadStatisticsManualPrevalentResource { };
- String localStorageDirectory;
- SandboxExtension::Handle localStorageDirectoryExtensionHandle;
String networkCacheDirectory;
SandboxExtension::Handle networkCacheDirectoryExtensionHandle;
};
diff --git a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp
index bf51578..8f4763c 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp
+++ b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp
@@ -259,7 +259,6 @@
if (m_isClosed)
return;
- ASSERT(m_didScheduleDatabaseUpdate);
m_didScheduleDatabaseUpdate = false;
HashMap<String, String> changedItems;
diff --git a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.h b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.h
index 4d6876b..8cfb24b 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.h
+++ b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.h
@@ -55,6 +55,8 @@
void removeItem(const String& key);
void clear();
+ void updateDatabase();
+
// Will block until all pending changes have been written to disk.
void close();
@@ -73,7 +75,6 @@
void itemDidChange(const String& key, const String& value);
void scheduleDatabaseUpdate();
- void updateDatabase();
void updateDatabaseWithChangedItems(const HashMap<String, String>&);
bool databaseIsEmpty();
diff --git a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabaseTracker.cpp b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabaseTracker.cpp
index 07a633f..6732709 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabaseTracker.cpp
+++ b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabaseTracker.cpp
@@ -39,24 +39,17 @@
namespace WebKit {
using namespace WebCore;
-Ref<LocalStorageDatabaseTracker> LocalStorageDatabaseTracker::create(Ref<WorkQueue>&& queue, String&& localStorageDirectory)
+Ref<LocalStorageDatabaseTracker> LocalStorageDatabaseTracker::create(String&& localStorageDirectory)
{
- return adoptRef(*new LocalStorageDatabaseTracker(WTFMove(queue), WTFMove(localStorageDirectory)));
+ return adoptRef(*new LocalStorageDatabaseTracker(WTFMove(localStorageDirectory)));
}
-LocalStorageDatabaseTracker::LocalStorageDatabaseTracker(Ref<WorkQueue>&& queue, String&& localStorageDirectory)
- : m_queue(WTFMove(queue))
- , m_localStorageDirectory(WTFMove(localStorageDirectory))
+LocalStorageDatabaseTracker::LocalStorageDatabaseTracker(String&& localStorageDirectory)
+ : m_localStorageDirectory(WTFMove(localStorageDirectory))
{
- ASSERT(RunLoop::isMain());
+ ASSERT(!RunLoop::isMain());
- // Make sure the encoding is initialized before we start dispatching things to the queue.
- UTF8Encoding();
-
- m_queue->dispatch([protectedThis = makeRef(*this)]() mutable {
- // Delete legacy storageTracker database file.
- SQLiteFileSystem::deleteDatabaseFile(protectedThis->databasePath("StorageTracker.db"));
- });
+ SQLiteFileSystem::deleteDatabaseFile(databasePath("StorageTracker.db"));
}
String LocalStorageDatabaseTracker::localStorageDirectory() const
@@ -66,7 +59,7 @@
LocalStorageDatabaseTracker::~LocalStorageDatabaseTracker()
{
- ASSERT(RunLoop::isMain());
+ ASSERT(!RunLoop::isMain());
}
String LocalStorageDatabaseTracker::databasePath(const SecurityOriginData& securityOrigin) const
diff --git a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabaseTracker.h b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabaseTracker.h
index 5d9d2c2..85b49ee 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabaseTracker.h
+++ b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabaseTracker.h
@@ -35,9 +35,9 @@
namespace WebKit {
-class LocalStorageDatabaseTracker : public ThreadSafeRefCounted<LocalStorageDatabaseTracker, WTF::DestructionThread::MainRunLoop> {
+class LocalStorageDatabaseTracker : public ThreadSafeRefCounted<LocalStorageDatabaseTracker> {
public:
- static Ref<LocalStorageDatabaseTracker> create(Ref<WorkQueue>&&, String&& localStorageDirectory);
+ static Ref<LocalStorageDatabaseTracker> create(String&& localStorageDirectory);
~LocalStorageDatabaseTracker();
String databasePath(const WebCore::SecurityOriginData&) const;
@@ -64,7 +64,7 @@
Vector<OriginDetails> originDetails();
private:
- LocalStorageDatabaseTracker(Ref<WorkQueue>&&, String&& localStorageDirectory);
+ LocalStorageDatabaseTracker(String&& localStorageDirectory);
String databasePath(const String& filename) const;
String localStorageDirectory() const;
@@ -73,8 +73,6 @@
CreateIfNonExistent,
SkipIfNonExistent
};
-
- Ref<WorkQueue> m_queue;
// It is not safe to use this member from a background thread, call localStorageDirectory() instead.
const String m_localStorageDirectory;
diff --git a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.cpp b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.cpp
index 54dc799..3aec668 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.cpp
+++ b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.cpp
@@ -47,7 +47,7 @@
ASSERT(!RunLoop::isMain());
}
-auto LocalStorageNamespace::getOrCreateStorageArea(SecurityOriginData&& securityOrigin, IsEphemeral isEphemeral) -> Ref<StorageArea>
+Ref<StorageArea> LocalStorageNamespace::getOrCreateStorageArea(SecurityOriginData&& securityOrigin, IsEphemeral isEphemeral)
{
ASSERT(!RunLoop::isMain());
return *m_storageAreaMap.ensure(securityOrigin, [&]() mutable {
@@ -81,11 +81,4 @@
return origins;
}
-void LocalStorageNamespace::cloneTo(LocalStorageNamespace& newLocalStorageNamespace)
-{
- ASSERT(!RunLoop::isMain());
- for (auto& pair : m_storageAreaMap)
- newLocalStorageNamespace.m_storageAreaMap.add(pair.key, pair.value->clone());
-}
-
} // namespace WebKit
diff --git a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.h b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.h
index 47190cc..9a76e1c 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.h
+++ b/Source/WebKit/NetworkProcess/WebStorage/LocalStorageNamespace.h
@@ -54,7 +54,6 @@
void clearAllStorageAreas();
Vector<WebCore::SecurityOriginData> ephemeralOrigins() const;
- void cloneTo(LocalStorageNamespace& newLocalStorageNamespace);
private:
LocalStorageNamespace(StorageManager&, uint64_t storageManagerID);
diff --git a/Source/WebKit/NetworkProcess/WebStorage/SessionStorageNamespace.cpp b/Source/WebKit/NetworkProcess/WebStorage/SessionStorageNamespace.cpp
index 580a8e6..ddf8212 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/SessionStorageNamespace.cpp
+++ b/Source/WebKit/NetworkProcess/WebStorage/SessionStorageNamespace.cpp
@@ -43,20 +43,7 @@
ASSERT(!RunLoop::isMain());
}
-void SessionStorageNamespace::addAllowedConnection(IPC::Connection::UniqueID allowedConnection)
-{
- ASSERT(!RunLoop::isMain());
- m_allowedConnections.add(allowedConnection);
-}
-
-
-void SessionStorageNamespace::removeAllowedConnection(IPC::Connection::UniqueID allowedConnection)
-{
- ASSERT(!RunLoop::isMain());
- ASSERT(m_allowedConnections.contains(allowedConnection));
- m_allowedConnections.remove(allowedConnection);
-}
-auto SessionStorageNamespace::getOrCreateStorageArea(SecurityOriginData&& securityOrigin) -> Ref<StorageArea>
+Ref<StorageArea> SessionStorageNamespace::getOrCreateStorageArea(SecurityOriginData&& securityOrigin)
{
ASSERT(!RunLoop::isMain());
return *m_storageAreaMap.ensure(securityOrigin, [this, &securityOrigin]() mutable {
diff --git a/Source/WebKit/NetworkProcess/WebStorage/SessionStorageNamespace.h b/Source/WebKit/NetworkProcess/WebStorage/SessionStorageNamespace.h
index 720748f..18f0f09 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/SessionStorageNamespace.h
+++ b/Source/WebKit/NetworkProcess/WebStorage/SessionStorageNamespace.h
@@ -45,10 +45,6 @@
bool isEmpty() const { return m_storageAreaMap.isEmpty(); }
- const HashSet<IPC::Connection::UniqueID>& allowedConnections() const { return m_allowedConnections; }
- void addAllowedConnection(IPC::Connection::UniqueID);
- void removeAllowedConnection(IPC::Connection::UniqueID);
-
Ref<StorageArea> getOrCreateStorageArea(WebCore::SecurityOriginData&&);
void cloneTo(SessionStorageNamespace& newSessionStorageNamespace);
@@ -61,7 +57,6 @@
private:
explicit SessionStorageNamespace(unsigned quotaInBytes);
- HashSet<IPC::Connection::UniqueID> m_allowedConnections;
unsigned m_quotaInBytes { 0 };
HashMap<WebCore::SecurityOriginData, RefPtr<StorageArea>> m_storageAreaMap;
diff --git a/Source/WebKit/NetworkProcess/WebStorage/StorageArea.cpp b/Source/WebKit/NetworkProcess/WebStorage/StorageArea.cpp
index 349431f..2d12583 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/StorageArea.cpp
+++ b/Source/WebKit/NetworkProcess/WebStorage/StorageArea.cpp
@@ -36,11 +36,18 @@
using namespace WebCore;
+static uint64_t generateStorageAreaIdentifier()
+{
+ static uint64_t identifier;
+ return ++identifier;
+}
+
StorageArea::StorageArea(LocalStorageNamespace* localStorageNamespace, const SecurityOriginData& securityOrigin, unsigned quotaInBytes)
: m_localStorageNamespace(makeWeakPtr(localStorageNamespace))
, m_securityOrigin(securityOrigin)
, m_quotaInBytes(quotaInBytes)
, m_storageMap(StorageMap::create(m_quotaInBytes))
+ , m_identifier(generateStorageAreaIdentifier())
{
ASSERT(!RunLoop::isMain());
}
@@ -48,30 +55,32 @@
StorageArea::~StorageArea()
{
ASSERT(!RunLoop::isMain());
- ASSERT(m_eventListeners.isEmpty());
if (m_localStorageDatabase)
m_localStorageDatabase->close();
}
-void StorageArea::addListener(IPC::Connection::UniqueID connectionID, uint64_t storageMapID)
+void StorageArea::addListener(IPC::Connection::UniqueID connectionID)
{
ASSERT(!RunLoop::isMain());
- ASSERT(!m_eventListeners.contains(std::make_pair(connectionID, storageMapID)));
- m_eventListeners.add(std::make_pair(connectionID, storageMapID));
+ ASSERT(!m_eventListeners.contains(connectionID));
+
+ if (m_eventListeners.isEmpty() && !isEphemeral())
+ openDatabaseAndImportItemsIfNeeded();
+
+ m_eventListeners.add(connectionID);
}
-void StorageArea::removeListener(IPC::Connection::UniqueID connectionID, uint64_t storageMapID)
+void StorageArea::removeListener(IPC::Connection::UniqueID connectionID)
{
ASSERT(!RunLoop::isMain());
- ASSERT(isEphemeral() || m_eventListeners.contains(std::make_pair(connectionID, storageMapID)));
- m_eventListeners.remove(std::make_pair(connectionID, storageMapID));
+ m_eventListeners.remove(connectionID);
}
-bool StorageArea::hasListener(IPC::Connection::UniqueID connectionID, uint64_t storageMapID) const
+bool StorageArea::hasListener(IPC::Connection::UniqueID connectionID) const
{
ASSERT(!RunLoop::isMain());
- return m_eventListeners.contains(std::make_pair(connectionID, storageMapID));
+ return m_eventListeners.contains(connectionID);
}
Ref<StorageArea> StorageArea::clone() const
@@ -105,25 +114,6 @@
dispatchEvents(sourceConnection, sourceStorageAreaID, key, oldValue, value, urlString);
}
-void StorageArea::setItems(const HashMap<String, String>& items)
-{
- ASSERT(!RunLoop::isMain());
- // Import items from web process if items are not stored on disk.
- if (!isEphemeral())
- return;
-
- for (auto& item : items) {
- String oldValue;
- bool quotaException;
- auto newStorageMap = m_storageMap->setItem(item.key, item.value, oldValue, quotaException);
- if (newStorageMap)
- m_storageMap = WTFMove(newStorageMap);
-
- if (quotaException)
- return;
- }
-}
-
void StorageArea::removeItem(IPC::Connection::UniqueID sourceConnection, uint64_t sourceStorageAreaID, const String& key, const String& urlString)
{
ASSERT(!RunLoop::isMain());
@@ -178,7 +168,7 @@
}
for (auto it = m_eventListeners.begin(), end = m_eventListeners.end(); it != end; ++it) {
- RunLoop::main().dispatch([connectionID = it->first, destinationStorageAreaID = it->second] {
+ RunLoop::main().dispatch([connectionID = *it, destinationStorageAreaID = m_identifier] {
if (auto* connection = IPC::Connection::connection(connectionID))
connection->send(Messages::StorageAreaMap::ClearCache(), destinationStorageAreaID);
});
@@ -192,9 +182,10 @@
return;
ASSERT(m_localStorageNamespace->storageManager()->localStorageDatabaseTracker());
+ ASSERT(m_queue);
// We open the database here even if we've already imported our items to ensure that the database is open if we need to write to it.
if (!m_localStorageDatabase)
- m_localStorageDatabase = LocalStorageDatabase::create(m_localStorageNamespace->storageManager()->workQueue(), *m_localStorageNamespace->storageManager()->localStorageDatabaseTracker(), m_securityOrigin);
+ m_localStorageDatabase = LocalStorageDatabase::create(*m_queue, *m_localStorageNamespace->storageManager()->localStorageDatabaseTracker(), m_securityOrigin);
if (m_didImportItemsFromDatabase)
return;
@@ -207,13 +198,21 @@
{
ASSERT(!RunLoop::isMain());
for (auto it = m_eventListeners.begin(), end = m_eventListeners.end(); it != end; ++it) {
- sourceStorageAreaID = it->first == sourceConnection ? sourceStorageAreaID : 0;
+ sourceStorageAreaID = *it == sourceConnection ? sourceStorageAreaID : 0;
- RunLoop::main().dispatch([connectionID = it->first, sourceStorageAreaID, destinationStorageAreaID = it->second, key = key.isolatedCopy(), oldValue = oldValue.isolatedCopy(), newValue = newValue.isolatedCopy(), urlString = urlString.isolatedCopy()] {
+ RunLoop::main().dispatch([connectionID = *it, sourceStorageAreaID, destinationStorageAreaID = m_identifier, key = key.isolatedCopy(), oldValue = oldValue.isolatedCopy(), newValue = newValue.isolatedCopy(), urlString = urlString.isolatedCopy()] {
if (auto* connection = IPC::Connection::connection(connectionID))
connection->send(Messages::StorageAreaMap::DispatchStorageEvent(sourceStorageAreaID, key, oldValue, newValue, urlString), destinationStorageAreaID);
});
}
}
+void StorageArea::syncToDatabase()
+{
+ if (!m_localStorageDatabase)
+ return;
+
+ m_localStorageDatabase->updateDatabase();
+}
+
} // namespace WebKit
diff --git a/Source/WebKit/NetworkProcess/WebStorage/StorageArea.h b/Source/WebKit/NetworkProcess/WebStorage/StorageArea.h
index 0001075..4d33c4a 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/StorageArea.h
+++ b/Source/WebKit/NetworkProcess/WebStorage/StorageArea.h
@@ -49,15 +49,15 @@
~StorageArea();
const WebCore::SecurityOriginData& securityOrigin() const { return m_securityOrigin; }
+ uint64_t identifier() { return m_identifier; }
- void addListener(IPC::Connection::UniqueID, uint64_t storageMapID);
- void removeListener(IPC::Connection::UniqueID, uint64_t storageMapID);
- bool hasListener(IPC::Connection::UniqueID, uint64_t storageMapID) const;
+ void addListener(IPC::Connection::UniqueID);
+ void removeListener(IPC::Connection::UniqueID);
+ bool hasListener(IPC::Connection::UniqueID connectionID) const;
Ref<StorageArea> clone() const;
void setItem(IPC::Connection::UniqueID sourceConnection, uint64_t sourceStorageAreaID, const String& key, const String& value, const String& urlString, bool& quotaException);
- void setItems(const HashMap<String, String>&);
void removeItem(IPC::Connection::UniqueID sourceConnection, uint64_t sourceStorageAreaID, const String& key, const String& urlString);
void clear(IPC::Connection::UniqueID sourceConnection, uint64_t sourceStorageAreaID, const String& urlString);
@@ -68,6 +68,10 @@
void openDatabaseAndImportItemsIfNeeded() const;
+ void setWorkQueue(RefPtr<WorkQueue>&& queue) { m_queue = WTFMove(queue); }
+
+ void syncToDatabase();
+
private:
StorageArea(LocalStorageNamespace*, const WebCore::SecurityOriginData&, unsigned quotaInBytes);
@@ -82,7 +86,10 @@
unsigned m_quotaInBytes { 0 };
RefPtr<WebCore::StorageMap> m_storageMap;
- HashSet<std::pair<IPC::Connection::UniqueID, uint64_t>> m_eventListeners;
+ HashSet<IPC::Connection::UniqueID> m_eventListeners;
+
+ uint64_t m_identifier;
+ RefPtr<WorkQueue> m_queue;
};
} // namespace WebKit
diff --git a/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp b/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp
index 3e3e0b4..64db494 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp
+++ b/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp
@@ -32,7 +32,6 @@
#include "SessionStorageNamespace.h"
#include "StorageArea.h"
#include "StorageAreaMapMessages.h"
-#include "StorageManagerMessages.h"
#include "TransientLocalStorageNamespace.h"
#include "WebProcessProxy.h"
#include <WebCore/SecurityOriginData.h>
@@ -41,7 +40,6 @@
#include <WebCore/TextEncoding.h>
#include <memory>
#include <wtf/WorkQueue.h>
-#include <wtf/threads/BinarySemaphore.h>
namespace WebKit {
using namespace WebCore;
@@ -50,523 +48,202 @@
const unsigned StorageManager::localStorageDatabaseQuotaInBytes = 5 * 1024 * 1024;
StorageManager::StorageManager(String&& localStorageDirectory)
- : m_queue(WorkQueue::create("com.apple.WebKit.StorageManager"))
{
- ASSERT(RunLoop::isMain());
+ ASSERT(!RunLoop::isMain());
- // Make sure the encoding is initialized before we start dispatching things to the queue.
- UTF8Encoding();
if (!localStorageDirectory.isNull())
- m_localStorageDatabaseTracker = LocalStorageDatabaseTracker::create(m_queue.copyRef(), WTFMove(localStorageDirectory));
+ m_localStorageDatabaseTracker = LocalStorageDatabaseTracker::create(WTFMove(localStorageDirectory));
}
StorageManager::~StorageManager()
{
- ASSERT(RunLoop::isMain());
+ ASSERT(!RunLoop::isMain());
}
void StorageManager::createSessionStorageNamespace(uint64_t storageNamespaceID, unsigned quotaInBytes)
{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), storageNamespaceID, quotaInBytes]() mutable {
- m_sessionStorageNamespaces.ensure(storageNamespaceID, [quotaInBytes] {
- return SessionStorageNamespace::create(quotaInBytes);
- });
+ ASSERT(!RunLoop::isMain());
+
+ m_sessionStorageNamespaces.ensure(storageNamespaceID, [quotaInBytes] {
+ return SessionStorageNamespace::create(quotaInBytes);
});
}
void StorageManager::destroySessionStorageNamespace(uint64_t storageNamespaceID)
{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), storageNamespaceID] {
- ASSERT(m_sessionStorageNamespaces.contains(storageNamespaceID));
- if (auto* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID)) {
- if (sessionStorageNamespace->allowedConnections().isEmpty())
- m_sessionStorageNamespaces.remove(storageNamespaceID);
- }
- });
-}
+ ASSERT(!RunLoop::isMain());
-void StorageManager::addAllowedSessionStorageNamespaceConnection(uint64_t storageNamespaceID, IPC::Connection& allowedConnection)
-{
- ASSERT(RunLoop::isMain());
- auto allowedConnectionID = allowedConnection.uniqueID();
- auto addResult = m_connections.add(allowedConnectionID);
- if (addResult.isNewEntry)
- allowedConnection.addWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName(), m_queue.get(), this);
-
- m_queue->dispatch([this, protectedThis = makeRef(*this), allowedConnectionID, storageNamespaceID]() mutable {
- ASSERT(m_sessionStorageNamespaces.contains(storageNamespaceID));
-
- m_sessionStorageNamespaces.get(storageNamespaceID)->addAllowedConnection(allowedConnectionID);
- });
-}
-
-void StorageManager::removeAllowedSessionStorageNamespaceConnection(uint64_t storageNamespaceID, IPC::Connection& allowedConnection)
-{
- ASSERT(RunLoop::isMain());
- auto allowedConnectionID = allowedConnection.uniqueID();
- m_queue->dispatch([this, protectedThis = makeRef(*this), allowedConnectionID, storageNamespaceID]() mutable {
- ASSERT(m_sessionStorageNamespaces.contains(storageNamespaceID));
- if (auto* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID))
- sessionStorageNamespace->removeAllowedConnection(allowedConnectionID);
- });
+ ASSERT(m_sessionStorageNamespaces.contains(storageNamespaceID));
+ if (auto* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID))
+ m_sessionStorageNamespaces.remove(storageNamespaceID);
}
void StorageManager::cloneSessionStorageNamespace(uint64_t storageNamespaceID, uint64_t newStorageNamespaceID)
{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), storageNamespaceID, newStorageNamespaceID] {
- SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID);
- if (!sessionStorageNamespace) {
- // FIXME: We can get into this situation if someone closes the originating page from within a
- // createNewPage callback. We bail for now, but we should really find a way to keep the session storage alive
- // so we we'll clone the session storage correctly.
- return;
- }
+ ASSERT(!RunLoop::isMain());
- SessionStorageNamespace* newSessionStorageNamespace = m_sessionStorageNamespaces.get(newStorageNamespaceID);
- ASSERT(newSessionStorageNamespace);
+ SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID);
+ if (!sessionStorageNamespace)
+ return;
- sessionStorageNamespace->cloneTo(*newSessionStorageNamespace);
+ SessionStorageNamespace* newSessionStorageNamespace = getOrCreateSessionStorageNamespace(newStorageNamespaceID);
+ ASSERT(newSessionStorageNamespace);
- if (!m_localStorageDatabaseTracker) {
- if (auto* localStorageNamespace = m_localStorageNamespaces.get(storageNamespaceID)) {
- LocalStorageNamespace* newlocalStorageNamespace = getOrCreateLocalStorageNamespace(newStorageNamespaceID);
- localStorageNamespace->cloneTo(*newlocalStorageNamespace);
- }
- }
- });
-}
-
-void StorageManager::processDidCloseConnection(IPC::Connection& connection)
-{
- ASSERT(RunLoop::isMain());
- if (m_connections.remove(connection.uniqueID()))
- connection.removeWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName());
-
- m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID()]() mutable {
- Vector<std::pair<IPC::Connection::UniqueID, uint64_t>> connectionAndStorageMapIDPairsToRemove;
- for (auto& storageArea : m_storageAreasByConnection) {
- if (storageArea.key.first != connectionID)
- continue;
-
- storageArea.value->removeListener(storageArea.key.first, storageArea.key.second);
- connectionAndStorageMapIDPairsToRemove.append(storageArea.key);
- }
-
- for (auto& pair : connectionAndStorageMapIDPairsToRemove)
- m_storageAreasByConnection.remove(pair);
-
- Vector<uint64_t> sessionStorageNameSpaceIDsToRemove;
- for (auto& sessionStorageNamespace : m_sessionStorageNamespaces) {
- if (sessionStorageNamespace.value->allowedConnections().contains(connectionID))
- sessionStorageNamespace.value->removeAllowedConnection(connectionID);
-
- if (sessionStorageNamespace.value->allowedConnections().isEmpty())
- sessionStorageNameSpaceIDsToRemove.append(sessionStorageNamespace.key);
- }
-
- for (auto id : sessionStorageNameSpaceIDsToRemove)
- m_sessionStorageNamespaces.remove(id);
- });
+ sessionStorageNamespace->cloneTo(*newSessionStorageNamespace);
}
void StorageManager::getSessionStorageOrigins(Function<void(HashSet<WebCore::SecurityOriginData>&&)>&& completionHandler)
{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
- HashSet<SecurityOriginData> origins;
+ ASSERT(!RunLoop::isMain());
- for (const auto& sessionStorageNamespace : m_sessionStorageNamespaces.values()) {
- for (auto& origin : sessionStorageNamespace->origins())
- origins.add(crossThreadCopy(origin));
- }
+ HashSet<SecurityOriginData> origins;
+ for (const auto& sessionStorageNamespace : m_sessionStorageNamespaces.values()) {
+ for (auto& origin : sessionStorageNamespace->origins())
+ origins.add(crossThreadCopy(origin));
+ }
- RunLoop::main().dispatch([origins = WTFMove(origins), completionHandler = WTFMove(completionHandler)]() mutable {
- completionHandler(WTFMove(origins));
- });
+ RunLoop::main().dispatch([origins = WTFMove(origins), completionHandler = WTFMove(completionHandler)]() mutable {
+ completionHandler(WTFMove(origins));
});
}
void StorageManager::deleteSessionStorageOrigins(Function<void()>&& completionHandler)
{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
- for (auto& sessionStorageNamespace : m_sessionStorageNamespaces.values())
- sessionStorageNamespace->clearAllStorageAreas();
+ ASSERT(!RunLoop::isMain());
- RunLoop::main().dispatch(WTFMove(completionHandler));
- });
+ for (auto& sessionStorageNamespace : m_sessionStorageNamespaces.values())
+ sessionStorageNamespace->clearAllStorageAreas();
+
+ RunLoop::main().dispatch(WTFMove(completionHandler));
}
void StorageManager::deleteSessionStorageEntriesForOrigins(const Vector<WebCore::SecurityOriginData>& origins, Function<void()>&& completionHandler)
{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), copiedOrigins = crossThreadCopy(origins), completionHandler = WTFMove(completionHandler)]() mutable {
- for (auto& origin : copiedOrigins) {
- for (auto& sessionStorageNamespace : m_sessionStorageNamespaces.values())
- sessionStorageNamespace->clearStorageAreasMatchingOrigin(origin);
- }
+ ASSERT(!RunLoop::isMain());
- RunLoop::main().dispatch(WTFMove(completionHandler));
- });
+ for (auto& origin : origins) {
+ for (auto& sessionStorageNamespace : m_sessionStorageNamespaces.values())
+ sessionStorageNamespace->clearStorageAreasMatchingOrigin(origin);
+ }
+
+ RunLoop::main().dispatch(WTFMove(completionHandler));
}
void StorageManager::getLocalStorageOrigins(Function<void(HashSet<WebCore::SecurityOriginData>&&)>&& completionHandler)
{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
- HashSet<SecurityOriginData> origins;
+ ASSERT(!RunLoop::isMain());
- if (m_localStorageDatabaseTracker) {
- for (auto& origin : m_localStorageDatabaseTracker->origins())
- origins.add(origin.isolatedCopy());
- } else {
- for (const auto& localStorageNameSpace : m_localStorageNamespaces.values()) {
- for (auto& origin : localStorageNameSpace->ephemeralOrigins())
- origins.add(origin.isolatedCopy());
- }
- }
-
- for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values()) {
- for (auto& origin : transientLocalStorageNamespace->origins())
+ HashSet<SecurityOriginData> origins;
+ if (m_localStorageDatabaseTracker) {
+ for (auto& origin : m_localStorageDatabaseTracker->origins())
+ origins.add(origin.isolatedCopy());
+ } else {
+ for (const auto& localStorageNameSpace : m_localStorageNamespaces.values()) {
+ for (auto& origin : localStorageNameSpace->ephemeralOrigins())
origins.add(origin.isolatedCopy());
}
+ }
- RunLoop::main().dispatch([origins = WTFMove(origins), completionHandler = WTFMove(completionHandler)]() mutable {
- completionHandler(WTFMove(origins));
- });
+ for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values()) {
+ for (auto& origin : transientLocalStorageNamespace->origins())
+ origins.add(origin.isolatedCopy());
+ }
+
+ RunLoop::main().dispatch([origins = WTFMove(origins), completionHandler = WTFMove(completionHandler)]() mutable {
+ completionHandler(WTFMove(origins));
});
}
void StorageManager::getLocalStorageOriginDetails(Function<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&& completionHandler)
{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
- Vector<LocalStorageDatabaseTracker::OriginDetails> originDetails;
- if (m_localStorageDatabaseTracker)
- originDetails = m_localStorageDatabaseTracker->originDetails().isolatedCopy();
+ ASSERT(!RunLoop::isMain());
- RunLoop::main().dispatch([originDetails = WTFMove(originDetails), completionHandler = WTFMove(completionHandler)]() mutable {
- completionHandler(WTFMove(originDetails));
- });
- });
-}
+ Vector<LocalStorageDatabaseTracker::OriginDetails> originDetails;
+ if (m_localStorageDatabaseTracker)
+ originDetails = crossThreadCopy(m_localStorageDatabaseTracker->originDetails());
-void StorageManager::deleteLocalStorageEntriesForOrigin(const SecurityOriginData& securityOrigin)
-{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), copiedOrigin = securityOrigin.isolatedCopy()]() mutable {
- for (auto& localStorageNamespace : m_localStorageNamespaces.values())
- localStorageNamespace->clearStorageAreasMatchingOrigin(copiedOrigin);
-
- for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values())
- transientLocalStorageNamespace->clearStorageAreasMatchingOrigin(copiedOrigin);
-
- if (m_localStorageDatabaseTracker)
- m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(copiedOrigin);
+ RunLoop::main().dispatch([originDetails = WTFMove(originDetails), completionHandler = WTFMove(completionHandler)]() mutable {
+ completionHandler(WTFMove(originDetails));
});
}
void StorageManager::deleteLocalStorageOriginsModifiedSince(WallTime time, Function<void()>&& completionHandler)
{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), time, completionHandler = WTFMove(completionHandler)]() mutable {
- if (m_localStorageDatabaseTracker) {
- auto originsToDelete = m_localStorageDatabaseTracker->databasesModifiedSince(time);
-
- for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values())
- transientLocalStorageNamespace->clearAllStorageAreas();
+ ASSERT(!RunLoop::isMain());
- for (const auto& origin : originsToDelete) {
- for (auto& localStorageNamespace : m_localStorageNamespaces.values())
- localStorageNamespace->clearStorageAreasMatchingOrigin(origin);
-
- m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(origin);
- }
- } else {
+ if (m_localStorageDatabaseTracker) {
+ auto originsToDelete = m_localStorageDatabaseTracker->databasesModifiedSince(time);
+
+ for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values())
+ transientLocalStorageNamespace->clearAllStorageAreas();
+
+ for (const auto& origin : originsToDelete) {
for (auto& localStorageNamespace : m_localStorageNamespaces.values())
- localStorageNamespace->clearAllStorageAreas();
+ localStorageNamespace->clearStorageAreasMatchingOrigin(origin);
+ m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(origin);
}
+ } else {
+ for (auto& localStorageNamespace : m_localStorageNamespaces.values())
+ localStorageNamespace->clearAllStorageAreas();
+ }
- RunLoop::main().dispatch(WTFMove(completionHandler));
- });
+ RunLoop::main().dispatch(WTFMove(completionHandler));
}
void StorageManager::deleteLocalStorageEntriesForOrigins(const Vector<WebCore::SecurityOriginData>& origins, Function<void()>&& completionHandler)
{
- ASSERT(RunLoop::isMain());
- m_queue->dispatch([this, protectedThis = makeRef(*this), copiedOrigins = crossThreadCopy(origins), completionHandler = WTFMove(completionHandler)]() mutable {
- for (auto& origin : copiedOrigins) {
- for (auto& localStorageNamespace : m_localStorageNamespaces.values())
- localStorageNamespace->clearStorageAreasMatchingOrigin(origin);
-
- for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values())
- transientLocalStorageNamespace->clearStorageAreasMatchingOrigin(origin);
-
- if (m_localStorageDatabaseTracker)
- m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(origin);
- }
-
- RunLoop::main().dispatch(WTFMove(completionHandler));
- });
-}
-
-void StorageManager::createLocalStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& securityOriginData)
-{
ASSERT(!RunLoop::isMain());
- auto connectionID = connection.uniqueID();
- std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connectionID, storageMapID);
- ASSERT((HashMap<std::pair<IPC::Connection::UniqueID, uint64_t>, RefPtr<StorageArea>>::isValidKey(connectionAndStorageMapIDPair)));
+ for (auto& origin : origins) {
+ for (auto& localStorageNamespace : m_localStorageNamespaces.values())
+ localStorageNamespace->clearStorageAreasMatchingOrigin(origin);
- auto result = m_storageAreasByConnection.add(connectionAndStorageMapIDPair, nullptr);
- ASSERT(result.isNewEntry);
- ASSERT((HashMap<uint64_t, RefPtr<LocalStorageNamespace>>::isValidKey(storageNamespaceID)));
+ for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values())
+ transientLocalStorageNamespace->clearStorageAreasMatchingOrigin(origin);
- LocalStorageNamespace* localStorageNamespace = getOrCreateLocalStorageNamespace(storageNamespaceID);
- ASSERT(localStorageNamespace);
-
- auto storageArea = localStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData), m_localStorageDatabaseTracker ? LocalStorageNamespace::IsEphemeral::No : LocalStorageNamespace::IsEphemeral::Yes);
- storageArea->addListener(connectionID, storageMapID);
-
- result.iterator->value = WTFMove(storageArea);
-}
-
-void StorageManager::createTransientLocalStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& topLevelOriginData, SecurityOriginData&& origin)
-{
- ASSERT(!RunLoop::isMain());
- auto connectionID = connection.uniqueID();
-
- ASSERT(m_storageAreasByConnection.isValidKey({ connectionID, storageMapID }));
-
- // See if we already have session storage for this connection/origin combo.
- // If so, update the map with the new ID, otherwise keep on trucking.
- for (auto it = m_storageAreasByConnection.begin(), end = m_storageAreasByConnection.end(); it != end; ++it) {
- if (it->key.first != connectionID)
- continue;
- Ref<StorageArea> area = *it->value;
- if (!area->isEphemeral())
- continue;
- if (!origin.securityOrigin()->isSameSchemeHostPort(area->securityOrigin().securityOrigin().get()))
- continue;
- area->addListener(connectionID, storageMapID);
- // If the storageMapID used as key in m_storageAreasByConnection is no longer one of the StorageArea's listeners, then this means
- // that destroyStorageMap() was already called for that storageMapID but it decided not to remove it from m_storageAreasByConnection
- // so that we could reuse it later on for the same connection/origin combo. In this case, it is safe to remove the previous
- // storageMapID from m_storageAreasByConnection.
- if (!area->hasListener(connectionID, it->key.second))
- m_storageAreasByConnection.remove(it);
- m_storageAreasByConnection.add({ connectionID, storageMapID }, WTFMove(area));
- return;
+ if (m_localStorageDatabaseTracker)
+ m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(origin);
}
- auto& slot = m_storageAreasByConnection.add({ connectionID, storageMapID }, nullptr).iterator->value;
- ASSERT(!slot);
-
- auto* transientLocalStorageNamespace = getOrCreateTransientLocalStorageNamespace(storageNamespaceID, WTFMove(topLevelOriginData));
-
- auto storageArea = transientLocalStorageNamespace->getOrCreateStorageArea(WTFMove(origin));
- storageArea->addListener(connectionID, storageMapID);
-
- slot = WTFMove(storageArea);
+ RunLoop::main().dispatch(WTFMove(completionHandler));
}
-void StorageManager::createSessionStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& securityOriginData)
+StorageArea* StorageManager::createLocalStorageArea(uint64_t storageNamespaceID, WebCore::SecurityOriginData&& origin)
{
ASSERT(!RunLoop::isMain());
- auto connectionID = connection.uniqueID();
- ASSERT(m_sessionStorageNamespaces.isValidKey(storageNamespaceID));
- SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID);
- if (!sessionStorageNamespace) {
- // We're getting an incoming message from the web process that's for session storage for a web page
- // that has already been closed, just ignore it.
- return;
- }
+ if (auto* localStorageNamespace = getOrCreateLocalStorageNamespace(storageNamespaceID))
+ return localStorageNamespace->getOrCreateStorageArea(WTFMove(origin), m_localStorageDatabaseTracker ? LocalStorageNamespace::IsEphemeral::No : LocalStorageNamespace::IsEphemeral::Yes).ptr();
- ASSERT(m_storageAreasByConnection.isValidKey({ connectionID, storageMapID }));
-
- auto& slot = m_storageAreasByConnection.add({ connectionID, storageMapID }, nullptr).iterator->value;
- ASSERT(!slot);
- ASSERT(sessionStorageNamespace->allowedConnections().contains(connectionID));
-
- auto storageArea = sessionStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData));
- storageArea->addListener(connectionID, storageMapID);
-
- slot = WTFMove(storageArea);
+ return nullptr;
}
-void StorageManager::destroyStorageMap(IPC::Connection& connection, uint64_t storageMapID)
+StorageArea* StorageManager::createTransientLocalStorageArea(uint64_t storageNamespaceID, WebCore::SecurityOriginData&& topLevelOrigin, WebCore::SecurityOriginData&& origin)
{
ASSERT(!RunLoop::isMain());
- auto connectionID = connection.uniqueID();
+ ASSERT((HashMap<uint64_t, RefPtr<TransientLocalStorageNamespace>>::isValidKey(storageNamespaceID)));
- std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connectionID, storageMapID);
- ASSERT(m_storageAreasByConnection.isValidKey(connectionAndStorageMapIDPair));
-
- auto it = m_storageAreasByConnection.find(connectionAndStorageMapIDPair);
- if (it == m_storageAreasByConnection.end()) {
- // The connection has been removed because the last page was closed.
- return;
- }
-
- it->value->removeListener(connectionID, storageMapID);
-
- // Don't remove session storage maps. The web process may reconnect and expect the data to still be around.
- if (it->value->isEphemeral())
- return;
-
- m_storageAreasByConnection.remove(connectionAndStorageMapIDPair);
+ if (auto* transientLocalStorageNamespace = getOrCreateTransientLocalStorageNamespace(storageNamespaceID, WTFMove(topLevelOrigin)))
+ return transientLocalStorageNamespace->getOrCreateStorageArea(WTFMove(origin)).ptr();
+
+ return nullptr;
}
-void StorageManager::prewarm(IPC::Connection& connection, uint64_t storageMapID)
+StorageArea* StorageManager::createSessionStorageArea(uint64_t storageNamespaceID, WebCore::SecurityOriginData&& origin)
{
ASSERT(!RunLoop::isMain());
- if (auto* storageArea = findStorageArea(connection, storageMapID))
- storageArea->openDatabaseAndImportItemsIfNeeded();
-}
+ ASSERT((HashMap<uint64_t, RefPtr<SessionStorageNamespace>>::isValidKey(storageNamespaceID)));
-void StorageManager::getValues(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageMapSeed, GetValuesCallback&& completionHandler)
-{
- ASSERT(!RunLoop::isMain());
- auto* storageArea = findStorageArea(connection, storageMapID);
-
- // This is a session storage area for a page that has already been closed. Ignore it.
- if (!storageArea)
- return completionHandler({ });
-
- completionHandler(storageArea->items());
- connection.send(Messages::StorageAreaMap::DidGetValues(storageMapSeed), storageMapID);
-}
-
-void StorageManager::setItem(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString)
-{
- ASSERT(!RunLoop::isMain());
- auto* storageArea = findStorageArea(connection, storageMapID);
-
- // This is a session storage area for a page that has already been closed. Ignore it.
- if (!storageArea)
- return;
-
- bool quotaError;
- storageArea->setItem(connection.uniqueID(), sourceStorageAreaID, key, value, urlString, quotaError);
- connection.send(Messages::StorageAreaMap::DidSetItem(storageMapSeed, key, quotaError), storageMapID);
-}
-
-void StorageManager::setItems(IPC::Connection& connection, uint64_t storageMapID, const HashMap<String, String>& items)
-{
- ASSERT(!RunLoop::isMain());
- if (auto* storageArea = findStorageArea(connection, storageMapID))
- storageArea->setItems(items);
-}
-
-void StorageManager::removeItem(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& urlString)
-{
- ASSERT(!RunLoop::isMain());
- auto* storageArea = findStorageArea(connection, storageMapID);
-
- // This is a session storage area for a page that has already been closed. Ignore it.
- if (!storageArea)
- return;
-
- storageArea->removeItem(connection.uniqueID(), sourceStorageAreaID, key, urlString);
- connection.send(Messages::StorageAreaMap::DidRemoveItem(storageMapSeed, key), storageMapID);
-}
-
-void StorageManager::clear(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& urlString)
-{
- ASSERT(!RunLoop::isMain());
- auto* storageArea = findStorageArea(connection, storageMapID);
-
- // This is a session storage area for a page that has already been closed. Ignore it.
- if (!storageArea)
- return;
-
- storageArea->clear(connection.uniqueID(), sourceStorageAreaID, urlString);
- connection.send(Messages::StorageAreaMap::DidClear(storageMapSeed), storageMapID);
-}
-
-void StorageManager::waitUntilTasksFinished()
-{
- ASSERT(RunLoop::isMain());
- BinarySemaphore semaphore;
- m_queue->dispatch([this, &semaphore] {
- Vector<std::pair<IPC::Connection::UniqueID, uint64_t>> connectionAndStorageMapIDPairsToRemove;
- for (auto& connectionStorageAreaPair : m_storageAreasByConnection) {
- connectionStorageAreaPair.value->removeListener(connectionStorageAreaPair.key.first, connectionStorageAreaPair.key.second);
- connectionAndStorageMapIDPairsToRemove.append(connectionStorageAreaPair.key);
- }
-
- for (auto& connectionStorageAreaPair : connectionAndStorageMapIDPairsToRemove)
- m_storageAreasByConnection.remove(connectionStorageAreaPair);
-
- m_sessionStorageNamespaces.clear();
- m_localStorageNamespaces.clear();
-
- semaphore.signal();
- });
- semaphore.wait();
-}
-
-void StorageManager::suspend(CompletionHandler<void()>&& completionHandler)
-{
- ASSERT(RunLoop::isMain());
- CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
- if (!m_localStorageDatabaseTracker)
- return;
-
- Locker<Lock> stateLocker(m_stateLock);
- if (m_state != State::Running)
- return;
- m_state = State::WillSuspend;
-
- m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = completionHandlerCaller.release()] () mutable {
- Locker<Lock> stateLocker(m_stateLock);
- ASSERT(m_state != State::Suspended);
-
- if (m_state != State::WillSuspend) {
- RunLoop::main().dispatch(WTFMove(completionHandler));
- return;
- }
-
- m_state = State::Suspended;
- RunLoop::main().dispatch(WTFMove(completionHandler));
-
- while (m_state == State::Suspended)
- m_stateChangeCondition.wait(m_stateLock);
- ASSERT(m_state == State::Running);
- });
-}
-
-void StorageManager::resume()
-{
- ASSERT(RunLoop::isMain());
- if (!m_localStorageDatabaseTracker)
- return;
-
- Locker<Lock> stateLocker(m_stateLock);
- auto previousState = m_state;
- m_state = State::Running;
- if (previousState == State::Suspended)
- m_stateChangeCondition.notifyOne();
-}
-
-StorageArea* StorageManager::findStorageArea(IPC::Connection& connection, uint64_t storageMapID) const
-{
- ASSERT(!RunLoop::isMain());
- std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connection.uniqueID(), storageMapID);
-
- if (!m_storageAreasByConnection.isValidKey(connectionAndStorageMapIDPair))
- return nullptr;
-
- return m_storageAreasByConnection.get(connectionAndStorageMapIDPair);
+ if (auto* sessionStorageNamespace = getOrCreateSessionStorageNamespace(storageNamespaceID))
+ return sessionStorageNamespace->getOrCreateStorageArea(WTFMove(origin)).ptr();
+
+ return nullptr;
}
LocalStorageNamespace* StorageManager::getOrCreateLocalStorageNamespace(uint64_t storageNamespaceID)
{
ASSERT(!RunLoop::isMain());
+
if (!m_localStorageNamespaces.isValidKey(storageNamespaceID))
return nullptr;
@@ -578,12 +255,35 @@
TransientLocalStorageNamespace* StorageManager::getOrCreateTransientLocalStorageNamespace(uint64_t storageNamespaceID, WebCore::SecurityOriginData&& topLevelOrigin)
{
ASSERT(!RunLoop::isMain());
+
if (!m_transientLocalStorageNamespaces.isValidKey({ storageNamespaceID, topLevelOrigin }))
return nullptr;
- return m_transientLocalStorageNamespaces.ensure({ storageNamespaceID, WTFMove(topLevelOrigin) }, [](){
+ return m_transientLocalStorageNamespaces.ensure({ storageNamespaceID, WTFMove(topLevelOrigin) }, [] {
return TransientLocalStorageNamespace::create();
}).iterator->value.get();
}
+SessionStorageNamespace* StorageManager::getOrCreateSessionStorageNamespace(uint64_t storageNamespaceID)
+{
+ ASSERT(!RunLoop::isMain());
+
+ if (!m_sessionStorageNamespaces.isValidKey(storageNamespaceID))
+ return nullptr;
+
+ return m_sessionStorageNamespaces.ensure(storageNamespaceID, [] {
+ // We currently have no limit on session storage.
+ return SessionStorageNamespace::create(std::numeric_limits<unsigned>::max());
+ }).iterator->value.get();
+}
+
+void StorageManager::clearStorageNamespaces()
+{
+ ASSERT(!RunLoop::isMain());
+
+ m_localStorageNamespaces.clear();
+ m_transientLocalStorageNamespaces.clear();
+ m_sessionStorageNamespaces.clear();
+}
+
} // namespace WebKit
diff --git a/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h b/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h
index 3199a42..6b53e1b 100644
--- a/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h
+++ b/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h
@@ -49,7 +49,7 @@
using GetValuesCallback = CompletionHandler<void(const HashMap<String, String>&)>;
-class StorageManager : public IPC::Connection::WorkQueueMessageReceiver {
+class StorageManager : public RefCounted<StorageManager> {
public:
static Ref<StorageManager> create(String&& localStorageDirectory)
{
@@ -60,78 +60,41 @@
void createSessionStorageNamespace(uint64_t storageNamespaceID, unsigned quotaInBytes);
void destroySessionStorageNamespace(uint64_t storageNamespaceID);
- void addAllowedSessionStorageNamespaceConnection(uint64_t storageNamespaceID, IPC::Connection&);
- void removeAllowedSessionStorageNamespaceConnection(uint64_t storageNamespaceID, IPC::Connection&);
void cloneSessionStorageNamespace(uint64_t storageNamespaceID, uint64_t newStorageNamespaceID);
- void processDidCloseConnection(IPC::Connection&);
- void waitUntilTasksFinished();
- void suspend(CompletionHandler<void()>&&);
- void resume();
-
- void getSessionStorageOrigins(Function<void(HashSet<WebCore::SecurityOriginData>&&)>&& completionHandler);
+ void getSessionStorageOrigins(Function<void(HashSet<WebCore::SecurityOriginData>&&)>&&);
void deleteSessionStorageOrigins(Function<void()>&& completionHandler);
- void deleteSessionStorageEntriesForOrigins(const Vector<WebCore::SecurityOriginData>&, Function<void()>&& completionHandler);
+ void deleteSessionStorageEntriesForOrigins(const Vector<WebCore::SecurityOriginData>&, Function<void()>&&);
- void getLocalStorageOrigins(Function<void(HashSet<WebCore::SecurityOriginData>&&)>&& completionHandler);
- void deleteLocalStorageEntriesForOrigin(const WebCore::SecurityOriginData&);
+ void getLocalStorageOrigins(Function<void(HashSet<WebCore::SecurityOriginData>&&)>&&);
+ void deleteLocalStorageOriginsModifiedSince(WallTime, Function<void()>&&);
+ void deleteLocalStorageEntriesForOrigins(const Vector<WebCore::SecurityOriginData>&, Function<void()>&&);
+ void getLocalStorageOriginDetails(Function<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&&);
- void deleteLocalStorageOriginsModifiedSince(WallTime, Function<void()>&& completionHandler);
- void deleteLocalStorageEntriesForOrigins(const Vector<WebCore::SecurityOriginData>&, Function<void()>&& completionHandler);
-
- void getLocalStorageOriginDetails(Function<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&& completionHandler);
+ void clearStorageNamespaces();
void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>& replyEncoder);
LocalStorageDatabaseTracker* localStorageDatabaseTracker() const { return m_localStorageDatabaseTracker.get(); }
- WorkQueue& workQueue() const { return m_queue.get(); }
-
static const unsigned localStorageDatabaseQuotaInBytes;
+ StorageArea* createLocalStorageArea(uint64_t storageNamespaceID, WebCore::SecurityOriginData&&);
+ StorageArea* createTransientLocalStorageArea(uint64_t storageNamespaceID, WebCore::SecurityOriginData&&, WebCore::SecurityOriginData&&);
+ StorageArea* createSessionStorageArea(uint64_t storageNamespaceID, WebCore::SecurityOriginData&&);
+
private:
explicit StorageManager(String&& localStorageDirectory);
- // Message handlers.
- void createLocalStorageMap(IPC::Connection&, uint64_t storageMapID, uint64_t storageNamespaceID, WebCore::SecurityOriginData&&);
- void createTransientLocalStorageMap(IPC::Connection&, uint64_t storageMapID, uint64_t storageNamespaceID, WebCore::SecurityOriginData&& topLevelOriginData, WebCore::SecurityOriginData&&);
- void createSessionStorageMap(IPC::Connection&, uint64_t storageMapID, uint64_t storageNamespaceID, WebCore::SecurityOriginData&&);
- void destroyStorageMap(IPC::Connection&, uint64_t storageMapID);
-
- void getValues(IPC::Connection&, uint64_t storageMapID, uint64_t storageMapSeed, GetValuesCallback&&);
- void prewarm(IPC::Connection&, uint64_t storageMapID);
- void setItem(IPC::Connection&, WebCore::SecurityOriginData&&, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString);
- void setItems(IPC::Connection&, uint64_t storageMapID, const HashMap<String, String>& items);
- void removeItem(IPC::Connection&, WebCore::SecurityOriginData&&, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& urlString);
- void clear(IPC::Connection&, WebCore::SecurityOriginData&&, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& urlString);
-
- StorageArea* findStorageArea(IPC::Connection&, uint64_t) const;
-
LocalStorageNamespace* getOrCreateLocalStorageNamespace(uint64_t storageNamespaceID);
-
TransientLocalStorageNamespace* getOrCreateTransientLocalStorageNamespace(uint64_t storageNamespaceID, WebCore::SecurityOriginData&& topLevelOrigin);
-
- Ref<WorkQueue> m_queue;
+ SessionStorageNamespace* getOrCreateSessionStorageNamespace(uint64_t storageNamespaceID);
RefPtr<LocalStorageDatabaseTracker> m_localStorageDatabaseTracker;
HashMap<uint64_t, RefPtr<LocalStorageNamespace>> m_localStorageNamespaces;
-
HashMap<std::pair<uint64_t, WebCore::SecurityOriginData>, RefPtr<TransientLocalStorageNamespace>> m_transientLocalStorageNamespaces;
-
HashMap<uint64_t, RefPtr<SessionStorageNamespace>> m_sessionStorageNamespaces;
-
- HashMap<std::pair<IPC::Connection::UniqueID, uint64_t>, RefPtr<StorageArea>> m_storageAreasByConnection;
- HashSet<IPC::Connection::UniqueID> m_connections;
-
- enum class State {
- Running,
- WillSuspend,
- Suspended
- };
- State m_state { State::Running };
- Lock m_stateLock;
- Condition m_stateChangeCondition;
};
} // namespace WebKit
diff --git a/Source/WebKit/NetworkProcess/WebStorage/StorageManager.messages.in b/Source/WebKit/NetworkProcess/WebStorage/StorageManager.messages.in
deleted file mode 100644
index 78bb6ab..0000000
--- a/Source/WebKit/NetworkProcess/WebStorage/StorageManager.messages.in
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2013-2019 Apple Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-messages -> StorageManager {
- CreateLocalStorageMap(uint64_t storageMapID, uint64_t storageNamespaceID, struct WebCore::SecurityOriginData securityOriginData) WantsConnection
- CreateTransientLocalStorageMap(uint64_t storageMapID, uint64_t storageNamespaceID, struct WebCore::SecurityOriginData topLevelSecurityOriginData, struct WebCore::SecurityOriginData securityOriginData) WantsConnection
- CreateSessionStorageMap(uint64_t storageMapID, uint64_t storageNamespaceID, struct WebCore::SecurityOriginData securityOriginData) WantsConnection
- DestroyStorageMap(uint64_t storageMapID) WantsConnection
-
- Prewarm(uint64_t storageMapID) WantsConnection
- GetValues(uint64_t storageMapID, uint64_t storageMapSeed) -> (HashMap<String, String> values) Synchronous WantsConnection
-
- SetItem(struct WebCore::SecurityOriginData securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, String key, String value, String urlString) WantsConnection
- SetItems(uint64_t storageMapID, HashMap<String, String> items) WantsConnection
- RemoveItem(struct WebCore::SecurityOriginData securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, String key, String urlString) WantsConnection
- Clear(struct WebCore::SecurityOriginData securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, String urlString) WantsConnection
-}
diff --git a/Source/WebKit/NetworkProcess/WebStorage/StorageManagerSet.cpp b/Source/WebKit/NetworkProcess/WebStorage/StorageManagerSet.cpp
new file mode 100644
index 0000000..81c7b71
--- /dev/null
+++ b/Source/WebKit/NetworkProcess/WebStorage/StorageManagerSet.cpp
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StorageManagerSet.h"
+
+#include "StorageAreaMapMessages.h"
+#include "StorageManagerSetMessages.h"
+#include <wtf/threads/BinarySemaphore.h>
+
+namespace WebKit {
+
+const uint64_t invalidStorageAreaID = 0;
+
+Ref<StorageManagerSet> StorageManagerSet::create()
+{
+ return adoptRef(*new StorageManagerSet);
+}
+
+StorageManagerSet::StorageManagerSet()
+ : m_queue(WorkQueue::create("com.apple.WebKit.WebStorage"))
+{
+ ASSERT(RunLoop::isMain());
+
+ // Make sure the encoding is initialized before we start dispatching things to the queue.
+ UTF8Encoding();
+}
+
+StorageManagerSet::~StorageManagerSet()
+{
+ ASSERT(RunLoop::isMain());
+
+ waitUntilTasksFinished();
+}
+
+void StorageManagerSet::add(PAL::SessionID sessionID, const String& localStorageDirectory, SandboxExtension::Handle& localStorageDirectoryHandle)
+{
+ ASSERT(RunLoop::isMain());
+
+ auto[iter, isNewEntry] = m_storageManagerPaths.add(sessionID, localStorageDirectory);
+ if (isNewEntry) {
+ if (!sessionID.isEphemeral())
+ SandboxExtension::consumePermanently(localStorageDirectoryHandle);
+
+ m_queue->dispatch([this, protectedThis = makeRef(*this), sessionID, directory = localStorageDirectory.isolatedCopy()]() mutable {
+ m_storageManagers.ensure(sessionID, [directory]() mutable {
+ return StorageManager::create(WTFMove(directory));
+ });
+ });
+ }
+}
+
+void StorageManagerSet::remove(PAL::SessionID sessionID)
+{
+ ASSERT(RunLoop::isMain());
+
+ if (m_storageManagerPaths.remove(sessionID)) {
+ m_queue->dispatch([this, protectedThis = makeRef(*this), sessionID]() {
+ m_storageManagers.remove(sessionID);
+ });
+ }
+}
+
+bool StorageManagerSet::contains(PAL::SessionID sessionID)
+{
+ ASSERT(RunLoop::isMain());
+
+ return m_storageManagerPaths.contains(sessionID);
+}
+
+void StorageManagerSet::addConnection(IPC::Connection& connection)
+{
+ ASSERT(RunLoop::isMain());
+
+ auto connectionID = connection.uniqueID();
+ ASSERT(!m_connections.contains(connectionID));
+ if (m_connections.add(connectionID).isNewEntry)
+ connection.addWorkQueueMessageReceiver(Messages::StorageManagerSet::messageReceiverName(), m_queue.get(), this);
+}
+
+void StorageManagerSet::removeConnection(IPC::Connection& connection)
+{
+ ASSERT(RunLoop::isMain());
+
+ auto connectionID = connection.uniqueID();
+ ASSERT(m_connections.contains(connectionID));
+ m_connections.remove(connectionID);
+ connection.removeWorkQueueMessageReceiver(Messages::StorageManagerSet::messageReceiverName());
+
+ m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID]() {
+ for (auto& storageArea : m_storageAreas.values())
+ storageArea->removeListener(connectionID);
+ });
+}
+
+void StorageManagerSet::waitUntilTasksFinished()
+{
+ ASSERT(RunLoop::isMain());
+
+ BinarySemaphore semaphore;
+ m_queue->dispatch([this, &semaphore] {
+ for (auto& [sessionID, storageManager] : m_storageManagers)
+ storageManager->clearStorageNamespaces();
+
+ m_storageManagers.clear();
+ m_storageAreas.clear();
+
+ semaphore.signal();
+ });
+ semaphore.wait();
+}
+
+void StorageManagerSet::waitUntilSyncingLocalStorageFinished()
+{
+ ASSERT(RunLoop::isMain());
+
+ BinarySemaphore semaphore;
+ m_queue->dispatch([this, &semaphore] {
+ for (auto* storageArea : m_storageAreas.values())
+ storageArea->syncToDatabase();
+
+ semaphore.signal();
+ });
+ semaphore.wait();
+}
+
+void StorageManagerSet::suspend(CompletionHandler<void()>&& completionHandler)
+{
+ ASSERT(RunLoop::isMain());
+
+ CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
+ Locker<Lock> stateLocker(m_stateLock);
+ if (m_state != State::Running)
+ return;
+ m_state = State::WillSuspend;
+
+ m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = completionHandlerCaller.release()] () mutable {
+ Locker<Lock> stateLocker(m_stateLock);
+ ASSERT(m_state != State::Suspended);
+
+ if (m_state != State::WillSuspend) {
+ RunLoop::main().dispatch(WTFMove(completionHandler));
+ return;
+ }
+
+ m_state = State::Suspended;
+ RunLoop::main().dispatch(WTFMove(completionHandler));
+
+ while (m_state == State::Suspended)
+ m_stateChangeCondition.wait(m_stateLock);
+ ASSERT(m_state == State::Running);
+ });
+}
+
+void StorageManagerSet::resume()
+{
+ ASSERT(RunLoop::isMain());
+
+ Locker<Lock> stateLocker(m_stateLock);
+ auto previousState = m_state;
+ m_state = State::Running;
+ if (previousState == State::Suspended)
+ m_stateChangeCondition.notifyOne();
+}
+
+void StorageManagerSet::getSessionStorageOrigins(PAL::SessionID sessionID, CompletionHandler<void(HashSet<WebCore::SecurityOriginData>&&)>&& completionHandler)
+{
+ m_queue->dispatch([this, protectedThis = makeRef(*this), sessionID, completionHandler = WTFMove(completionHandler)]() mutable {
+ auto* storageManager = m_storageManagers.get(sessionID);
+ ASSERT(storageManager);
+
+ storageManager->getSessionStorageOrigins(WTFMove(completionHandler));
+ });
+}
+
+void StorageManagerSet::deleteSessionStorage(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
+{
+ m_queue->dispatch([this, protectedThis = makeRef(*this), sessionID, completionHandler = WTFMove(completionHandler)]() mutable {
+ auto* storageManager = m_storageManagers.get(sessionID);
+ ASSERT(storageManager);
+
+ storageManager->deleteSessionStorageOrigins(WTFMove(completionHandler));
+ });
+}
+
+void StorageManagerSet::deleteSessionStorageForOrigins(PAL::SessionID sessionID, const Vector<WebCore::SecurityOriginData>& originDatas, DeleteCallback&& completionHandler)
+{
+ m_queue->dispatch([this, protectedThis = makeRef(*this), sessionID, copiedOriginDatas = crossThreadCopy(originDatas), completionHandler = WTFMove(completionHandler)]() mutable {
+ auto* storageManager = m_storageManagers.get(sessionID);
+ ASSERT(storageManager);
+
+ storageManager->deleteSessionStorageEntriesForOrigins(copiedOriginDatas, WTFMove(completionHandler));
+ });
+}
+
+void StorageManagerSet::getLocalStorageOrigins(PAL::SessionID sessionID, GetOriginsCallback&& completionHandler)
+{
+ m_queue->dispatch([this, protectedThis = makeRef(*this), sessionID, completionHandler = WTFMove(completionHandler)]() mutable {
+ auto* storageManager = m_storageManagers.get(sessionID);
+ ASSERT(storageManager);
+
+ storageManager->getLocalStorageOrigins(WTFMove(completionHandler));
+ });
+}
+
+void StorageManagerSet::deleteLocalStorageModifiedSince(PAL::SessionID sessionID, WallTime time, DeleteCallback&& completionHandler)
+{
+ m_queue->dispatch([this, protectedThis = makeRef(*this), sessionID, time, completionHandler = WTFMove(completionHandler)]() mutable {
+ auto* storageManager = m_storageManagers.get(sessionID);
+ ASSERT(storageManager);
+
+ storageManager->deleteLocalStorageOriginsModifiedSince(time, WTFMove(completionHandler));
+ });
+}
+
+void StorageManagerSet::deleteLocalStorageForOrigins(PAL::SessionID sessionID, const Vector<WebCore::SecurityOriginData>& originDatas, DeleteCallback&& completionHandler)
+{
+ m_queue->dispatch([this, protectedThis = makeRef(*this), sessionID, copiedOriginDatas = crossThreadCopy(originDatas), completionHandler = WTFMove(completionHandler)]() mutable {
+ auto* storageManager = m_storageManagers.get(sessionID);
+ ASSERT(storageManager);
+
+ storageManager->deleteLocalStorageEntriesForOrigins(copiedOriginDatas, WTFMove(completionHandler));
+ });
+}
+
+void StorageManagerSet::getLocalStorageOriginDetails(PAL::SessionID sessionID, CompletionHandler<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&& completionHandler)
+{
+ m_queue->dispatch([this, protectedThis = makeRef(*this), sessionID, completionHandler = WTFMove(completionHandler)]() mutable {
+ auto* storageManager = m_storageManagers.get(sessionID);
+ ASSERT(storageManager);
+
+ storageManager->getLocalStorageOriginDetails(WTFMove(completionHandler));
+ });
+}
+
+void StorageManagerSet::connectToLocalStorageArea(IPC::Connection& connection, PAL::SessionID sessionID, uint64_t storageNamespaceID, SecurityOriginData&& originData, ConnectToStorageAreaCallback&& completionHandler)
+{
+ ASSERT(!RunLoop::isMain());
+
+ auto* storageManager = m_storageManagers.get(sessionID);
+ if (!storageManager) {
+ completionHandler(invalidStorageAreaID);
+ return;
+ }
+
+ auto* storageArea = storageManager->createLocalStorageArea(storageNamespaceID, WTFMove(originData));
+ if (!storageArea) {
+ completionHandler(invalidStorageAreaID);
+ return;
+ }
+
+ auto storageAreaID = storageArea->identifier();
+ auto[iter, isNewEntry] = m_storageAreas.add(storageAreaID, nullptr);
+ if (isNewEntry) {
+ storageArea->setWorkQueue(m_queue.ptr());
+ iter->value = storageArea;
+ } else
+ ASSERT(storageArea == iter->value);
+
+ completionHandler(storageAreaID);
+
+ storageArea->addListener(connection.uniqueID());
+}
+
+void StorageManagerSet::connectToTransientLocalStorageArea(IPC::Connection& connection, PAL::SessionID sessionID, uint64_t storageNamespaceID, SecurityOriginData&& topLevelOriginData, SecurityOriginData&& originData, ConnectToStorageAreaCallback&& completionHandler)
+{
+ ASSERT(!RunLoop::isMain());
+
+ auto* storageManager = m_storageManagers.get(sessionID);
+ if (!storageManager) {
+ completionHandler(invalidStorageAreaID);
+ return;
+ }
+
+ auto* storageArea = storageManager->createTransientLocalStorageArea(storageNamespaceID, WTFMove(topLevelOriginData), WTFMove(originData));
+ if (!storageArea) {
+ completionHandler(invalidStorageAreaID);
+ return;
+ }
+
+ auto storageAreaID = storageArea->identifier();
+ auto[iter, isNewEntry] = m_storageAreas.add(storageAreaID, nullptr);
+ if (isNewEntry)
+ iter->value = storageArea;
+ else
+ ASSERT(storageArea == iter->value);
+
+ completionHandler(storageAreaID);
+
+ storageArea->addListener(connection.uniqueID());
+}
+
+void StorageManagerSet::connectToSessionStorageArea(IPC::Connection& connection, PAL::SessionID sessionID, uint64_t storageNamespaceID, SecurityOriginData&& originData, ConnectToStorageAreaCallback&& completionHandler)
+{
+ ASSERT(!RunLoop::isMain());
+
+ auto* storageManager = m_storageManagers.get(sessionID);
+ if (!storageManager) {
+ completionHandler(invalidStorageAreaID);
+ return;
+ }
+
+ auto* storageArea = storageManager->createSessionStorageArea(storageNamespaceID, WTFMove(originData));
+ if (!storageArea) {
+ completionHandler(invalidStorageAreaID);
+ return;
+ }
+
+ auto storageAreaID = storageArea->identifier();
+ auto[iter, isNewEntry] = m_storageAreas.add(storageAreaID, nullptr);
+ if (isNewEntry)
+ iter->value = storageArea;
+ else
+ ASSERT(storageArea == iter->value);
+
+ completionHandler(storageAreaID);
+
+ storageArea->addListener(connection.uniqueID());
+}
+
+void StorageManagerSet::disconnectFromStorageArea(IPC::Connection& connection, uint64_t storageAreaID)
+{
+ ASSERT(!RunLoop::isMain());
+
+ auto* storageArea = m_storageAreas.get(storageAreaID);
+ ASSERT(storageArea);
+ ASSERT(storageArea->hasListener(connection.uniqueID()));
+
+ storageArea->removeListener(connection.uniqueID());
+}
+
+void StorageManagerSet::getValues(IPC::Connection& connection, uint64_t storageAreaID, GetValuesCallback&& completionHandler)
+{
+ ASSERT(!RunLoop::isMain());
+
+ auto* storageArea = m_storageAreas.get(storageAreaID);
+ ASSERT(!storageArea || storageArea->hasListener(connection.uniqueID()));
+
+ completionHandler(storageArea ? storageArea->items() : HashMap<String, String>());
+}
+
+void StorageManagerSet::setItem(IPC::Connection& connection, uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString)
+{
+ ASSERT(!RunLoop::isMain());
+
+ auto* storageArea = m_storageAreas.get(storageAreaID);
+ ASSERT(storageArea);
+
+ bool quotaError;
+ storageArea->setItem(connection.uniqueID(), sourceStorageAreaID, key, value, urlString, quotaError);
+
+ connection.send(Messages::StorageAreaMap::DidSetItem(storageMapSeed, key, quotaError), storageAreaID);
+}
+
+void StorageManagerSet::removeItem(IPC::Connection& connection, uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& urlString)
+{
+ ASSERT(!RunLoop::isMain());
+
+ auto* storageArea = m_storageAreas.get(storageAreaID);
+ ASSERT(storageArea);
+
+ storageArea->removeItem(connection.uniqueID(), sourceStorageAreaID, key, urlString);
+
+ connection.send(Messages::StorageAreaMap::DidRemoveItem(storageMapSeed, key), storageAreaID);
+}
+
+void StorageManagerSet::clear(IPC::Connection& connection, uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& urlString)
+{
+ ASSERT(!RunLoop::isMain());
+
+ auto* storageArea = m_storageAreas.get(storageAreaID);
+ ASSERT(storageArea);
+
+ storageArea->clear(connection.uniqueID(), sourceStorageAreaID, urlString);
+
+ connection.send(Messages::StorageAreaMap::DidClear(storageMapSeed), storageAreaID);
+}
+
+void StorageManagerSet::cloneSessionStorageNamespace(IPC::Connection&, PAL::SessionID sessionID, uint64_t fromStorageNamespaceID, uint64_t toStorageNamespaceID)
+{
+ ASSERT(!RunLoop::isMain());
+
+ if (auto* storageManager = m_storageManagers.get(sessionID))
+ storageManager->cloneSessionStorageNamespace(fromStorageNamespaceID, toStorageNamespaceID);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/NetworkProcess/WebStorage/StorageManagerSet.h b/Source/WebKit/NetworkProcess/WebStorage/StorageManagerSet.h
new file mode 100644
index 0000000..77032ac
--- /dev/null
+++ b/Source/WebKit/NetworkProcess/WebStorage/StorageManagerSet.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "SandboxExtension.h"
+#include "StorageManager.h"
+#include <WebCore/SecurityOriginData.h>
+#include <pal/SessionID.h>
+
+using WebCore::SecurityOriginData;
+
+namespace WebKit {
+
+class SandboxExtension;
+
+using ConnectToStorageAreaCallback = CompletionHandler<void(uint64_t)>;
+using GetValuesCallback = CompletionHandler<void(const HashMap<String, String>&)>;
+using GetOriginsCallback = CompletionHandler<void(HashSet<WebCore::SecurityOriginData>&&)>;
+using GetOriginDetailsCallback = CompletionHandler<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>;
+using DeleteCallback = CompletionHandler<void()>;
+
+class StorageManagerSet : public IPC::Connection::WorkQueueMessageReceiver {
+public:
+ static Ref<StorageManagerSet> create();
+ StorageManagerSet();
+ ~StorageManagerSet();
+
+ void add(PAL::SessionID, const String& localStorageDirectory, SandboxExtension::Handle& localStorageDirectoryHandle);
+ void remove(PAL::SessionID);
+ bool contains(PAL::SessionID);
+
+ void addConnection(IPC::Connection&);
+ void removeConnection(IPC::Connection&);
+
+ void waitUntilTasksFinished();
+ void waitUntilSyncingLocalStorageFinished();
+ void suspend(CompletionHandler<void()>&&);
+ void resume();
+
+ void getSessionStorageOrigins(PAL::SessionID, GetOriginsCallback&&);
+ void deleteSessionStorage(PAL::SessionID, DeleteCallback&&);
+ void deleteSessionStorageForOrigins(PAL::SessionID, const Vector<WebCore::SecurityOriginData>&, DeleteCallback&&);
+ void getLocalStorageOrigins(PAL::SessionID, GetOriginsCallback&&);
+ void deleteLocalStorageModifiedSince(PAL::SessionID, WallTime, DeleteCallback&&);
+ void deleteLocalStorageForOrigins(PAL::SessionID, const Vector<WebCore::SecurityOriginData>&, DeleteCallback&&);
+ void getLocalStorageOriginDetails(PAL::SessionID, GetOriginDetailsCallback&&);
+
+ void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
+ void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>& replyEncoder);
+
+private:
+ // Message Handlers
+ void connectToLocalStorageArea(IPC::Connection&, PAL::SessionID , uint64_t storageNamespaceID, SecurityOriginData&&, ConnectToStorageAreaCallback&&);
+ void connectToTransientLocalStorageArea(IPC::Connection&, PAL::SessionID , uint64_t storageNamespaceID, SecurityOriginData&&, SecurityOriginData&&, ConnectToStorageAreaCallback&&);
+ void connectToSessionStorageArea(IPC::Connection&, PAL::SessionID, uint64_t storageNamespaceID, SecurityOriginData&&, ConnectToStorageAreaCallback&&);
+ void disconnectFromStorageArea(IPC::Connection&, uint64_t storageAreaID);
+ void getValues(IPC::Connection&, uint64_t storageAreaID, GetValuesCallback&&);
+ void setItem(IPC::Connection&, uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString);
+ void removeItem(IPC::Connection&, uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& urlString);
+ void clear(IPC::Connection&, uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& urlString);
+ void cloneSessionStorageNamespace(IPC::Connection&, PAL::SessionID, uint64_t fromStorageNamespaceID, uint64_t toStorageNamespaceID);
+
+ HashMap<PAL::SessionID, RefPtr<StorageManager>> m_storageManagers;
+ HashMap<PAL::SessionID, String> m_storageManagerPaths;
+ HashMap<uint64_t, StorageArea*> m_storageAreas;
+
+ HashSet<IPC::Connection::UniqueID> m_connections;
+ Ref<WorkQueue> m_queue;
+
+ enum class State {
+ Running,
+ WillSuspend,
+ Suspended
+ };
+ State m_state { State::Running };
+ Lock m_stateLock;
+ Condition m_stateChangeCondition;
+};
+
+} // namespace WebKit
diff --git a/Source/WebKit/NetworkProcess/WebStorage/StorageManagerSet.messages.in b/Source/WebKit/NetworkProcess/WebStorage/StorageManagerSet.messages.in
new file mode 100644
index 0000000..e0c13a0
--- /dev/null
+++ b/Source/WebKit/NetworkProcess/WebStorage/StorageManagerSet.messages.in
@@ -0,0 +1,34 @@
+# Copyright (C) 2019 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+messages -> StorageManagerSet {
+ ConnectToLocalStorageArea(PAL::SessionID sessionID, uint64_t storageNamespaceID, struct WebCore::SecurityOriginData securityOriginData) -> (uint64_t storageAreaID) Synchronous WantsConnection
+ ConnectToTransientLocalStorageArea(PAL::SessionID sessionID, uint64_t storageNamespaceID, struct WebCore::SecurityOriginData topLevelSecurityOriginData, struct WebCore::SecurityOriginData securityOriginData) -> (uint64_t storageAreaID) Synchronous WantsConnection
+ ConnectToSessionStorageArea(PAL::SessionID sessionID, uint64_t storageNamespaceID, struct WebCore::SecurityOriginData securityOriginData) -> (uint64_t storageAreaID) Synchronous WantsConnection
+ DisconnectFromStorageArea(uint64_t storageAreaID) WantsConnection
+ GetValues(uint64_t storageAreaID) -> (HashMap<String, String> values) Synchronous WantsConnection
+ CloneSessionStorageNamespace(PAL::SessionID sessionID, uint64_t fromStorageNamespaceID, uint64_t toStorageNamespaceID) WantsConnection
+
+ SetItem(uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, String key, String value, String urlString) WantsConnection
+ RemoveItem(uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, String key, String urlString) WantsConnection
+ Clear(uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, String urlString) WantsConnection
+}
diff --git a/Source/WebKit/Shared/WebsiteDataStoreParameters.cpp b/Source/WebKit/Shared/WebsiteDataStoreParameters.cpp
index d91a34f..f18dd16 100644
--- a/Source/WebKit/Shared/WebsiteDataStoreParameters.cpp
+++ b/Source/WebKit/Shared/WebsiteDataStoreParameters.cpp
@@ -53,6 +53,8 @@
encoder << serviceWorkerRegistrationDirectory << serviceWorkerRegistrationDirectoryExtensionHandle;
#endif
+ encoder << localStorageDirectory << localStorageDirectoryExtensionHandle;
+
encoder << perOriginStorageQuota;
encoder << perThirdPartyOriginStorageQuota;
}
@@ -121,6 +123,18 @@
parameters.serviceWorkerRegistrationDirectoryExtensionHandle = WTFMove(*serviceWorkerRegistrationDirectoryExtensionHandle);
#endif
+ Optional<String> localStorageDirectory;
+ decoder >> localStorageDirectory;
+ if (!localStorageDirectory)
+ return WTF::nullopt;
+ parameters.localStorageDirectory = WTFMove(*localStorageDirectory);
+
+ Optional<SandboxExtension::Handle> localStorageDirectoryExtensionHandle;
+ decoder >> localStorageDirectoryExtensionHandle;
+ if (!localStorageDirectoryExtensionHandle)
+ return WTF::nullopt;
+ parameters.localStorageDirectoryExtensionHandle = WTFMove(*localStorageDirectoryExtensionHandle);
+
Optional<uint64_t> perOriginStorageQuota;
decoder >> perOriginStorageQuota;
if (!perOriginStorageQuota)
@@ -149,6 +163,7 @@
#if ENABLE(SERVICE_WORKER)
, { }, { }
#endif
+ , { }, { }
};
}
diff --git a/Source/WebKit/Shared/WebsiteDataStoreParameters.h b/Source/WebKit/Shared/WebsiteDataStoreParameters.h
index 992fee9..6fece3f 100644
--- a/Source/WebKit/Shared/WebsiteDataStoreParameters.h
+++ b/Source/WebKit/Shared/WebsiteDataStoreParameters.h
@@ -70,6 +70,9 @@
SandboxExtension::Handle serviceWorkerRegistrationDirectoryExtensionHandle;
#endif
+ String localStorageDirectory;
+ SandboxExtension::Handle localStorageDirectoryExtensionHandle;
+
uint64_t perOriginStorageQuota { WebCore::StorageQuotaManager::defaultQuota() };
uint64_t perThirdPartyOriginStorageQuota { WebCore::StorageQuotaManager::defaultThirdPartyQuota() };
};
diff --git a/Source/WebKit/Sources.txt b/Source/WebKit/Sources.txt
index 4bc20fd..b466d2c 100644
--- a/Source/WebKit/Sources.txt
+++ b/Source/WebKit/Sources.txt
@@ -70,6 +70,7 @@
NetworkProcess/WebStorage/SessionStorageNamespace.cpp
NetworkProcess/WebStorage/StorageArea.cpp
NetworkProcess/WebStorage/StorageManager.cpp
+NetworkProcess/WebStorage/StorageManagerSet.cpp
NetworkProcess/WebStorage/TransientLocalStorageNamespace.cpp
NetworkProcess/cache/CacheStorageEngine.cpp
diff --git a/Source/WebKit/UIProcess/API/C/WKContext.cpp b/Source/WebKit/UIProcess/API/C/WKContext.cpp
index d0eb31a..d83c6b8 100644
--- a/Source/WebKit/UIProcess/API/C/WKContext.cpp
+++ b/Source/WebKit/UIProcess/API/C/WKContext.cpp
@@ -669,3 +669,19 @@
{
WebKit::toImpl(contextRef)->clearCurrentModifierStateForTesting();
}
+
+void WKContextSyncLocalStorage(WKContextRef contextRef, void* context, WKContextSyncLocalStorageCallback callback)
+{
+ WebKit::toImpl(contextRef)->syncLocalStorage([context, callback] {
+ if (callback)
+ callback(context);
+ });
+}
+
+void WKContextClearLegacyPrivateBrowsingLocalStorage(WKContextRef contextRef, void* context, WKContextClearLegacyPrivateBrowsingLocalStorageCallback callback)
+{
+ WebKit::toImpl(contextRef)->clearLegacyPrivateBrowsingLocalStorage([context, callback] {
+ if (callback)
+ callback(context);
+ });
+}
diff --git a/Source/WebKit/UIProcess/API/C/WKContextPrivate.h b/Source/WebKit/UIProcess/API/C/WKContextPrivate.h
index f9c7d32..58f1a92 100644
--- a/Source/WebKit/UIProcess/API/C/WKContextPrivate.h
+++ b/Source/WebKit/UIProcess/API/C/WKContextPrivate.h
@@ -120,6 +120,12 @@
WK_EXPORT void WKContextClearCurrentModifierStateForTesting(WKContextRef context);
+typedef void (*WKContextSyncLocalStorageCallback)(void* functionContext);
+WK_EXPORT void WKContextSyncLocalStorage(WKContextRef contextRef, void* context, WKContextSyncLocalStorageCallback callback);
+
+typedef void (*WKContextClearLegacyPrivateBrowsingLocalStorageCallback)(void* functionContext);
+WK_EXPORT void WKContextClearLegacyPrivateBrowsingLocalStorage(WKContextRef contextRef, void* context, WKContextClearLegacyPrivateBrowsingLocalStorageCallback callback);
+
#ifdef __cplusplus
}
#endif
diff --git a/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp b/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp
index 96b2337..8faa76f 100644
--- a/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp
+++ b/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp
@@ -531,6 +531,15 @@
});
}
+void WKWebsiteDataStoreRemoveLocalStorage(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreRemoveLocalStorageCallback callback)
+{
+ OptionSet<WebKit::WebsiteDataType> dataTypes = WebKit::WebsiteDataType::LocalStorage;
+ WebKit::toImpl(dataStoreRef)->websiteDataStore().removeData(dataTypes, -WallTime::infinity(), [context, callback] {
+ if (callback)
+ callback(context);
+ });
+}
+
void WKWebsiteDataStoreRemoveAllServiceWorkerRegistrations(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreRemoveAllServiceWorkerRegistrationsCallback callback)
{
#if ENABLE(SERVICE_WORKER)
diff --git a/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h b/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h
index cde14ca..7dec92a 100644
--- a/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h
+++ b/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h
@@ -121,6 +121,9 @@
typedef void (*WKWebsiteDataStoreGetFetchCacheOriginsFunction)(WKArrayRef, void*);
WK_EXPORT void WKWebsiteDataStoreGetFetchCacheOrigins(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreGetFetchCacheOriginsFunction function);
+typedef void (*WKWebsiteDataStoreRemoveLocalStorageCallback)(void* functionContext);
+WK_EXPORT void WKWebsiteDataStoreRemoveLocalStorage(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreRemoveLocalStorageCallback callback);
+
typedef void (*WKWebsiteDataStoreGetFetchCacheSizeForOriginFunction)(uint64_t, void*);
WK_EXPORT void WKWebsiteDataStoreGetFetchCacheSizeForOrigin(WKWebsiteDataStoreRef dataStoreRef, WKStringRef origin, void* context, WKWebsiteDataStoreGetFetchCacheSizeForOriginFunction function);
diff --git a/Source/WebKit/UIProcess/WebProcessPool.cpp b/Source/WebKit/UIProcess/WebProcessPool.cpp
index 36367f0..b976791 100644
--- a/Source/WebKit/UIProcess/WebProcessPool.cpp
+++ b/Source/WebKit/UIProcess/WebProcessPool.cpp
@@ -583,8 +583,8 @@
auto localStorageDirectory = m_websiteDataStore ? m_websiteDataStore->websiteDataStore().resolvedLocalStorageDirectory() : nullString();
if (!localStorageDirectory)
localStorageDirectory = API::WebsiteDataStore::defaultLocalStorageDirectory();
- parameters.defaultDataStoreParameters.networkSessionParameters.localStorageDirectory = localStorageDirectory;
- SandboxExtension::createHandleForReadWriteDirectory(localStorageDirectory, parameters.defaultDataStoreParameters.networkSessionParameters.localStorageDirectoryExtensionHandle);
+ parameters.defaultDataStoreParameters.localStorageDirectory = localStorageDirectory;
+ SandboxExtension::createHandleForReadWriteDirectory(localStorageDirectory, parameters.defaultDataStoreParameters.localStorageDirectoryExtensionHandle);
if (m_websiteDataStore)
parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectory = m_websiteDataStore->websiteDataStore().resolvedResourceLoadStatisticsDirectory();
@@ -1809,6 +1809,19 @@
#endif
}
+void WebProcessPool::syncLocalStorage(CompletionHandler<void()>&& completionHandler)
+{
+ sendSyncToNetworkingProcess(Messages::NetworkProcess::SyncLocalStorage(), Messages::NetworkProcess::SyncLocalStorage::Reply());
+ completionHandler();
+}
+
+void WebProcessPool::clearLegacyPrivateBrowsingLocalStorage(CompletionHandler<void()>&& completionHandler)
+{
+ if (m_networkProcess)
+ m_networkProcess->send(Messages::NetworkProcess::ClearLegacyPrivateBrowsingLocalStorage(), 0);
+ completionHandler();
+}
+
void WebProcessPool::allowSpecificHTTPSCertificateForHost(const WebCertificateInfo* certificate, const String& host)
{
ensureNetworkProcess();
diff --git a/Source/WebKit/UIProcess/WebProcessPool.h b/Source/WebKit/UIProcess/WebProcessPool.h
index 2ccb47f..ed6c29f 100644
--- a/Source/WebKit/UIProcess/WebProcessPool.h
+++ b/Source/WebKit/UIProcess/WebProcessPool.h
@@ -317,6 +317,8 @@
void disableServiceWorkerProcessTerminationDelay();
void syncNetworkProcessCookies();
+ void syncLocalStorage(CompletionHandler<void()>&& callback);
+ void clearLegacyPrivateBrowsingLocalStorage(CompletionHandler<void()>&& callback);
void setIDBPerOriginQuota(uint64_t);
diff --git a/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm b/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm
index ba9fcce..a0544d0 100644
--- a/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm
+++ b/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm
@@ -109,11 +109,6 @@
if (!resourceLoadStatisticsDirectory.isEmpty())
SandboxExtension::createHandleForReadWriteDirectory(resourceLoadStatisticsDirectory, resourceLoadStatisticsDirectoryHandle);
- auto localStorageDirectory = resolvedLocalStorageDirectory();
- SandboxExtension::Handle localStorageDirectoryExtensionHandle;
- if (!localStorageDirectory.isEmpty())
- SandboxExtension::createHandleForReadWriteDirectory(localStorageDirectory, localStorageDirectoryExtensionHandle);
-
auto networkCacheDirectory = resolvedNetworkCacheDirectory();
SandboxExtension::Handle networkCacheDirectoryExtensionHandle;
if (!networkCacheDirectory.isEmpty())
@@ -143,8 +138,6 @@
m_configuration->deviceManagementRestrictionsEnabled(),
m_configuration->allLoadsBlockedByDeviceManagementRestrictionsForTesting(),
WTFMove(resourceLoadStatisticsManualPrevalentResource),
- WTFMove(localStorageDirectory),
- WTFMove(localStorageDirectoryExtensionHandle),
WTFMove(networkCacheDirectory),
WTFMove(networkCacheDirectoryExtensionHandle),
};
@@ -180,6 +173,10 @@
SandboxExtension::createHandleForReadWriteDirectory(parameters.serviceWorkerRegistrationDirectory, parameters.serviceWorkerRegistrationDirectoryExtensionHandle);
#endif
+ parameters.localStorageDirectory = resolvedLocalStorageDirectory();
+ if (!parameters.localStorageDirectory.isEmpty())
+ SandboxExtension::createHandleForReadWriteDirectory(parameters.localStorageDirectory, parameters.localStorageDirectoryExtensionHandle);
+
parameters.perOriginStorageQuota = perOriginStorageQuota();
parameters.perThirdPartyOriginStorageQuota = perThirdPartyOriginStorageQuota();
diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
index 02587b1..6ff1bcd 100644
--- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
+++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
@@ -1969,8 +1969,8 @@
auto localStorageDirectory = resolvedLocalStorageDirectory();
if (!localStorageDirectory.isEmpty()) {
- parameters.networkSessionParameters.localStorageDirectory = localStorageDirectory;
- SandboxExtension::createHandleForReadWriteDirectory(localStorageDirectory, parameters.networkSessionParameters.localStorageDirectoryExtensionHandle);
+ parameters.localStorageDirectory = localStorageDirectory;
+ SandboxExtension::createHandleForReadWriteDirectory(localStorageDirectory, parameters.localStorageDirectoryExtensionHandle);
}
#if ENABLE(INDEXED_DATABASE)
diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
index b13e33d..7e9e9e2 100644
--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj
+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj
@@ -293,8 +293,6 @@
1AB1F7971D1B3613007C9BD1 /* WebPaymentCoordinatorMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB1F7931D1B3613007C9BD1 /* WebPaymentCoordinatorMessages.h */; };
1AB1F7981D1B3613007C9BD1 /* WebPaymentCoordinatorProxyMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AB1F7941D1B3613007C9BD1 /* WebPaymentCoordinatorProxyMessageReceiver.cpp */; };
1AB1F7991D1B3613007C9BD1 /* WebPaymentCoordinatorProxyMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB1F7951D1B3613007C9BD1 /* WebPaymentCoordinatorProxyMessages.h */; };
- 1AB31A9616BC688100F6DBC9 /* StorageManagerMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AB31A9416BC688100F6DBC9 /* StorageManagerMessageReceiver.cpp */; };
- 1AB31A9716BC688100F6DBC9 /* StorageManagerMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB31A9516BC688100F6DBC9 /* StorageManagerMessages.h */; };
1AB40EE61BF677E300BA81BE /* WKMenuItemIdentifiersPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB40EE41BF677E300BA81BE /* WKMenuItemIdentifiersPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
1AB474D8184D43FD0051B622 /* WKBundlePageLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB474D7184D43FD0051B622 /* WKBundlePageLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
1AB474DA184D44250051B622 /* WKBundlePageResourceLoadClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB474D9184D44250051B622 /* WKBundlePageResourceLoadClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1275,6 +1273,9 @@
9356F2E12152B76600E6D5DF /* WebSWServerConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93BA04E12151ADF4007F455F /* WebSWServerConnection.cpp */; };
935EEB9B1277617C003322B8 /* WKBundleBackForwardListItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 935EEB981277616D003322B8 /* WKBundleBackForwardListItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
935EEB9F127761AC003322B8 /* WKBundleBackForwardList.h in Headers */ = {isa = PBXBuildFile; fileRef = 935EEB961277616D003322B8 /* WKBundleBackForwardList.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 9368EEDE2303A90200BDB11A /* StorageManagerSetMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9368EEDC2303A8D800BDB11A /* StorageManagerSetMessageReceiver.cpp */; };
+ 9368EEDF2303A9ED00BDB11A /* StorageManagerSetMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 9368EEDD2303A8D800BDB11A /* StorageManagerSetMessages.h */; };
+ 936B059823039097002FC06B /* StorageManagerSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 936B05952303900B002FC06B /* StorageManagerSet.h */; };
93735EBB1C92986300336FA7 /* WKPreviewActionItemInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 93735EBA1C92986300336FA7 /* WKPreviewActionItemInternal.h */; };
9391074F1BF6BC65008C17AD /* WKPreviewElementInfoInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9391074E1BF6BC65008C17AD /* WKPreviewElementInfoInternal.h */; };
9391F2CB121B67AD00EBF7E8 /* WebFrameNetworkingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 9391F283121B38F500EBF7E8 /* WebFrameNetworkingContext.h */; };
@@ -1707,6 +1708,8 @@
compilerSpec = com.apple.compilers.proxy.script;
filePatterns = "*.h";
fileType = pattern.proxy;
+ inputFiles = (
+ );
isEditable = 1;
outputFiles = (
"$(HEADER_OUTPUT_DIR)/$(INPUT_FILE_NAME)",
@@ -2307,8 +2310,6 @@
1AB1F7931D1B3613007C9BD1 /* WebPaymentCoordinatorMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebPaymentCoordinatorMessages.h; path = DerivedSources/WebKit2/WebPaymentCoordinatorMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
1AB1F7941D1B3613007C9BD1 /* WebPaymentCoordinatorProxyMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebPaymentCoordinatorProxyMessageReceiver.cpp; path = DerivedSources/WebKit2/WebPaymentCoordinatorProxyMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
1AB1F7951D1B3613007C9BD1 /* WebPaymentCoordinatorProxyMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebPaymentCoordinatorProxyMessages.h; path = DerivedSources/WebKit2/WebPaymentCoordinatorProxyMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
- 1AB31A9416BC688100F6DBC9 /* StorageManagerMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StorageManagerMessageReceiver.cpp; path = DerivedSources/WebKit2/StorageManagerMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
- 1AB31A9516BC688100F6DBC9 /* StorageManagerMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StorageManagerMessages.h; path = DerivedSources/WebKit2/StorageManagerMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
1AB40EE31BF677E300BA81BE /* WKMenuItemIdentifiers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKMenuItemIdentifiers.mm; sourceTree = "<group>"; };
1AB40EE41BF677E300BA81BE /* WKMenuItemIdentifiersPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKMenuItemIdentifiersPrivate.h; sourceTree = "<group>"; };
1AB474D7184D43FD0051B622 /* WKBundlePageLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKBundlePageLoaderClient.h; sourceTree = "<group>"; };
@@ -3897,6 +3898,11 @@
935EEB961277616D003322B8 /* WKBundleBackForwardList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKBundleBackForwardList.h; sourceTree = "<group>"; };
935EEB971277616D003322B8 /* WKBundleBackForwardListItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKBundleBackForwardListItem.cpp; sourceTree = "<group>"; };
935EEB981277616D003322B8 /* WKBundleBackForwardListItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKBundleBackForwardListItem.h; sourceTree = "<group>"; };
+ 9368EEDC2303A8D800BDB11A /* StorageManagerSetMessageReceiver.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = StorageManagerSetMessageReceiver.cpp; path = DerivedSources/WebKit2/StorageManagerSetMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9368EEDD2303A8D800BDB11A /* StorageManagerSetMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StorageManagerSetMessages.h; path = DerivedSources/WebKit2/StorageManagerSetMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
+ 936B05952303900B002FC06B /* StorageManagerSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageManagerSet.h; sourceTree = "<group>"; };
+ 936B05962303900B002FC06B /* StorageManagerSet.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = StorageManagerSet.messages.in; sourceTree = "<group>"; };
+ 936B05972303900B002FC06B /* StorageManagerSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StorageManagerSet.cpp; sourceTree = "<group>"; };
93735EBA1C92986300336FA7 /* WKPreviewActionItemInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKPreviewActionItemInternal.h; sourceTree = "<group>"; };
9391074E1BF6BC65008C17AD /* WKPreviewElementInfoInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKPreviewElementInfoInternal.h; sourceTree = "<group>"; };
9391F283121B38F500EBF7E8 /* WebFrameNetworkingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFrameNetworkingContext.h; sourceTree = "<group>"; };
@@ -3926,7 +3932,6 @@
93B26148227D147100B97A76 /* ios */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ios; sourceTree = "<group>"; };
93B26149227D147200B97A76 /* StorageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageManager.h; sourceTree = "<group>"; };
93B2614A227D147200B97A76 /* StorageManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StorageManager.cpp; sourceTree = "<group>"; };
- 93B2614B227D147200B97A76 /* StorageManager.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = StorageManager.messages.in; sourceTree = "<group>"; };
93B2614C227D147200B97A76 /* LocalStorageDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LocalStorageDatabase.cpp; sourceTree = "<group>"; };
93BA04DA2151ADF3007F455F /* WebSWServerConnection.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebSWServerConnection.messages.in; sourceTree = "<group>"; };
93BA04DB2151ADF3007F455F /* WebSWServerToContextConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSWServerToContextConnection.h; sourceTree = "<group>"; };
@@ -7304,7 +7309,9 @@
46BEB6D522FB9BD600269867 /* StorageArea.h */,
93B2614A227D147200B97A76 /* StorageManager.cpp */,
93B26149227D147200B97A76 /* StorageManager.h */,
- 93B2614B227D147200B97A76 /* StorageManager.messages.in */,
+ 936B05972303900B002FC06B /* StorageManagerSet.cpp */,
+ 936B05952303900B002FC06B /* StorageManagerSet.h */,
+ 936B05962303900B002FC06B /* StorageManagerSet.messages.in */,
46BEB6E222FBB21A00269867 /* TransientLocalStorageNamespace.cpp */,
46BEB6E122FBB21A00269867 /* TransientLocalStorageNamespace.h */,
);
@@ -8766,8 +8773,8 @@
2DE6943C18BD2A68005C15E5 /* SmartMagnificationControllerMessages.h */,
1A334DEB16DE8F88006A8E38 /* StorageAreaMapMessageReceiver.cpp */,
1A334DEC16DE8F88006A8E38 /* StorageAreaMapMessages.h */,
- 1AB31A9416BC688100F6DBC9 /* StorageManagerMessageReceiver.cpp */,
- 1AB31A9516BC688100F6DBC9 /* StorageManagerMessages.h */,
+ 9368EEDC2303A8D800BDB11A /* StorageManagerSetMessageReceiver.cpp */,
+ 9368EEDD2303A8D800BDB11A /* StorageManagerSetMessages.h */,
5118E9A51F295963003EF9F5 /* StorageProcessMessageReceiver.cpp */,
5118E9A61F295963003EF9F5 /* StorageProcessMessages.h */,
5118E9A71F295963003EF9F5 /* StorageProcessProxyMessageReceiver.cpp */,
@@ -9670,7 +9677,8 @@
1ACECD2517162DB1001FC9EF /* StorageAreaMap.h in Headers */,
1A334DEE16DE8F88006A8E38 /* StorageAreaMapMessages.h in Headers */,
93B2614D227D149E00B97A76 /* StorageManager.h in Headers */,
- 1AB31A9716BC688100F6DBC9 /* StorageManagerMessages.h in Headers */,
+ 936B059823039097002FC06B /* StorageManagerSet.h in Headers */,
+ 9368EEDF2303A9ED00BDB11A /* StorageManagerSetMessages.h in Headers */,
1AE00D6C18327C1200087DD7 /* StringReference.h in Headers */,
296BD85D15019BC30071F424 /* StringUtilities.h in Headers */,
57FD318622B3516C008D0E8B /* SubFrameSOAuthorizationSession.h in Headers */,
@@ -11184,7 +11192,7 @@
2D92A787212B6AB100F493FD /* ShareableBitmap.cpp in Sources */,
2DE6943D18BD2A68005C15E5 /* SmartMagnificationControllerMessageReceiver.cpp in Sources */,
1A334DED16DE8F88006A8E38 /* StorageAreaMapMessageReceiver.cpp in Sources */,
- 1AB31A9616BC688100F6DBC9 /* StorageManagerMessageReceiver.cpp in Sources */,
+ 9368EEDE2303A90200BDB11A /* StorageManagerSetMessageReceiver.cpp in Sources */,
2D92A783212B6A7100F493FD /* StringReference.cpp in Sources */,
2D11B7512126A282006F8878 /* UnifiedSource1-mm.mm in Sources */,
2D11B7522126A282006F8878 /* UnifiedSource1.cpp in Sources */,
diff --git a/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.cpp b/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.cpp
index 20ce559..b0dcb90 100644
--- a/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.cpp
+++ b/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.cpp
@@ -46,6 +46,7 @@
#include "WebProcessCreationParameters.h"
#include "WebProcessMessages.h"
#include "WebProcessPoolMessages.h"
+#include "WebStorageNamespaceProvider.h"
#include "WebUserContentController.h"
#include "WebsiteDataStoreParameters.h"
#include <JavaScriptCore/APICast.h>
@@ -348,9 +349,13 @@
void InjectedBundle::setPrivateBrowsingEnabled(WebPageGroupProxy* pageGroup, bool enabled)
{
ASSERT(!hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
- WebProcess::singleton().enablePrivateBrowsingForTesting(enabled);
+ if (enabled)
+ WebProcess::singleton().ensureLegacyPrivateBrowsingSessionInNetworkProcess();
PageGroup::pageGroup(pageGroup->identifier())->enableLegacyPrivateBrowsingForTesting(enabled);
+
+ auto webStorageNameSpaceProvider = WebStorageNamespaceProvider::getOrCreate(pageGroup->pageGroupID());
+ webStorageNameSpaceProvider->enableLegacyPrivateBrowsingForTesting(enabled);
}
void InjectedBundle::setPopupBlockingEnabled(WebPageGroupProxy* pageGroup, bool enabled)
diff --git a/Source/WebKit/WebProcess/WebProcess.cpp b/Source/WebKit/WebProcess/WebProcess.cpp
index 4eb6def..7600550 100644
--- a/Source/WebKit/WebProcess/WebProcess.cpp
+++ b/Source/WebKit/WebProcess/WebProcess.cpp
@@ -677,7 +677,6 @@
// It is necessary to check for page existence here since during a window.open() (or targeted
// link) the WebPage gets created both in the synchronous handler and through the normal way.
auto result = m_pageMap.add(pageID, nullptr);
- auto oldPageID = parameters.oldPageID ? parameters.oldPageID.value() : pageID;
if (result.isNewEntry) {
ASSERT(!result.iterator->value);
result.iterator->value = WebPage::create(pageID, WTFMove(parameters));
@@ -688,8 +687,6 @@
} else
result.iterator->value->reinitializeWebPage(WTFMove(parameters));
- ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::WebPageWasAdded(result.iterator->value->sessionID(), pageID, oldPageID), 0);
-
ASSERT(result.iterator->value);
}
@@ -697,7 +694,6 @@
{
ASSERT(m_pageMap.contains(pageID));
- ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::WebPageWasRemoved(sessionID, pageID), 0);
pageWillLeaveWindow(pageID);
m_pageMap.remove(pageID);
@@ -1246,16 +1242,6 @@
CRASH();
m_networkProcessConnection = NetworkProcessConnection::create(connectionIdentifier);
-
- // To recover web storage, network process needs to know active webpages to prepare session storage.
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198051.
- // Webpage should be added when Storage is used, not when connection is re-established.
- for (auto& page : m_pageMap) {
- if (!page.value)
- continue;
-
- m_networkProcessConnection->connection().send(Messages::NetworkConnectionToWebProcess::WebPageWasAdded(page.value->sessionID(), page.key, page.key), 0);
- }
}
return *m_networkProcessConnection;
@@ -1286,7 +1272,7 @@
ASSERT(m_networkProcessConnection);
ASSERT_UNUSED(connection, m_networkProcessConnection == connection);
- for (auto* storageAreaMap : m_storageAreaMaps.values())
+ for (auto* storageAreaMap : copyToVector(m_storageAreaMaps.values()))
storageAreaMap->disconnect();
#if ENABLE(INDEXED_DATABASE)
@@ -1687,25 +1673,9 @@
StorageAreaMap* WebProcess::storageAreaMap(uint64_t identifier) const
{
- ASSERT(m_storageAreaMaps.contains(identifier));
return m_storageAreaMaps.get(identifier);
}
-void WebProcess::enablePrivateBrowsingForTesting(bool enable)
-{
- if (enable)
- ensureLegacyPrivateBrowsingSessionInNetworkProcess();
-
- Vector<PageIdentifier> pageIDs;
- for (auto& page : m_pageMap) {
- if (page.value)
- pageIDs.append(page.key);
- }
-
- if (!pageIDs.isEmpty())
- ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::WebProcessSessionChanged(enable ? PAL::SessionID::legacyPrivateSessionID() : PAL::SessionID::defaultSessionID(), pageIDs), 0);
-}
-
void WebProcess::setResourceLoadStatisticsEnabled(bool enabled)
{
WebCore::DeprecatedGlobalSettings::setResourceLoadStatisticsEnabled(enabled);
diff --git a/Source/WebKit/WebProcess/WebProcess.h b/Source/WebKit/WebProcess/WebProcess.h
index 3cb2c49..c591559 100644
--- a/Source/WebKit/WebProcess/WebProcess.h
+++ b/Source/WebKit/WebProcess/WebProcess.h
@@ -215,8 +215,6 @@
void unregisterStorageAreaMap(StorageAreaMap&);
StorageAreaMap* storageAreaMap(uint64_t identifier) const;
- void enablePrivateBrowsingForTesting(bool);
-
#if PLATFORM(COCOA)
RetainPtr<CFDataRef> sourceApplicationAuditData() const;
void destroyRenderingResources();
diff --git a/Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.cpp b/Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.cpp
index 740c0db..ecd2b93 100644
--- a/Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.cpp
+++ b/Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.cpp
@@ -33,6 +33,7 @@
#include <WebCore/SchemeRegistry.h>
#include <WebCore/SecurityOriginData.h>
#include <WebCore/Settings.h>
+#include <WebCore/StorageType.h>
namespace WebKit {
using namespace WebCore;
@@ -50,7 +51,7 @@
StorageAreaImpl::StorageAreaImpl(Ref<StorageAreaMap>&& storageAreaMap)
: m_storageAreaID(generateStorageAreaID())
- , m_storageAreaMap(WTFMove(storageAreaMap))
+ , m_storageAreaMap(makeWeakPtr(storageAreaMap.get()))
{
}
@@ -60,49 +61,54 @@
unsigned StorageAreaImpl::length()
{
- return m_storageAreaMap->length();
+ return m_storageAreaMap ? m_storageAreaMap->length() : 0;
}
String StorageAreaImpl::key(unsigned index)
{
- return m_storageAreaMap->key(index);
+ return m_storageAreaMap ? m_storageAreaMap->key(index) : nullString();
}
String StorageAreaImpl::item(const String& key)
{
- return m_storageAreaMap->item(key);
-}
-
-bool StorageAreaImpl::prewarm()
-{
- return m_storageAreaMap->prewarm();
+ return m_storageAreaMap ? m_storageAreaMap->item(key) : nullString();
}
void StorageAreaImpl::setItem(Frame* sourceFrame, const String& key, const String& value, bool& quotaException)
{
ASSERT(!value.isNull());
- m_storageAreaMap->setItem(sourceFrame, this, key, value, quotaException);
+ if (m_storageAreaMap)
+ m_storageAreaMap->setItem(sourceFrame, this, key, value, quotaException);
}
void StorageAreaImpl::removeItem(Frame* sourceFrame, const String& key)
{
- m_storageAreaMap->removeItem(sourceFrame, this, key);
+ if (m_storageAreaMap)
+ m_storageAreaMap->removeItem(sourceFrame, this, key);
}
void StorageAreaImpl::clear(Frame* sourceFrame)
{
- m_storageAreaMap->clear(sourceFrame, this);
+ if (m_storageAreaMap)
+ m_storageAreaMap->clear(sourceFrame, this);
}
bool StorageAreaImpl::contains(const String& key)
{
- return m_storageAreaMap->contains(key);
+ if (m_storageAreaMap)
+ return m_storageAreaMap->contains(key);
+
+ return false;
}
StorageType StorageAreaImpl::storageType() const
{
- return m_storageAreaMap->storageType();
+ if (m_storageAreaMap)
+ return m_storageAreaMap->storageType();
+
+ // We probably need an Invalid type.
+ return StorageType::Local;
}
size_t StorageAreaImpl::memoryBytesUsedByCache()
@@ -112,12 +118,12 @@
void StorageAreaImpl::incrementAccessCount()
{
- // Storage access is handled in the UI process, so there's nothing to do here.
+ // Storage access is handled in the network process, so there's nothing to do here.
}
void StorageAreaImpl::decrementAccessCount()
{
- // Storage access is handled in the UI process, so there's nothing to do here.
+ // Storage access is handled in the network process, so there's nothing to do here.
}
void StorageAreaImpl::closeDatabaseIfIdle()
@@ -126,9 +132,4 @@
ASSERT_NOT_REACHED();
}
-const SecurityOriginData& StorageAreaImpl::securityOrigin() const
-{
- return m_storageAreaMap->securityOrigin().data();
-}
-
} // namespace WebKit
diff --git a/Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.h b/Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.h
index b8f16f2..b2a8d50 100644
--- a/Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.h
+++ b/Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.h
@@ -28,6 +28,7 @@
#include "MessageReceiver.h"
#include <WebCore/StorageArea.h>
#include <wtf/HashMap.h>
+#include <wtf/WeakPtr.h>
namespace WebCore {
class SecurityOrigin;
@@ -60,11 +61,9 @@
void incrementAccessCount() override;
void decrementAccessCount() override;
void closeDatabaseIfIdle() override;
- const WebCore::SecurityOriginData& securityOrigin() const override;
- bool prewarm() final;
uint64_t m_storageAreaID;
- Ref<StorageAreaMap> m_storageAreaMap;
+ WeakPtr<StorageAreaMap> m_storageAreaMap;
};
} // namespace WebKit
diff --git a/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp b/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp
index 3e050df..6665b3f 100644
--- a/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp
+++ b/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp
@@ -29,7 +29,7 @@
#include "NetworkProcessConnection.h"
#include "StorageAreaImpl.h"
#include "StorageAreaMapMessages.h"
-#include "StorageManagerMessages.h"
+#include "StorageManagerSetMessages.h"
#include "StorageNamespaceImpl.h"
#include "WebPage.h"
#include "WebPageGroupProxy.h"
@@ -48,40 +48,26 @@
namespace WebKit {
using namespace WebCore;
-static uint64_t generateStorageMapID()
-{
- static uint64_t storageMapID;
- return ++storageMapID;
-}
-
Ref<StorageAreaMap> StorageAreaMap::create(StorageNamespaceImpl* storageNamespace, Ref<WebCore::SecurityOrigin>&& securityOrigin)
{
return adoptRef(*new StorageAreaMap(storageNamespace, WTFMove(securityOrigin)));
}
StorageAreaMap::StorageAreaMap(StorageNamespaceImpl* storageNamespace, Ref<WebCore::SecurityOrigin>&& securityOrigin)
- : m_storageNamespace(*storageNamespace)
- , m_storageMapID(generateStorageMapID())
+ : m_storageNamespace(storageNamespace)
+ , m_storageMapID(0)
, m_storageType(storageNamespace->storageType())
- , m_storageNamespaceID(storageNamespace->storageNamespaceID())
, m_quotaInBytes(storageNamespace->quotaInBytes())
, m_securityOrigin(WTFMove(securityOrigin))
, m_currentSeed(0)
, m_hasPendingClear(false)
- , m_hasPendingGetValues(false)
{
- WebProcess::singleton().registerStorageAreaMap(*this);
connect();
}
StorageAreaMap::~StorageAreaMap()
{
- if (m_storageType != StorageType::EphemeralLocal)
- WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::DestroyStorageMap(m_storageMapID), 0);
-
- m_storageNamespace->didDestroyStorageAreaMap(*this);
-
- WebProcess::singleton().unregisterStorageAreaMap(*this);
+ disconnect();
}
unsigned StorageAreaMap::length()
@@ -122,7 +108,7 @@
m_pendingValueChanges.add(key);
- WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::SetItem(m_securityOrigin->data(), m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, key, value, sourceFrame->document()->url()), 0);
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManagerSet::SetItem(m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, key, value, sourceFrame->document()->url()), 0);
}
void StorageAreaMap::removeItem(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea, const String& key)
@@ -138,16 +124,18 @@
m_pendingValueChanges.add(key);
- WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::RemoveItem(m_securityOrigin->data(), m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, key, sourceFrame->document()->url()), 0);
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManagerSet::RemoveItem(m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, key, sourceFrame->document()->url()), 0);
}
void StorageAreaMap::clear(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea)
{
+ connect();
+
resetValues();
m_hasPendingClear = true;
m_storageMap = StorageMap::create(m_quotaInBytes);
- WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::Clear(m_securityOrigin->data(), m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, sourceFrame->document()->url()), 0);
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManagerSet::Clear(m_storageMapID, sourceArea->storageAreaID(), m_currentSeed, sourceFrame->document()->url()), 0);
}
bool StorageAreaMap::contains(const String& key)
@@ -163,7 +151,6 @@
m_pendingValueChanges.clear();
m_hasPendingClear = false;
- m_hasPendingGetValues = false;
m_currentSeed++;
}
@@ -178,33 +165,10 @@
// FIXME: This should use a special sendSync flag to indicate that we don't want to process incoming messages while waiting for a reply.
// (This flag does not yet exist). Since loadValuesIfNeeded() ends up being called from within JavaScript code, processing incoming synchronous messages
// could lead to weird reentrency bugs otherwise.
- WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::StorageManager::GetValues(m_storageMapID, m_currentSeed), Messages::StorageManager::GetValues::Reply(values), 0);
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::StorageManagerSet::GetValues(m_storageMapID), Messages::StorageManagerSet::GetValues::Reply(values), 0);
m_storageMap = StorageMap::create(m_quotaInBytes);
m_storageMap->importItems(WTFMove(values));
-
- // We want to ignore all changes until we get the DidGetValues message.
- m_hasPendingGetValues = true;
-}
-
-bool StorageAreaMap::prewarm()
-{
- if (m_didPrewarm || m_storageMap)
- return false;
- m_didPrewarm = true;
-
- connect();
- WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::Prewarm(m_storageMapID), 0);
- return true;
-}
-
-void StorageAreaMap::didGetValues(uint64_t storageMapSeed)
-{
- if (m_currentSeed != storageMapSeed)
- return;
-
- ASSERT(m_hasPendingGetValues);
- m_hasPendingGetValues = false;
}
void StorageAreaMap::didSetItem(uint64_t storageMapSeed, const String& key, bool quotaError)
@@ -259,8 +223,8 @@
{
ASSERT(!m_storageMap || m_storageMap->hasOneRef());
- // There's a clear pending or getValues pending we don't want to apply any changes until we get the corresponding DidClear/DidGetValues messages.
- if (m_hasPendingClear || m_hasPendingGetValues)
+ // There is at least one clear pending we don't want to apply any changes until we get the corresponding DidClear messages.
+ if (m_hasPendingClear)
return;
if (!key) {
@@ -305,7 +269,7 @@
applyChange(key, newValue);
}
- if (storageType() == StorageType::Session || storageType() == StorageType::EphemeralLocal)
+ if (storageType() == StorageType::Session)
dispatchSessionStorageEvent(sourceStorageAreaID, key, oldValue, newValue, urlString);
else
dispatchLocalStorageEvent(sourceStorageAreaID, key, oldValue, newValue, urlString);
@@ -318,9 +282,9 @@
void StorageAreaMap::dispatchSessionStorageEvent(uint64_t sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString)
{
- // Namespace IDs for session storage namespaces and ephemeral local storage namespaces are equivalent to web page IDs
+ // Namespace IDs for session storage namespaces are equivalent to web page IDs
// so we can get the right page here.
- WebPage* webPage = WebProcess::singleton().webPage(makeObjectIdentifier<PageIdentifierType>(m_storageNamespaceID));
+ WebPage* webPage = WebProcess::singleton().webPage(makeObjectIdentifier<PageIdentifierType>(m_storageNamespace->storageNamespaceID()));
if (!webPage)
return;
@@ -354,7 +318,8 @@
Vector<RefPtr<Frame>> frames;
- PageGroup& pageGroup = *WebProcess::singleton().webPageGroup(m_storageNamespaceID)->corePageGroup();
+ // Namespace IDs for local storage namespaces are equivalent to web page group IDs.
+ PageGroup& pageGroup = *WebProcess::singleton().webPageGroup(m_storageNamespace->storageNamespaceID())->corePageGroup();
const HashSet<Page*>& pages = pageGroup.pages();
for (HashSet<Page*>::const_iterator it = pages.begin(), end = pages.end(); it != end; ++it) {
for (Frame* frame = &(*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
@@ -381,35 +346,37 @@
void StorageAreaMap::connect()
{
- if (!m_isDisconnected)
+ if (m_storageMapID)
return;
switch (m_storageType) {
case StorageType::Local:
- case StorageType::EphemeralLocal:
case StorageType::TransientLocal:
if (SecurityOrigin* topLevelOrigin = m_storageNamespace->topLevelOrigin())
- WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::CreateTransientLocalStorageMap(m_storageMapID, m_storageNamespace->storageNamespaceID(), topLevelOrigin->data(), m_securityOrigin->data()), 0);
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::StorageManagerSet::ConnectToTransientLocalStorageArea(m_storageNamespace->sessionID(), m_storageNamespace->storageNamespaceID(), topLevelOrigin->data(), m_securityOrigin->data()), Messages::StorageManagerSet::ConnectToTransientLocalStorageArea::Reply(m_storageMapID), 0);
else
- WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::CreateLocalStorageMap(m_storageMapID, m_storageNamespace->storageNamespaceID(), m_securityOrigin->data()), 0);
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::StorageManagerSet::ConnectToLocalStorageArea(m_storageNamespace->sessionID(), m_storageNamespace->storageNamespaceID(), m_securityOrigin->data()), Messages::StorageManagerSet::ConnectToLocalStorageArea::Reply(m_storageMapID), 0);
break;
case StorageType::Session:
- WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::CreateSessionStorageMap(m_storageMapID, m_storageNamespace->storageNamespaceID(), m_securityOrigin->data()), 0);
+ WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::StorageManagerSet::ConnectToSessionStorageArea(m_storageNamespace->sessionID(), m_storageNamespace->storageNamespaceID(), m_securityOrigin->data()), Messages::StorageManagerSet::ConnectToSessionStorageArea::Reply(m_storageMapID), 0);
}
- if (m_storageMap)
- WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::StorageManager::SetItems(m_storageMapID, m_storageMap->items()), 0);
- m_isDisconnected = false;
+ if (m_storageMapID)
+ WebProcess::singleton().registerStorageAreaMap(*this);
}
void StorageAreaMap::disconnect()
{
- m_isDisconnected = true;
- if (m_storageType == StorageType::Session && m_storageMap) {
- m_pendingValueChanges.clear();
- m_hasPendingClear = false;
- } else
- resetValues();
+ if (!m_storageMapID)
+ return;
+
+ resetValues();
+ WebProcess::singleton().unregisterStorageAreaMap(*this);
+
+ if (auto networkProcessConnection = WebProcess::singleton().existingNetworkProcessConnection())
+ networkProcessConnection->connection().send(Messages::StorageManagerSet::DisconnectFromStorageArea(m_storageMapID), 0);
+
+ m_storageMapID = 0;
}
} // namespace WebKit
diff --git a/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.h b/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.h
index fb91bc9..44ad06f 100644
--- a/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.h
+++ b/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.h
@@ -32,6 +32,7 @@
#include <wtf/HashCountedSet.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
+#include <wtf/WeakPtr.h>
namespace WebCore {
class SecurityOrigin;
@@ -43,7 +44,7 @@
class StorageAreaImpl;
class StorageNamespaceImpl;
-class StorageAreaMap : public RefCounted<StorageAreaMap>, private IPC::MessageReceiver {
+class StorageAreaMap : public RefCounted<StorageAreaMap>, private IPC::MessageReceiver, public CanMakeWeakPtr<StorageAreaMap> {
public:
static Ref<StorageAreaMap> create(StorageNamespaceImpl*, Ref<WebCore::SecurityOrigin>&&);
~StorageAreaMap();
@@ -57,7 +58,6 @@
void removeItem(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea, const String& key);
void clear(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea);
bool contains(const String& key);
- bool prewarm();
// IPC::MessageReceiver
void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
@@ -71,7 +71,6 @@
private:
StorageAreaMap(StorageNamespaceImpl*, Ref<WebCore::SecurityOrigin>&&);
- void didGetValues(uint64_t storageMapSeed);
void didSetItem(uint64_t storageMapSeed, const String& key, bool quotaError);
void didRemoveItem(uint64_t storageMapSeed, const String& key);
void didClear(uint64_t storageMapSeed);
@@ -88,12 +87,11 @@
void dispatchSessionStorageEvent(uint64_t sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString);
void dispatchLocalStorageEvent(uint64_t sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString);
- Ref<StorageNamespaceImpl> m_storageNamespace;
+ StorageNamespaceImpl* m_storageNamespace;
uint64_t m_storageMapID;
WebCore::StorageType m_storageType;
- uint64_t m_storageNamespaceID;
unsigned m_quotaInBytes;
Ref<WebCore::SecurityOrigin> m_securityOrigin;
@@ -101,11 +99,7 @@
uint64_t m_currentSeed;
bool m_hasPendingClear;
- bool m_hasPendingGetValues;
HashCountedSet<String> m_pendingValueChanges;
-
- bool m_isDisconnected { true };
- bool m_didPrewarm { false };
};
} // namespace WebKit
diff --git a/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.messages.in b/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.messages.in
index b15904f..7a75d21 100644
--- a/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.messages.in
+++ b/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.messages.in
@@ -21,7 +21,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
messages -> StorageAreaMap {
- DidGetValues(uint64_t storageMapSeed)
DidSetItem(uint64_t storageMapSeed, String key, bool quotaException)
DidRemoveItem(uint64_t storageMapSeed, String key)
DidClear(uint64_t storageMapSeed)
diff --git a/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.cpp b/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.cpp
index f59c79b..7429618 100644
--- a/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.cpp
+++ b/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.cpp
@@ -28,6 +28,7 @@
#include "StorageAreaImpl.h"
#include "StorageAreaMap.h"
+#include "StorageManagerSetMessages.h"
#include "WebPage.h"
#include "WebPageGroupProxy.h"
#include "WebProcess.h"
@@ -40,31 +41,27 @@
namespace WebKit {
using namespace WebCore;
-Ref<StorageNamespaceImpl> StorageNamespaceImpl::createSessionStorageNamespace(uint64_t identifier, unsigned quotaInBytes)
+Ref<StorageNamespaceImpl> StorageNamespaceImpl::createSessionStorageNamespace(uint64_t identifier, unsigned quotaInBytes, PAL::SessionID sessionID)
{
- return adoptRef(*new StorageNamespaceImpl(StorageType::Session, identifier, nullptr, quotaInBytes));
+ return adoptRef(*new StorageNamespaceImpl(StorageType::Session, identifier, nullptr, quotaInBytes, sessionID));
}
-Ref<StorageNamespaceImpl> StorageNamespaceImpl::createEphemeralLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes)
+Ref<StorageNamespaceImpl> StorageNamespaceImpl::createLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes, PAL::SessionID sessionID)
{
- return createLocalStorageNamespace(identifier, quotaInBytes, IsEphemeral::Yes);
+ return adoptRef(*new StorageNamespaceImpl(StorageType::Local, identifier, nullptr, quotaInBytes, sessionID));
}
-Ref<StorageNamespaceImpl> StorageNamespaceImpl::createLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes, IsEphemeral isEphemeral)
+Ref<StorageNamespaceImpl> StorageNamespaceImpl::createTransientLocalStorageNamespace(uint64_t identifier, WebCore::SecurityOrigin& topLevelOrigin, uint64_t quotaInBytes, PAL::SessionID sessionID)
{
- return adoptRef(*new StorageNamespaceImpl(isEphemeral == IsEphemeral::Yes ? StorageType::EphemeralLocal : StorageType::Local, identifier, nullptr, quotaInBytes));
+ return adoptRef(*new StorageNamespaceImpl(StorageType::TransientLocal, identifier, &topLevelOrigin, quotaInBytes, sessionID));
}
-Ref<StorageNamespaceImpl> StorageNamespaceImpl::createTransientLocalStorageNamespace(uint64_t identifier, WebCore::SecurityOrigin& topLevelOrigin, uint64_t quotaInBytes)
-{
- return adoptRef(*new StorageNamespaceImpl(StorageType::TransientLocal, identifier, &topLevelOrigin, quotaInBytes));
-}
-
-StorageNamespaceImpl::StorageNamespaceImpl(WebCore::StorageType storageType, uint64_t storageNamespaceID, WebCore::SecurityOrigin* topLevelOrigin, unsigned quotaInBytes)
+StorageNamespaceImpl::StorageNamespaceImpl(WebCore::StorageType storageType, uint64_t storageNamespaceID, WebCore::SecurityOrigin* topLevelOrigin, unsigned quotaInBytes, PAL::SessionID sessionID)
: m_storageType(storageType)
, m_storageNamespaceID(storageNamespaceID)
, m_topLevelOrigin(topLevelOrigin)
, m_quotaInBytes(quotaInBytes)
+ , m_sessionID(sessionID)
{
}
@@ -77,13 +74,14 @@
m_storageAreaMaps.remove(map.securityOrigin().data());
}
-Ref<StorageArea> StorageNamespaceImpl::storageArea(const SecurityOriginData& securityOrigin)
+Ref<StorageArea> StorageNamespaceImpl::storageArea(const SecurityOriginData& securityOriginData)
{
RefPtr<StorageAreaMap> map;
- auto& slot = m_storageAreaMaps.add(securityOrigin, nullptr).iterator->value;
+ auto securityOrigin = securityOriginData.securityOrigin();
+ auto& slot = m_storageAreaMaps.add(securityOrigin->data(), nullptr).iterator->value;
if (!slot) {
- map = StorageAreaMap::create(this, securityOrigin.securityOrigin());
+ map = StorageAreaMap::create(this, WTFMove(securityOrigin));
slot = map.get();
} else
map = slot;
@@ -95,13 +93,17 @@
{
ASSERT(m_storageNamespaceID);
- if (m_storageType == StorageType::Session)
- return createSessionStorageNamespace(WebPage::fromCorePage(newPage)->pageID().toUInt64(), m_quotaInBytes);
+ if (auto networkProcessConnection = WebProcess::singleton().existingNetworkProcessConnection())
+ networkProcessConnection->connection().send(Messages::StorageManagerSet::CloneSessionStorageNamespace(newPage->sessionID(), m_storageNamespaceID, WebPage::fromCorePage(newPage)->pageID().toUInt64()), 0);
- ASSERT(m_storageType == StorageType::EphemeralLocal);
- auto newNamespace = adoptRef(*new StorageNamespaceImpl(m_storageType, m_storageNamespaceID, m_topLevelOrigin.get(), m_quotaInBytes));
+ return adoptRef(*new StorageNamespaceImpl(m_storageType, WebPage::fromCorePage(newPage)->pageID().toUInt64(), m_topLevelOrigin.get(), m_quotaInBytes, newPage->sessionID()));
+}
- return newNamespace;
+void StorageNamespaceImpl::setSessionIDForTesting(PAL::SessionID sessionID)
+{
+ m_sessionID = sessionID;
+ for (auto storageAreaMap : m_storageAreaMaps.values())
+ storageAreaMap->disconnect();
}
} // namespace WebKit
diff --git a/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.h b/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.h
index ea6d551..5ee89e7 100644
--- a/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.h
+++ b/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.h
@@ -39,12 +39,9 @@
class StorageNamespaceImpl : public WebCore::StorageNamespace {
public:
- static Ref<StorageNamespaceImpl> createSessionStorageNamespace(uint64_t identifier, unsigned quotaInBytes);
- static Ref<StorageNamespaceImpl> createEphemeralLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes);
-
- enum class IsEphemeral : bool { No, Yes };
- static Ref<StorageNamespaceImpl> createLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes, IsEphemeral isEphemeral);
- static Ref<StorageNamespaceImpl> createTransientLocalStorageNamespace(uint64_t identifier, WebCore::SecurityOrigin& topLevelOrigin, uint64_t quotaInBytes);
+ static Ref<StorageNamespaceImpl> createSessionStorageNamespace(uint64_t identifier, unsigned quotaInBytes, PAL::SessionID);
+ static Ref<StorageNamespaceImpl> createLocalStorageNamespace(uint64_t identifier, unsigned quotaInBytes, PAL::SessionID);
+ static Ref<StorageNamespaceImpl> createTransientLocalStorageNamespace(uint64_t identifier, WebCore::SecurityOrigin& topLevelOrigin, uint64_t quotaInBytes, PAL::SessionID);
virtual ~StorageNamespaceImpl();
@@ -52,11 +49,14 @@
uint64_t storageNamespaceID() const { return m_storageNamespaceID; }
WebCore::SecurityOrigin* topLevelOrigin() const { return m_topLevelOrigin.get(); }
unsigned quotaInBytes() const { return m_quotaInBytes; }
+ PAL::SessionID sessionID() const override { return m_sessionID; }
void didDestroyStorageAreaMap(StorageAreaMap&);
+ void setSessionIDForTesting(PAL::SessionID) override;
+
private:
- explicit StorageNamespaceImpl(WebCore::StorageType, uint64_t storageNamespaceID, WebCore::SecurityOrigin* topLevelOrigin, unsigned quotaInBytes);
+ explicit StorageNamespaceImpl(WebCore::StorageType, uint64_t storageNamespaceID, WebCore::SecurityOrigin* topLevelOrigin, unsigned quotaInBytes, PAL::SessionID);
Ref<WebCore::StorageArea> storageArea(const WebCore::SecurityOriginData&) override;
Ref<WebCore::StorageNamespace> copy(WebCore::Page*) override;
@@ -69,7 +69,9 @@
const unsigned m_quotaInBytes;
- HashMap<WebCore::SecurityOriginData, StorageAreaMap*> m_storageAreaMaps;
+ PAL::SessionID m_sessionID;
+
+ HashMap<WebCore::SecurityOriginData, RefPtr<StorageAreaMap>> m_storageAreaMaps;
};
} // namespace WebKit
diff --git a/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.cpp b/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.cpp
index 88a93c5..9e72163 100644
--- a/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.cpp
+++ b/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.cpp
@@ -67,22 +67,17 @@
Ref<WebCore::StorageNamespace> WebStorageNamespaceProvider::createSessionStorageNamespace(Page& page, unsigned quota)
{
- return StorageNamespaceImpl::createSessionStorageNamespace(WebPage::fromCorePage(&page)->pageID().toUInt64(), quota);
+ return StorageNamespaceImpl::createSessionStorageNamespace(WebPage::fromCorePage(&page)->pageID().toUInt64(), quota, page.sessionID());
}
-Ref<WebCore::StorageNamespace> WebStorageNamespaceProvider::createEphemeralLocalStorageNamespace(Page& page, unsigned quota)
+Ref<WebCore::StorageNamespace> WebStorageNamespaceProvider::createLocalStorageNamespace(unsigned quota, PAL::SessionID sessionID)
{
- return StorageNamespaceImpl::createEphemeralLocalStorageNamespace(WebPage::fromCorePage(&page)->pageID().toUInt64(), quota);
+ return StorageNamespaceImpl::createLocalStorageNamespace(m_identifier, quota, sessionID);
}
-Ref<WebCore::StorageNamespace> WebStorageNamespaceProvider::createLocalStorageNamespace(unsigned quota)
+Ref<WebCore::StorageNamespace> WebStorageNamespaceProvider::createTransientLocalStorageNamespace(WebCore::SecurityOrigin& topLevelOrigin, unsigned quota, PAL::SessionID sessionID)
{
- return StorageNamespaceImpl::createLocalStorageNamespace(m_identifier, quota, StorageNamespaceImpl::IsEphemeral::No);
-}
-
-Ref<WebCore::StorageNamespace> WebStorageNamespaceProvider::createTransientLocalStorageNamespace(WebCore::SecurityOrigin& topLevelOrigin, unsigned quota)
-{
- return StorageNamespaceImpl::createTransientLocalStorageNamespace(m_identifier, topLevelOrigin, quota);
+ return StorageNamespaceImpl::createTransientLocalStorageNamespace(m_identifier, topLevelOrigin, quota, sessionID);
}
}
diff --git a/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.h b/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.h
index 3ce6db9..22e42f5 100644
--- a/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.h
+++ b/Source/WebKit/WebProcess/WebStorage/WebStorageNamespaceProvider.h
@@ -38,9 +38,8 @@
explicit WebStorageNamespaceProvider(uint64_t identifier);
Ref<WebCore::StorageNamespace> createSessionStorageNamespace(WebCore::Page&, unsigned quota) override;
- Ref<WebCore::StorageNamespace> createEphemeralLocalStorageNamespace(WebCore::Page&, unsigned quota) override;
- Ref<WebCore::StorageNamespace> createLocalStorageNamespace(unsigned quota) override;
- Ref<WebCore::StorageNamespace> createTransientLocalStorageNamespace(WebCore::SecurityOrigin&, unsigned quota) override;
+ Ref<WebCore::StorageNamespace> createLocalStorageNamespace(unsigned quota, PAL::SessionID) override;
+ Ref<WebCore::StorageNamespace> createTransientLocalStorageNamespace(WebCore::SecurityOrigin&, unsigned quota, PAL::SessionID) override;
const uint64_t m_identifier;
};
diff --git a/Source/WebKitLegacy/ChangeLog b/Source/WebKitLegacy/ChangeLog
index d7bffcb..66e5fa3 100644
--- a/Source/WebKitLegacy/ChangeLog
+++ b/Source/WebKitLegacy/ChangeLog
@@ -1,3 +1,38 @@
+2019-08-15 Sihui Liu <sihui_liu@apple.com>
+
+ Some improvements on web storage
+ https://bugs.webkit.org/show_bug.cgi?id=200373
+
+ Reviewed by Geoffrey Garen.
+
+ Do some clean-up and add support for session change of web storage in layout tests.
+
+ * Storage/StorageAreaImpl.cpp:
+ (WebKit::StorageAreaImpl::sessionChanged):
+ * Storage/StorageAreaImpl.h:
+ (): Deleted.
+
+ * Storage/StorageAreaSync.h: make sure StorageAreaSync is destructed on the main thread, as it can be
+ dereferenced in StorageAreaImpl::sessionChanged and its last reference for final sync could be released on the
+ background thread.
+
+ * Storage/StorageNamespaceImpl.cpp: replace EphemeralLocalStorage with LocalStorage, and store SessionID in
+ StorageNamespace.
+ (WebKit::StorageNamespaceImpl::createSessionStorageNamespace):
+ (WebKit::StorageNamespaceImpl::getOrCreateLocalStorageNamespace):
+ (WebKit::StorageNamespaceImpl::StorageNamespaceImpl):
+ (WebKit::StorageNamespaceImpl::copy):
+ (WebKit::StorageNamespaceImpl::close):
+ (WebKit::StorageNamespaceImpl::setSessionIDForTesting):
+ (WebKit::StorageNamespaceImpl::createEphemeralLocalStorageNamespace): Deleted.
+ * Storage/StorageNamespaceImpl.h:
+ * Storage/WebStorageNamespaceProvider.cpp:
+ (WebKit::WebStorageNamespaceProvider::createSessionStorageNamespace):
+ (WebKit::WebStorageNamespaceProvider::createLocalStorageNamespace):
+ (WebKit::WebStorageNamespaceProvider::createTransientLocalStorageNamespace):
+ (WebKit::WebStorageNamespaceProvider::createEphemeralLocalStorageNamespace): Deleted.
+ * Storage/WebStorageNamespaceProvider.h:
+
2019-08-14 Ryan Haddad <ryanhaddad@apple.com>
Unreviewed, rolling out r248526.
diff --git a/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp b/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp
index 7da5c72..42cc4db 100644
--- a/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp
+++ b/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp
@@ -292,4 +292,22 @@
StorageEventDispatcher::dispatchSessionStorageEvents(key, oldValue, newValue, m_securityOrigin, sourceFrame);
}
+void StorageAreaImpl::sessionChanged(bool isNewSessionPersistent)
+{
+ ASSERT(isMainThread());
+
+ unsigned quota = m_storageMap->quota();
+ m_storageMap = StorageMap::create(quota);
+
+ if (isNewSessionPersistent && !m_storageAreaSync && m_storageSyncManager) {
+ m_storageAreaSync = StorageAreaSync::create(m_storageSyncManager.get(), *this, m_securityOrigin.databaseIdentifier());
+ return;
+ }
+
+ if (!isNewSessionPersistent && m_storageAreaSync) {
+ m_storageAreaSync->scheduleFinalSync();
+ m_storageAreaSync = nullptr;
+ }
+}
+
} // namespace WebCore
diff --git a/Source/WebKitLegacy/Storage/StorageAreaImpl.h b/Source/WebKitLegacy/Storage/StorageAreaImpl.h
index 58fcba0..b20bef9 100644
--- a/Source/WebKitLegacy/Storage/StorageAreaImpl.h
+++ b/Source/WebKitLegacy/Storage/StorageAreaImpl.h
@@ -61,8 +61,6 @@
void decrementAccessCount() override;
void closeDatabaseIfIdle() override;
- const WebCore::SecurityOriginData& securityOrigin() const override { return m_securityOrigin; }
-
Ref<StorageAreaImpl> copy();
void close();
@@ -74,6 +72,8 @@
void sync();
+ void sessionChanged(bool isNewSessionPersistent);
+
private:
StorageAreaImpl(WebCore::StorageType, const WebCore::SecurityOriginData&, RefPtr<WebCore::StorageSyncManager>&&, unsigned quota);
explicit StorageAreaImpl(const StorageAreaImpl&);
diff --git a/Source/WebKitLegacy/Storage/StorageAreaSync.h b/Source/WebKitLegacy/Storage/StorageAreaSync.h
index c008753..109c7cf 100644
--- a/Source/WebKitLegacy/Storage/StorageAreaSync.h
+++ b/Source/WebKitLegacy/Storage/StorageAreaSync.h
@@ -39,7 +39,7 @@
class StorageAreaImpl;
-class StorageAreaSync : public ThreadSafeRefCounted<StorageAreaSync> {
+class StorageAreaSync : public ThreadSafeRefCounted<StorageAreaSync, WTF::DestructionThread::Main> {
public:
static Ref<StorageAreaSync> create(RefPtr<WebCore::StorageSyncManager>&&, Ref<StorageAreaImpl>&&, const String& databaseIdentifier);
~StorageAreaSync();
diff --git a/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp b/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp
index 4a94a1d..737f5c0 100644
--- a/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp
+++ b/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp
@@ -45,17 +45,12 @@
return localStorageNamespaceMap;
}
-Ref<StorageNamespaceImpl> StorageNamespaceImpl::createSessionStorageNamespace(unsigned quota)
+Ref<StorageNamespaceImpl> StorageNamespaceImpl::createSessionStorageNamespace(unsigned quota, PAL::SessionID sessionID)
{
- return adoptRef(*new StorageNamespaceImpl(StorageType::Session, String(), quota));
+ return adoptRef(*new StorageNamespaceImpl(StorageType::Session, String(), quota, sessionID));
}
-Ref<StorageNamespaceImpl> StorageNamespaceImpl::createEphemeralLocalStorageNamespace(unsigned quota)
-{
- return adoptRef(*new StorageNamespaceImpl(StorageType::EphemeralLocal, String(), quota));
-}
-
-Ref<StorageNamespaceImpl> StorageNamespaceImpl::getOrCreateLocalStorageNamespace(const String& databasePath, unsigned quota)
+Ref<StorageNamespaceImpl> StorageNamespaceImpl::getOrCreateLocalStorageNamespace(const String& databasePath, unsigned quota, PAL::SessionID sessionID)
{
ASSERT(!databasePath.isNull());
@@ -63,18 +58,19 @@
if (slot)
return *slot;
- Ref<StorageNamespaceImpl> storageNamespace = adoptRef(*new StorageNamespaceImpl(StorageType::Local, databasePath, quota));
+ Ref<StorageNamespaceImpl> storageNamespace = adoptRef(*new StorageNamespaceImpl(StorageType::Local, databasePath, quota, sessionID));
slot = storageNamespace.ptr();
return storageNamespace;
}
-StorageNamespaceImpl::StorageNamespaceImpl(StorageType storageType, const String& path, unsigned quota)
+StorageNamespaceImpl::StorageNamespaceImpl(StorageType storageType, const String& path, unsigned quota, PAL::SessionID sessionID)
: m_storageType(storageType)
, m_path(path.isolatedCopy())
, m_syncManager(0)
, m_quota(quota)
, m_isShutdown(false)
+ , m_sessionID(sessionID)
{
if (isPersistentLocalStorage(m_storageType) && !m_path.isEmpty())
m_syncManager = StorageSyncManager::create(m_path);
@@ -97,9 +93,9 @@
{
ASSERT(isMainThread());
ASSERT(!m_isShutdown);
- ASSERT(m_storageType == StorageType::Session || m_storageType == StorageType::EphemeralLocal);
+ ASSERT(m_storageType == StorageType::Session);
- auto newNamespace = adoptRef(*new StorageNamespaceImpl(m_storageType, m_path, m_quota));
+ auto newNamespace = adoptRef(*new StorageNamespaceImpl(m_storageType, m_path, m_quota, m_sessionID));
for (auto& iter : m_storageAreaMap)
newNamespace->m_storageAreaMap.set(iter.key, iter.value->copy());
@@ -127,7 +123,7 @@
return;
// If we're not a persistent storage, we shouldn't need to do any work here.
- if (m_storageType == StorageType::Session || m_storageType == StorageType::EphemeralLocal) {
+ if (m_storageType == StorageType::Session) {
ASSERT(!m_syncManager);
return;
}
@@ -176,4 +172,11 @@
it->value->closeDatabaseIfIdle();
}
+void StorageNamespaceImpl::setSessionIDForTesting(PAL::SessionID sessionID)
+{
+ m_sessionID = sessionID;
+ for (auto storageAreaMap : m_storageAreaMap.values())
+ storageAreaMap->sessionChanged(!sessionID.isEphemeral());
+}
+
} // namespace WebCore
diff --git a/Source/WebKitLegacy/Storage/StorageNamespaceImpl.h b/Source/WebKitLegacy/Storage/StorageNamespaceImpl.h
index c88f061..1203252 100644
--- a/Source/WebKitLegacy/Storage/StorageNamespaceImpl.h
+++ b/Source/WebKitLegacy/Storage/StorageNamespaceImpl.h
@@ -28,6 +28,7 @@
#include <WebCore/SecurityOriginData.h>
#include <WebCore/StorageArea.h>
#include <WebCore/StorageNamespace.h>
+#include <pal/SessionID.h>
#include <wtf/HashMap.h>
#include <wtf/RefPtr.h>
#include <wtf/text/WTFString.h>
@@ -38,9 +39,8 @@
class StorageNamespaceImpl : public WebCore::StorageNamespace {
public:
- static Ref<StorageNamespaceImpl> createSessionStorageNamespace(unsigned quota);
- static Ref<StorageNamespaceImpl> createEphemeralLocalStorageNamespace(unsigned quota);
- static Ref<StorageNamespaceImpl> getOrCreateLocalStorageNamespace(const String& databasePath, unsigned quota);
+ static Ref<StorageNamespaceImpl> createSessionStorageNamespace(unsigned quota, PAL::SessionID);
+ static Ref<StorageNamespaceImpl> getOrCreateLocalStorageNamespace(const String& databasePath, unsigned quota, PAL::SessionID);
virtual ~StorageNamespaceImpl();
void close();
@@ -54,8 +54,11 @@
void sync();
void closeIdleLocalStorageDatabases();
+ PAL::SessionID sessionID() const override { return m_sessionID; }
+ void setSessionIDForTesting(PAL::SessionID) override;
+
private:
- StorageNamespaceImpl(WebCore::StorageType, const String& path, unsigned quota);
+ StorageNamespaceImpl(WebCore::StorageType, const String& path, unsigned quota, PAL::SessionID);
Ref<WebCore::StorageArea> storageArea(const WebCore::SecurityOriginData&) override;
Ref<StorageNamespace> copy(WebCore::Page* newPage) override;
@@ -73,6 +76,8 @@
unsigned m_quota;
bool m_isShutdown;
+
+ PAL::SessionID m_sessionID;
};
} // namespace WebCore
diff --git a/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.cpp b/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.cpp
index 8362057..d094691 100644
--- a/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.cpp
+++ b/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.cpp
@@ -26,6 +26,7 @@
#include "WebStorageNamespaceProvider.h"
#include "StorageNamespaceImpl.h"
+#include <WebCore/Page.h>
#include <wtf/NeverDestroyed.h>
using namespace WebCore;
@@ -96,26 +97,21 @@
}
}
-Ref<StorageNamespace> WebStorageNamespaceProvider::createSessionStorageNamespace(Page&, unsigned quota)
+Ref<StorageNamespace> WebStorageNamespaceProvider::createSessionStorageNamespace(Page& page, unsigned quota)
{
- return StorageNamespaceImpl::createSessionStorageNamespace(quota);
+ return StorageNamespaceImpl::createSessionStorageNamespace(quota, page.sessionID());
}
-Ref<StorageNamespace> WebStorageNamespaceProvider::createEphemeralLocalStorageNamespace(Page&, unsigned quota)
+Ref<StorageNamespace> WebStorageNamespaceProvider::createLocalStorageNamespace(unsigned quota, PAL::SessionID sessionID)
{
- return StorageNamespaceImpl::createEphemeralLocalStorageNamespace(quota);
+ return StorageNamespaceImpl::getOrCreateLocalStorageNamespace(m_localStorageDatabasePath, quota, sessionID);
}
-Ref<StorageNamespace> WebStorageNamespaceProvider::createLocalStorageNamespace(unsigned quota)
-{
- return StorageNamespaceImpl::getOrCreateLocalStorageNamespace(m_localStorageDatabasePath, quota);
-}
-
-Ref<StorageNamespace> WebStorageNamespaceProvider::createTransientLocalStorageNamespace(SecurityOrigin&, unsigned quota)
+Ref<StorageNamespace> WebStorageNamespaceProvider::createTransientLocalStorageNamespace(SecurityOrigin&, unsigned quota, PAL::SessionID sessionID)
{
// FIXME: A smarter implementation would create a special namespace type instead of just piggy-backing off
// SessionStorageNamespace here.
- return StorageNamespaceImpl::createSessionStorageNamespace(quota);
+ return StorageNamespaceImpl::createSessionStorageNamespace(quota, sessionID);
}
}
diff --git a/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.h b/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.h
index e589fee..6dbc5c9 100644
--- a/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.h
+++ b/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.h
@@ -50,9 +50,8 @@
explicit WebStorageNamespaceProvider(const String& localStorageDatabasePath);
Ref<WebCore::StorageNamespace> createSessionStorageNamespace(WebCore::Page&, unsigned quota) override;
- Ref<WebCore::StorageNamespace> createEphemeralLocalStorageNamespace(WebCore::Page&, unsigned quota) override;
- Ref<WebCore::StorageNamespace> createLocalStorageNamespace(unsigned quota) override;
- Ref<WebCore::StorageNamespace> createTransientLocalStorageNamespace(WebCore::SecurityOrigin&, unsigned quota) override;
+ Ref<WebCore::StorageNamespace> createLocalStorageNamespace(unsigned quota, PAL::SessionID) override;
+ Ref<WebCore::StorageNamespace> createTransientLocalStorageNamespace(WebCore::SecurityOrigin&, unsigned quota, PAL::SessionID) override;
const String m_localStorageDatabasePath;
};
diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog
index 01d3a59..3ba4950 100644
--- a/Source/WebKitLegacy/mac/ChangeLog
+++ b/Source/WebKitLegacy/mac/ChangeLog
@@ -1,3 +1,13 @@
+2019-08-15 Sihui Liu <sihui_liu@apple.com>
+
+ Some improvements on web storage
+ https://bugs.webkit.org/show_bug.cgi?id=200373
+
+ Reviewed by Geoffrey Garen.
+
+ * WebView/WebView.mm:
+ (-[WebView _preferencesChanged:]): notify storageNamespaceProvider about session change.
+
2019-08-15 Youenn Fablet <youenn@apple.com>
Always create a Document with a valid SessionID
diff --git a/Source/WebKitLegacy/mac/WebView/WebView.mm b/Source/WebKitLegacy/mac/WebView/WebView.mm
index b8d9711..034f0ec 100644
--- a/Source/WebKitLegacy/mac/WebView/WebView.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebView.mm
@@ -2888,6 +2888,7 @@
settings.setLocalStorageEnabled([preferences localStorageEnabled]);
_private->page->enableLegacyPrivateBrowsing([preferences privateBrowsingEnabled]);
+ _private->group->storageNamespaceProvider().enableLegacyPrivateBrowsingForTesting([preferences privateBrowsingEnabled]);
settings.setSansSerifFontFamily([preferences sansSerifFontFamily]);
settings.setSerifFontFamily([preferences serifFontFamily]);
settings.setStandardFontFamily([preferences standardFontFamily]);
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index b165099..e7fbb6a 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,36 @@
+2019-08-15 Sihui Liu <sihui_liu@apple.com>
+
+ Some improvements on web storage
+ https://bugs.webkit.org/show_bug.cgi?id=200373
+
+ Reviewed by Geoffrey Garen.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm:
+ (TEST): update expectation for behavior change.
+
+ * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl: new SPI to synchronously flush localStorage to
+ database file.
+ * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+ (WTR::TestRunner::syncLocalStorage):
+ * WebKitTestRunner/InjectedBundle/TestRunner.h:
+
+ * WebKitTestRunner/TestController.cpp: clear local storage between test runs to make each test isolated.
+ (WTR::TestController::resetStateToConsistentValues):
+ (WTR::StorageVoidCallbackContext::StorageVoidCallbackContext):
+ (WTR::StorageVoidCallback):
+ (WTR::TestController::clearIndexedDatabases):
+ (WTR::TestController::clearLocalStorage):
+ (WTR::TestController::syncLocalStorage):
+ (WTR::RemoveAllIndexedDatabasesCallbackContext::RemoveAllIndexedDatabasesCallbackContext): Deleted. Replaced
+ with StorageVoidCallbackContext for general usage.
+ (WTR::RemoveAllIndexedDatabasesCallback): Deleted. Replaced with StorageVoidCallback.
+ (WTR::TestController::ClearIndexedDatabases): Deleted. Use lowercase for consistent style.
+ * WebKitTestRunner/TestController.h:
+
+ * WebKitTestRunner/TestInvocation.cpp:
+ (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle): add handler for new message
+ SyncLocalStorage.
+
2019-08-15 Jonathan Bedard <jbedard@apple.com>
results.webkit.org: Add content hook to FlaskRequestsResponse
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm
index 11562bb..592bc29 100644
--- a/Tools/TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm
+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/LocalStoragePersistence.mm
@@ -104,9 +104,10 @@
}];
TestWebKitAPI::Util::run(&readyToContinue);
+ // If network process crashes, sessionStorage would be lost.
readyToContinue = false;
[webView evaluateJavaScript:@"window.sessionStorage.getItem('session')" completionHandler:^(id result, NSError *) {
- EXPECT_TRUE([@"storage" isEqualToString:result]);
+ EXPECT_TRUE([result isEqual:NSNull.null]);
readyToContinue = true;
}];
TestWebKitAPI::Util::run(&readyToContinue);
diff --git a/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl b/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
index 158d2f6..4329ec1 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
+++ b/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
@@ -142,6 +142,7 @@
void clearAllDatabases();
void setDatabaseQuota(unsigned long long quota);
DOMString pathToLocalResource(DOMString url);
+ void syncLocalStorage();
attribute double databaseDefaultQuota;
attribute double databaseMaxQuota;
diff --git a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
index 1860f16..527566d 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
@@ -342,6 +342,13 @@
return WKBundleSetDatabaseQuota(InjectedBundle::singleton().bundle(), quota);
}
+void TestRunner::syncLocalStorage()
+{
+ WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("SyncLocalStorage"));
+ WKRetainPtr<WKBooleanRef> messageBody = adoptWK(WKBooleanCreate(true));
+ WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
void TestRunner::clearAllApplicationCaches()
{
WKBundlePageClearApplicationCache(InjectedBundle::singleton().page()->page());
diff --git a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
index 75093d0..f5736ea 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
@@ -159,6 +159,7 @@
void clearAllDatabases();
void setDatabaseQuota(uint64_t);
JSRetainPtr<JSStringRef> pathToLocalResource(JSStringRef);
+ void syncLocalStorage();
// Application Cache
void clearAllApplicationCaches();
diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp
index 8e733be..ea8afb5 100644
--- a/Tools/WebKitTestRunner/TestController.cpp
+++ b/Tools/WebKitTestRunner/TestController.cpp
@@ -939,9 +939,11 @@
auto websiteDataStore = WKContextGetWebsiteDataStore(TestController::singleton().context());
WKWebsiteDataStoreClearAllDeviceOrientationPermissions(websiteDataStore);
- ClearIndexedDatabases();
setIDBPerOriginQuota(50 * MB);
+ clearIndexedDatabases();
+ clearLocalStorage();
+
clearServiceWorkerRegistrations();
clearDOMCaches();
@@ -3069,8 +3071,8 @@
WKContextSetIDBPerOriginQuota(platformContext(), quota);
}
-struct RemoveAllIndexedDatabasesCallbackContext {
- explicit RemoveAllIndexedDatabasesCallbackContext(TestController& controller)
+struct StorageVoidCallbackContext {
+ explicit StorageVoidCallbackContext(TestController& controller)
: testController(controller)
{
}
@@ -3079,18 +3081,37 @@
bool done { false };
};
-static void RemoveAllIndexedDatabasesCallback(void* userData)
+static void StorageVoidCallback(void* userData)
{
- auto* context = static_cast<RemoveAllIndexedDatabasesCallbackContext*>(userData);
+ auto* context = static_cast<StorageVoidCallbackContext*>(userData);
context->done = true;
context->testController.notifyDone();
}
-void TestController::ClearIndexedDatabases()
+void TestController::clearIndexedDatabases()
{
auto websiteDataStore = WKContextGetWebsiteDataStore(platformContext());
- RemoveAllIndexedDatabasesCallbackContext context(*this);
- WKWebsiteDataStoreRemoveAllIndexedDatabases(websiteDataStore, &context, RemoveAllIndexedDatabasesCallback);
+ StorageVoidCallbackContext context(*this);
+ WKWebsiteDataStoreRemoveAllIndexedDatabases(websiteDataStore, &context, StorageVoidCallback);
+ runUntil(context.done, noTimeout);
+}
+
+void TestController::clearLocalStorage()
+{
+ auto websiteDataStore = WKContextGetWebsiteDataStore(platformContext());
+ StorageVoidCallbackContext context(*this);
+ WKWebsiteDataStoreRemoveLocalStorage(websiteDataStore, &context, StorageVoidCallback);
+ runUntil(context.done, noTimeout);
+
+ StorageVoidCallbackContext legacyContext(*this);
+ WKContextClearLegacyPrivateBrowsingLocalStorage(platformContext(), &legacyContext, StorageVoidCallback);
+ runUntil(legacyContext.done, noTimeout);
+}
+
+void TestController::syncLocalStorage()
+{
+ StorageVoidCallbackContext context(*this);
+ WKContextSyncLocalStorage(platformContext(), &context, StorageVoidCallback);
runUntil(context.done, noTimeout);
}
diff --git a/Tools/WebKitTestRunner/TestController.h b/Tools/WebKitTestRunner/TestController.h
index b95cea3..a5ae56e 100644
--- a/Tools/WebKitTestRunner/TestController.h
+++ b/Tools/WebKitTestRunner/TestController.h
@@ -262,7 +262,9 @@
void removeAllSessionCredentials();
- void ClearIndexedDatabases();
+ void clearIndexedDatabases();
+ void clearLocalStorage();
+ void syncLocalStorage();
void clearServiceWorkerRegistrations();
diff --git a/Tools/WebKitTestRunner/TestInvocation.cpp b/Tools/WebKitTestRunner/TestInvocation.cpp
index 28ad1ed..a5aea21 100644
--- a/Tools/WebKitTestRunner/TestInvocation.cpp
+++ b/Tools/WebKitTestRunner/TestInvocation.cpp
@@ -1666,6 +1666,11 @@
return nullptr;
}
+ if (WKStringIsEqualToUTF8CString(messageName, "SyncLocalStorage")) {
+ TestController::singleton().syncLocalStorage();
+ return nullptr;
+ }
+
ASSERT_NOT_REACHED();
return nullptr;
}