Source/WebCore/ChangeLog

 12022-01-17 Sihui Liu <sihui_liu@apple.com>
 2
 3 Make LocalStorage prewarming async
 4 https://bugs.webkit.org/show_bug.cgi?id=235236
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * page/DOMWindow.cpp:
 9 (WebCore::DOMWindow::prewarmLocalStorageIfNecessary):
 10 * page/Frame.cpp:
 11 (WebCore::Frame::didPrewarmLocalStorage): Deleted.
 12 (WebCore::Frame::mayPrewarmLocalStorage const): Deleted.
 13 * page/Frame.h:
 14 * storage/StorageArea.h:
 15 (WebCore::StorageArea::prewarm):
 16 * storage/StorageType.h:
 17
1182022-01-17 Wenson Hsieh <wenson_hsieh@apple.com>
219
320 ImageAnalysisQueue should analyze image elements that are loaded after the call to enqueueAllImages()

Source/WebKit/ChangeLog

 12022-01-17 Sihui Liu <sihui_liu@apple.com>
 2
 3 Make LocalStorage prewarming async
 4 https://bugs.webkit.org/show_bug.cgi?id=235236
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 StorageAreaMap in web process needs to sync with a remote StorageArea in network process before it performs any
 9 Web Storage operation. To connect to remote StorageArea, StorageAreaMap currently sends out two sync messages:
 10 1. ConnectTo*StorageArea: for getting the remote StorageAreaIdentifier
 11 2. getValues: for getting the content of StorageArea
 12 We can merge these two messages into one message: ConnectToStorageAreaSync, and return both remote
 13 StorageAreaIdentifier and content in its reply. This way, web process will not be blocked twice.
 14
 15 To reduce the wait time for connecting to a local StorageArea, we would prewarm LocalStorage by creating its
 16 StorageAreaMap ahead and making it connected (r247555), but we don't actually need StorageAreaMap to be ready
 17 for operation at this time. Therefore, a new async message ConnectToStorageArea is added to be used for
 18 prewarming.
 19
 20 If LocalStorage is used immediately after prewarming, a StorageAreaMap may send ConnectToStorageAreaSync before
 21 receiving the reply of ConnectToStorageArea. In this case, StorageAreaMap would handle ConnectToStorageAreaSync
 22 reply before ConnectToStorageArea reply (due to the priority of sync message), and also before other async
 23 messages (DispatchStorageEvent / ClearCache) that are sent from network process earlier before the sync reply.
 24 To solve this, we use a message identifier to indicate the order of messages sent from network process, so
 25 StorageAreaMap can ignore previous messages when it is already synced with a more recent version of StorageArea.
 26
 27 * NetworkProcess/WebStorage/StorageArea.cpp:
 28 (WebKit::StorageArea::clear):
 29 (WebKit::StorageArea::dispatchEvents const):
 30 * NetworkProcess/storage/LocalStorageManager.cpp:
 31 (WebKit::LocalStorageManager::connectToLocalStorageArea):
 32 (WebKit::LocalStorageManager::connectToTransientLocalStorageArea):
 33 * NetworkProcess/storage/LocalStorageManager.h:
 34 * NetworkProcess/storage/NetworkStorageManager.cpp:
 35 (WebKit::NetworkStorageManager::connectToStorageArea):
 36 (WebKit::NetworkStorageManager::connectToStorageAreaSync):
 37 (WebKit::NetworkStorageManager::connectToLocalStorageArea): Deleted.
 38 (WebKit::NetworkStorageManager::connectToTransientLocalStorageArea): Deleted.
 39 (WebKit::NetworkStorageManager::connectToSessionStorageArea): Deleted.
 40 (WebKit::NetworkStorageManager::getValues): Deleted.
 41 * NetworkProcess/storage/NetworkStorageManager.h:
 42 * NetworkProcess/storage/NetworkStorageManager.messages.in:
 43 * NetworkProcess/storage/SessionStorageManager.cpp:
 44 (WebKit::SessionStorageManager::connectToSessionStorageArea):
 45 * NetworkProcess/storage/SessionStorageManager.h:
 46 * NetworkProcess/storage/StorageAreaBase.cpp:
 47 (WebKit::StorageAreaBase::nextMessageIdentifier):
 48 (WebKit::StorageAreaBase::StorageAreaBase):
 49 (WebKit::StorageAreaBase::addListener):
 50 (WebKit::StorageAreaBase::notifyListenersAboutClear):
 51 (WebKit::StorageAreaBase::dispatchEvents const):
 52 * NetworkProcess/storage/StorageAreaBase.h:
 53 * Scripts/webkit/messages.py:
 54 (types_that_cannot_be_forward_declared):
 55 (headers_for_type):
 56 * WebKit.xcodeproj/project.pbxproj:
 57 * WebProcess/Network/NetworkProcessConnection.cpp:
 58 (WebKit::NetworkProcessConnection::didReceiveMessage):
 59 * WebProcess/WebProcess.cpp:
 60 (WebKit::WebProcess::networkProcessConnectionClosed):
 61 (WebKit::WebProcess::registerStorageAreaMap):
 62 (WebKit::WebProcess::unregisterStorageAreaMap):
 63 (WebKit::WebProcess::storageAreaMap const):
 64 * WebProcess/WebProcess.h:
 65 * WebProcess/WebStorage/StorageAreaImpl.cpp:
 66 (WebKit::StorageAreaImpl::prewarm):
 67 (WebKit::StorageAreaImpl::incrementAccessCount): Deleted.
 68 (WebKit::StorageAreaImpl::decrementAccessCount): Deleted.
 69 (WebKit::StorageAreaImpl::closeDatabaseIfIdle): Deleted.
 70 * WebProcess/WebStorage/StorageAreaImpl.h:
 71 * WebProcess/WebStorage/StorageAreaMap.cpp:
 72 (WebKit::StorageAreaMap::StorageAreaMap):
 73 (WebKit::StorageAreaMap::~StorageAreaMap):
 74 (WebKit::StorageAreaMap::setItem):
 75 (WebKit::StorageAreaMap::removeItem):
 76 (WebKit::StorageAreaMap::clear):
 77 (WebKit::StorageAreaMap::ensureMap):
 78 (WebKit::StorageAreaMap::dispatchStorageEvent):
 79 (WebKit::StorageAreaMap::clearCache):
 80 (WebKit::StorageAreaMap::sendConnectMessage):
 81 (WebKit::StorageAreaMap::connectSync):
 82 (WebKit::StorageAreaMap::connect):
 83 (WebKit::StorageAreaMap::didConnect):
 84 (WebKit::StorageAreaMap::disconnect):
 85 * WebProcess/WebStorage/StorageAreaMap.h:
 86 * WebProcess/WebStorage/StorageAreaMap.messages.in:
 87 * WebProcess/WebStorage/StorageAreaMapIdentifier.h: Added.
 88
1892022-01-17 Youenn Fablet <youenn@apple.com>
290
391 Make ServiceWorkerClient.id a UUID instead of a string derived from a ScriptExecutionContextIdentifier

Source/WebCore/page/DOMWindow.cpp

@@void DOMWindow::prewarmLocalStorageIfNecessary()
413413 if (!page || page->usesEphemeralSession())
414414 return;
415415
416  if (!page->mainFrame().mayPrewarmLocalStorage())
417  return;
418 
419416 // This eagerly constructs the StorageArea, which will load items from disk.
420417 auto localStorageResult = this->localStorage();
421418 if (localStorageResult.hasException())

@@void DOMWindow::prewarmLocalStorageIfNecessary()
425422 if (!localStorage)
426423 return;
427424
428  page->mainFrame().didPrewarmLocalStorage();
 425 localStorage->area().prewarm();
429426}
430427
431428DOMWindow::~DOMWindow()

Source/WebCore/page/Frame.cpp

@@void Frame::dropChildren()
10571057 tree().removeChild(*child);
10581058}
10591059
1060 void Frame::didPrewarmLocalStorage()
1061 {
1062  ASSERT(isMainFrame());
1063  ASSERT(m_localStoragePrewarmingCount < maxlocalStoragePrewarmingCount);
1064  ++m_localStoragePrewarmingCount;
1065 }
1066 
1067 bool Frame::mayPrewarmLocalStorage() const
1068 {
1069  ASSERT(isMainFrame());
1070  return m_localStoragePrewarmingCount < maxlocalStoragePrewarmingCount;
1071 }
1072 
10731060FloatSize Frame::screenSize() const
10741061{
10751062 if (!m_overrideScreenSize.isEmpty())

Source/WebCore/page/Frame.h

@@public:
291291 void resumeActiveDOMObjectsAndAnimations();
292292 bool activeDOMObjectsAndAnimationsSuspended() const { return m_activeDOMObjectsAndAnimationsSuspendedCount > 0; }
293293
294  void didPrewarmLocalStorage();
295  bool mayPrewarmLocalStorage() const;
296 
297294 enum class InvalidateContentEventRegionsReason { Layout, EventHandlerChange };
298295 void invalidateContentEventRegionsIfNeeded(InvalidateContentEventRegionsReason);
299296

@@private:
361358 unsigned m_navigationDisableCount { 0 };
362359 unsigned m_selfOnlyRefCount { 0 };
363360 bool m_hasHadUserInteraction { false };
364  unsigned m_localStoragePrewarmingCount { 0 };
365361
366362 FloatSize m_overrideScreenSize;
367363

Source/WebCore/storage/StorageArea.h

@@public:
5858 virtual void incrementAccessCount() { }
5959 virtual void decrementAccessCount() { }
6060 virtual void closeDatabaseIfIdle() { }
 61 virtual void prewarm() { }
6162};
6263
6364} // namespace WebCore

Source/WebCore/storage/StorageType.h

2525
2626#pragma once
2727
 28#include <wtf/EnumTraits.h>
 29
2830namespace WebCore {
2931
3032enum class StorageType : uint8_t {

@@inline bool isPersistentLocalStorage(StorageType storageType)
4446}
4547
4648} // namespace WebCore
 49
 50namespace WTF {
 51
 52template<> struct EnumTraits<WebCore::StorageType> {
 53 using values = EnumValues<
 54 WebCore::StorageType,
 55 WebCore::StorageType::Session,
 56 WebCore::StorageType::Local,
 57 WebCore::StorageType::TransientLocal
 58 >;
 59};
 60
 61} // namespace WTF

Source/WebKit/NetworkProcess/WebStorage/StorageArea.cpp

@@void StorageArea::clear()
165165 }
166166
167167 for (auto& listenerUniqueID : m_eventListeners)
168  IPC::Connection::send(listenerUniqueID, Messages::StorageAreaMap::ClearCache(), m_identifier.toUInt64());
 168 IPC::Connection::send(listenerUniqueID, Messages::StorageAreaMap::ClearCache(0), m_identifier.toUInt64());
169169}
170170
171171LocalStorageDatabase& StorageArea::ensureDatabase() const

@@void StorageArea::dispatchEvents(IPC::Connection::UniqueID sourceConnection, Sto
188188 ASSERT(storageAreaImplID);
189189 for (auto& listenerUniqueID : m_eventListeners) {
190190 auto optionalStorageAreaImplID = listenerUniqueID == sourceConnection ? std::make_optional(storageAreaImplID) : std::nullopt;
191  IPC::Connection::send(listenerUniqueID, Messages::StorageAreaMap::DispatchStorageEvent(optionalStorageAreaImplID, key, oldValue, newValue, urlString), m_identifier.toUInt64());
 191 IPC::Connection::send(listenerUniqueID, Messages::StorageAreaMap::DispatchStorageEvent(optionalStorageAreaImplID, key, oldValue, newValue, urlString, 0), m_identifier.toUInt64());
192192 }
193193}
194194

Source/WebKit/NetworkProcess/storage/LocalStorageManager.cpp

@@void LocalStorageManager::connectionClosedForTransientStorageArea(IPC::Connectio
165165 m_transientStorageArea = nullptr;
166166}
167167
168 StorageAreaIdentifier LocalStorageManager::connectToLocalStorageArea(IPC::Connection::UniqueID connection, const WebCore::ClientOrigin& origin, Ref<WorkQueue>&& workQueue)
 168StorageAreaIdentifier LocalStorageManager::connectToLocalStorageArea(IPC::Connection::UniqueID connection, StorageAreaMapIdentifier sourceIdentifier, const WebCore::ClientOrigin& origin, Ref<WorkQueue>&& workQueue)
169169{
170170 if (!m_localStorageArea) {
171171 if (!m_path.isEmpty())

@@StorageAreaIdentifier LocalStorageManager::connectToLocalStorageArea(IPC::Connec
177177 }
178178
179179 ASSERT(m_path.isEmpty() || m_localStorageArea->type() == StorageAreaBase::Type::SQLite);
180  m_localStorageArea->addListener(connection);
 180 m_localStorageArea->addListener(connection, sourceIdentifier);
181181 return m_localStorageArea->identifier();
182182}
183183
184 StorageAreaIdentifier LocalStorageManager::connectToTransientLocalStorageArea(IPC::Connection::UniqueID connection, const WebCore::ClientOrigin& origin)
 184StorageAreaIdentifier LocalStorageManager::connectToTransientLocalStorageArea(IPC::Connection::UniqueID connection, StorageAreaMapIdentifier sourceIdentifier, const WebCore::ClientOrigin& origin)
185185{
186186 if (!m_transientStorageArea) {
187187 m_transientStorageArea = makeUnique<MemoryStorageArea>(origin, StorageAreaBase::StorageType::Local);

@@StorageAreaIdentifier LocalStorageManager::connectToTransientLocalStorageArea(IP
189189 }
190190
191191 ASSERT(m_transientStorageArea->type() == StorageAreaBase::Type::Memory);
192  m_transientStorageArea->addListener(connection);
 192 m_transientStorageArea->addListener(connection, sourceIdentifier);
193193 return m_transientStorageArea->identifier();
194194}
195195

Source/WebKit/NetworkProcess/storage/LocalStorageManager.h

2727
2828#include "Connection.h"
2929#include "StorageAreaIdentifier.h"
 30#include "StorageAreaMapIdentifier.h"
3031#include <wtf/WorkQueue.h>
3132
3233namespace WebCore {

@@public:
5657 void syncLocalStorage();
5758 void connectionClosed(IPC::Connection::UniqueID);
5859
59  StorageAreaIdentifier connectToLocalStorageArea(IPC::Connection::UniqueID, const WebCore::ClientOrigin&, Ref<WorkQueue>&&);
60  StorageAreaIdentifier connectToTransientLocalStorageArea(IPC::Connection::UniqueID, const WebCore::ClientOrigin&);
 60 StorageAreaIdentifier connectToLocalStorageArea(IPC::Connection::UniqueID, StorageAreaMapIdentifier, const WebCore::ClientOrigin&, Ref<WorkQueue>&&);
 61 StorageAreaIdentifier connectToTransientLocalStorageArea(IPC::Connection::UniqueID, StorageAreaMapIdentifier, const WebCore::ClientOrigin&);
6162 void disconnectFromStorageArea(IPC::Connection::UniqueID, StorageAreaIdentifier);
6263
6364private:

Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp

@@void NetworkStorageManager::syncLocalStorage(CompletionHandler<void()>&& complet
625625 });
626626}
627627
628 void NetworkStorageManager::connectToLocalStorageArea(IPC::Connection& connection, StorageNamespaceIdentifier, WebCore::SecurityOriginData&& topOrigin, CompletionHandler<void(StorageAreaIdentifier)>&& completionHandler)
 628void NetworkStorageManager::connectToStorageArea(IPC::Connection& connection, WebCore::StorageType type, StorageAreaMapIdentifier sourceIdentifier, StorageNamespaceIdentifier namespaceIdentifier, const WebCore::ClientOrigin& origin, CompletionHandler<void(StorageAreaIdentifier, HashMap<String, String>, uint64_t)>&& completionHandler)
629629{
630630 ASSERT(!RunLoop::isMain());
631631
632  WebCore::ClientOrigin origin = { topOrigin, topOrigin };
633  completionHandler(localOriginStorageManager(origin).localStorageManager(*m_storageAreaRegistry).connectToLocalStorageArea(connection.uniqueID(), origin, m_queue.copyRef()));
634 }
 632 auto connectionIdentifier = connection.uniqueID();
 633 auto& originStorageManager = localOriginStorageManager(origin);
 634 StorageAreaIdentifier resultIdentifier;
 635 switch (type) {
 636 case WebCore::StorageType::Local:
 637 resultIdentifier = originStorageManager.localStorageManager(*m_storageAreaRegistry).connectToLocalStorageArea(connectionIdentifier, sourceIdentifier, origin, m_queue.copyRef());
 638 break;
 639 case WebCore::StorageType::TransientLocal:
 640 resultIdentifier = originStorageManager.localStorageManager(*m_storageAreaRegistry).connectToTransientLocalStorageArea(connectionIdentifier, sourceIdentifier, origin);
 641 break;
 642 case WebCore::StorageType::Session:
 643 resultIdentifier = originStorageManager.sessionStorageManager(*m_storageAreaRegistry).connectToSessionStorageArea(connectionIdentifier, sourceIdentifier, origin, namespaceIdentifier);
 644 }
635645
636 void NetworkStorageManager::connectToTransientLocalStorageArea(IPC::Connection& connection, StorageNamespaceIdentifier, WebCore::SecurityOriginData&& topOrigin, WebCore::SecurityOriginData&& openingOrigin, CompletionHandler<void(StorageAreaIdentifier)>&& completionHandler)
637 {
638  WebCore::ClientOrigin origin = { topOrigin, openingOrigin };
639  completionHandler(localOriginStorageManager(origin).localStorageManager(*m_storageAreaRegistry).connectToTransientLocalStorageArea(connection.uniqueID(), origin));
 646 if (auto storageArea = m_storageAreaRegistry->getStorageArea(resultIdentifier))
 647 return completionHandler(resultIdentifier, storageArea->allItems(), StorageAreaBase::nextMessageIdentifier());
 648
 649 return completionHandler(resultIdentifier, HashMap<String, String> { }, StorageAreaBase::nextMessageIdentifier());
640650}
641651
642 void NetworkStorageManager::connectToSessionStorageArea(IPC::Connection& connection, StorageNamespaceIdentifier identifier, WebCore::SecurityOriginData&& topOrigin, CompletionHandler<void(StorageAreaIdentifier)>&& completionHandler)
 652void NetworkStorageManager::connectToStorageAreaSync(IPC::Connection& connection, WebCore::StorageType type, StorageAreaMapIdentifier sourceIdentifier, StorageNamespaceIdentifier namespaceIdentifier, const WebCore::ClientOrigin& origin, CompletionHandler<void(StorageAreaIdentifier, HashMap<String, String>, uint64_t)>&& completionHandler)
643653{
644  WebCore::ClientOrigin origin = { topOrigin, topOrigin };
645  completionHandler(localOriginStorageManager(origin).sessionStorageManager(*m_storageAreaRegistry).connectToSessionStorageArea(connection.uniqueID(), origin, identifier));
 654 connectToStorageArea(connection, type, sourceIdentifier, namespaceIdentifier, origin, WTFMove(completionHandler));
646655}
647656
648657void NetworkStorageManager::disconnectFromStorageArea(IPC::Connection& connection, StorageAreaIdentifier identifier)

@@void NetworkStorageManager::cloneSessionStorageNamespace(IPC::Connection& connec
669678 }
670679}
671680
672 void NetworkStorageManager::getValues(StorageAreaIdentifier identifier, CompletionHandler<void(const HashMap<String, String>&)>&& completionHandler)
673 {
674  ASSERT(!RunLoop::isMain());
675 
676  if (auto storageArea = m_storageAreaRegistry->getStorageArea(identifier))
677  return completionHandler(storageArea->allItems());
678 
679  return completionHandler({ });
680 }
681 
682681void NetworkStorageManager::setItem(IPC::Connection& connection, StorageAreaIdentifier identifier, StorageAreaImplIdentifier implIdentifier, uint64_t storageMapSeed, String&& key, String&& value, String&& urlString)
683682{
684683 ASSERT(!RunLoop::isMain());

Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h

3030#include "OriginStorageManager.h"
3131#include "StorageAreaIdentifier.h"
3232#include "StorageAreaImplIdentifier.h"
 33#include "StorageAreaMapIdentifier.h"
3334#include "StorageNamespaceIdentifier.h"
3435#include "WebsiteData.h"
3536#include <WebCore/ClientOrigin.h>

@@class SharedFileHandle;
4445
4546namespace WebCore {
4647struct ClientOrigin;
 48enum class StorageType : uint8_t;
4749}
4850
4951namespace WebKit {

@@private:
108110 void getHandle(IPC::Connection&, WebCore::FileSystemHandleIdentifier, String&& name, CompletionHandler<void(Expected<std::pair<WebCore::FileSystemHandleIdentifier, bool>, FileSystemStorageError>)>&&);
109111
110112 // Message handlers for WebStorage.
111  void connectToLocalStorageArea(IPC::Connection&, StorageNamespaceIdentifier, WebCore::SecurityOriginData&&, CompletionHandler<void(StorageAreaIdentifier)>&&);
112  void connectToTransientLocalStorageArea(IPC::Connection&, StorageNamespaceIdentifier, WebCore::SecurityOriginData&&, WebCore::SecurityOriginData&&, CompletionHandler<void(StorageAreaIdentifier)>&&);
113  void connectToSessionStorageArea(IPC::Connection&, StorageNamespaceIdentifier, WebCore::SecurityOriginData&&, CompletionHandler<void(StorageAreaIdentifier)>&&);
 113 void connectToStorageArea(IPC::Connection&, WebCore::StorageType, StorageAreaMapIdentifier, StorageNamespaceIdentifier, const WebCore::ClientOrigin&, CompletionHandler<void(StorageAreaIdentifier, HashMap<String, String>, uint64_t)>&&);
 114 void connectToStorageAreaSync(IPC::Connection&, WebCore::StorageType, StorageAreaMapIdentifier, StorageNamespaceIdentifier, const WebCore::ClientOrigin&, CompletionHandler<void(StorageAreaIdentifier, HashMap<String, String>, uint64_t)>&&);
114115 void disconnectFromStorageArea(IPC::Connection&, StorageAreaIdentifier);
115116 void cloneSessionStorageNamespace(IPC::Connection&, StorageNamespaceIdentifier, StorageNamespaceIdentifier);
116  void getValues(StorageAreaIdentifier, CompletionHandler<void(const HashMap<String, String>&)>&&);
117117 void setItem(IPC::Connection&, StorageAreaIdentifier, StorageAreaImplIdentifier, uint64_t seed, String&& key, String&& value, String&& urlString);
118118 void removeItem(IPC::Connection&, StorageAreaIdentifier, StorageAreaImplIdentifier, uint64_t seed, String&& key, String&& urlString);
119119 void clear(IPC::Connection&, StorageAreaIdentifier, StorageAreaImplIdentifier, uint64_t seed, String&& urlString);

Source/WebKit/NetworkProcess/storage/NetworkStorageManager.messages.in

4040 GetHandleNames(WebCore::FileSystemHandleIdentifier identifier) -> (Expected<Vector<String>, WebKit::FileSystemStorageError> result) Async
4141 GetHandle(WebCore::FileSystemHandleIdentifier identifier, String name) -> (Expected<std::pair<WebCore::FileSystemHandleIdentifier, bool>, WebKit::FileSystemStorageError> result) Async WantsConnection
4242
43  ConnectToLocalStorageArea(WebKit::StorageNamespaceIdentifier storageNamespaceID, struct WebCore::SecurityOriginData securityOriginData) -> (WebKit::StorageAreaIdentifier identifier) Synchronous WantsConnection
44  ConnectToTransientLocalStorageArea(WebKit::StorageNamespaceIdentifier storageNamespaceID, struct WebCore::SecurityOriginData topLevelSecurityOriginData, struct WebCore::SecurityOriginData securityOriginData) -> (WebKit::StorageAreaIdentifier identifier) Synchronous WantsConnection
45  ConnectToSessionStorageArea(WebKit::StorageNamespaceIdentifier storageNamespaceID, struct WebCore::SecurityOriginData securityOriginData) -> (WebKit::StorageAreaIdentifier identifier) Synchronous WantsConnection
 43 ConnectToStorageArea(WebCore::StorageType type, WebKit::StorageAreaMapIdentifier sourceIdentifier, WebKit::StorageNamespaceIdentifier namespaceIdentifier, struct WebCore::ClientOrigin origin) -> (WebKit::StorageAreaIdentifier identifier, HashMap<String, String> items, uint64_t messageIdentifier) Async WantsConnection
 44 ConnectToStorageAreaSync(WebCore::StorageType type, WebKit::StorageAreaMapIdentifier sourceIdentifier, WebKit::StorageNamespaceIdentifier namespaceIdentifier, struct WebCore::ClientOrigin origin) -> (WebKit::StorageAreaIdentifier identifier, HashMap<String, String> items, uint64_t messageIdentifier) Synchronous WantsConnection
4645 DisconnectFromStorageArea(WebKit::StorageAreaIdentifier identifier) WantsConnection
4746 CloneSessionStorageNamespace(WebKit::StorageNamespaceIdentifier fromStorageNamespaceID, WebKit::StorageNamespaceIdentifier toStorageNamespaceID) WantsConnection
48  GetValues(WebKit::StorageAreaIdentifier identifier) -> (HashMap<String, String> values) Synchronous
4947 SetItem(WebKit::StorageAreaIdentifier identifier, WebKit::StorageAreaImplIdentifier implIdentifier, uint64_t storageMapSeed, String key, String value, String urlString) WantsConnection
5048 RemoveItem(WebKit::StorageAreaIdentifier identifier, WebKit::StorageAreaImplIdentifier implIdentifier, uint64_t storageMapSeed, String key, String urlString) WantsConnection
5149 Clear(WebKit::StorageAreaIdentifier identifier, WebKit::StorageAreaImplIdentifier implIdentifier, uint64_t storageMapSeed, String urlString) WantsConnection

Source/WebKit/NetworkProcess/storage/SessionStorageManager.cpp

@@StorageAreaIdentifier SessionStorageManager::addStorageArea(std::unique_ptr<Memo
7272 return identifier;
7373}
7474
75 StorageAreaIdentifier SessionStorageManager::connectToSessionStorageArea(IPC::Connection::UniqueID connection, const WebCore::ClientOrigin& origin, StorageNamespaceIdentifier namespaceIdentifier)
 75StorageAreaIdentifier SessionStorageManager::connectToSessionStorageArea(IPC::Connection::UniqueID connection, StorageAreaMapIdentifier sourceIdentifier, const WebCore::ClientOrigin& origin, StorageNamespaceIdentifier namespaceIdentifier)
7676{
7777 auto identifier = m_storageAreasByNamespace.get(namespaceIdentifier);
7878 if (!identifier.isValid()) {

@@StorageAreaIdentifier SessionStorageManager::connectToSessionStorageArea(IPC::Co
8484 if (!storageArea)
8585 return StorageAreaIdentifier { };
8686
87  storageArea->addListener(connection);
 87 storageArea->addListener(connection, sourceIdentifier);
 88
8889 return identifier;
8990}
9091

Source/WebKit/NetworkProcess/storage/SessionStorageManager.h

2727
2828#include "Connection.h"
2929#include "StorageAreaIdentifier.h"
 30#include "StorageAreaMapIdentifier.h"
3031#include "StorageNamespaceIdentifier.h"
3132
3233namespace WebCore {

@@public:
4748 void clearData();
4849 void connectionClosed(IPC::Connection::UniqueID);
4950
50  StorageAreaIdentifier connectToSessionStorageArea(IPC::Connection::UniqueID, const WebCore::ClientOrigin&, StorageNamespaceIdentifier);
 51 StorageAreaIdentifier connectToSessionStorageArea(IPC::Connection::UniqueID, StorageAreaMapIdentifier, const WebCore::ClientOrigin&, StorageNamespaceIdentifier);
5152 void disconnectFromStorageArea(IPC::Connection::UniqueID, StorageAreaIdentifier);
5253 void cloneStorageArea(IPC::Connection::UniqueID, StorageNamespaceIdentifier, StorageNamespaceIdentifier);
5354

Source/WebKit/NetworkProcess/storage/StorageAreaBase.cpp

3030
3131namespace WebKit {
3232
 33uint64_t StorageAreaBase::nextMessageIdentifier()
 34{
 35 static std::atomic<uint64_t> currenIdentifier(0);
 36 return ++currenIdentifier;
 37}
 38
3339StorageAreaBase::StorageAreaBase(unsigned quota, const WebCore::ClientOrigin& origin)
34  : m_identifier(StorageAreaIdentifier::generate())
 40 : m_identifier(StorageAreaIdentifier::generateThreadSafe())
3541 , m_quota(quota)
3642 , m_origin(origin)
3743{

@@StorageAreaBase::StorageAreaBase(unsigned quota, const WebCore::ClientOrigin& or
3945
4046StorageAreaBase::~StorageAreaBase() = default;
4147
42 void StorageAreaBase::addListener(IPC::Connection::UniqueID connection)
 48void StorageAreaBase::addListener(IPC::Connection::UniqueID connection, StorageAreaMapIdentifier identifier)
4349{
44  ASSERT(!m_listeners.contains(connection));
 50 ASSERT(!m_listeners.contains(connection) || m_listeners.get(connection) == identifier);
4551
46  m_listeners.add(connection);
 52 m_listeners.set(connection, identifier);
4753}
4854
4955void StorageAreaBase::removeListener(IPC::Connection::UniqueID connection)

@@bool StorageAreaBase::hasListeners() const
5864
5965void StorageAreaBase::notifyListenersAboutClear()
6066{
61  for (auto& connection : m_listeners)
62  IPC::Connection::send(connection, Messages::StorageAreaMap::ClearCache(), m_identifier.toUInt64());
 67 for (auto& [connection, identifier] : m_listeners)
 68 IPC::Connection::send(connection, Messages::StorageAreaMap::ClearCache(StorageAreaBase::nextMessageIdentifier()), identifier.toUInt64());
6369}
6470
6571void StorageAreaBase::dispatchEvents(IPC::Connection::UniqueID sourceConnection, StorageAreaImplIdentifier sourceImplIdentifier, const String& key, const String& oldValue, const String& newValue, const String& urlString) const
6672{
6773 ASSERT(sourceImplIdentifier);
6874
69  for (auto& connection : m_listeners) {
 75 for (auto& [connection, identifier] : m_listeners) {
7076 std::optional<StorageAreaImplIdentifier> implIdentifier;
7177 if (connection == sourceConnection)
7278 implIdentifier = sourceImplIdentifier;
73  IPC::Connection::send(connection, Messages::StorageAreaMap::DispatchStorageEvent(implIdentifier, key, oldValue, newValue, urlString), m_identifier.toUInt64());
 79 IPC::Connection::send(connection, Messages::StorageAreaMap::DispatchStorageEvent(implIdentifier, key, oldValue, newValue, urlString, StorageAreaBase::nextMessageIdentifier()), identifier.toUInt64());
7480 }
7581}
7682

Source/WebKit/NetworkProcess/storage/StorageAreaBase.h

2828#include "Connection.h"
2929#include "StorageAreaIdentifier.h"
3030#include "StorageAreaImplIdentifier.h"
 31#include "StorageAreaMapIdentifier.h"
3132#include <WebCore/ClientOrigin.h>
3233#include <wtf/WeakPtr.h>
3334

@@class StorageAreaBase : public CanMakeWeakPtr<StorageAreaBase> {
4748 WTF_MAKE_NONCOPYABLE(StorageAreaBase);
4849 WTF_MAKE_FAST_ALLOCATED;
4950public:
 51 static uint64_t nextMessageIdentifier();
5052 virtual ~StorageAreaBase();
5153
5254 enum class Type : bool { SQLite, Memory };

@@public:
5961 StorageAreaIdentifier identifier() const { return m_identifier; }
6062 WebCore::ClientOrigin origin() const { return m_origin; }
6163 unsigned quota() const { return m_quota; }
62  void addListener(IPC::Connection::UniqueID);
 64 void addListener(IPC::Connection::UniqueID, StorageAreaMapIdentifier);
6365 void removeListener(IPC::Connection::UniqueID);
6466 bool hasListeners() const;
6567 void notifyListenersAboutClear();

@@private:
7779 StorageAreaIdentifier m_identifier;
7880 unsigned m_quota;
7981 WebCore::ClientOrigin m_origin;
80  HashSet<IPC::Connection::UniqueID> m_listeners;
 82 HashMap<IPC::Connection::UniqueID, StorageAreaMapIdentifier> m_listeners;
8183};
8284
8385} // namespace WebKit

Source/WebKit/Scripts/webkit/messages.py

@@def types_that_cannot_be_forward_declared():
305305 'WebCore::SleepDisablerIdentifier',
306306 'WebCore::SourceBufferAppendMode',
307307 'WebCore::SpeechRecognitionConnectionClientIdentifier',
 308 'WebCore::StorageType',
308309 'WebCore::UserMediaRequestIdentifier',
309310 'WebCore::WebLockIdentifier',
310311 'WebCore::WebSocketIdentifier',

@@def types_that_cannot_be_forward_declared():
347348 'WebKit::SampleBufferDisplayLayerIdentifier',
348349 'WebKit::StorageAreaIdentifier',
349350 'WebKit::StorageAreaImplIdentifier',
 351 'WebKit::StorageAreaMapIdentifier',
350352 'WebKit::StorageNamespaceIdentifier',
351353 'WebKit::TapIdentifier',
352354 'WebKit::TextCheckerRequestID',

Source/WebKit/WebKit.xcodeproj/project.pbxproj

14571457 93AB9B4E257567E20098B10E /* SpeechRecognitionRemoteRealtimeMediaSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 93AB9B422574928C0098B10E /* SpeechRecognitionRemoteRealtimeMediaSource.h */; };
14581458 93AB9B552575A2760098B10E /* SpeechRecognitionRealtimeMediaSourceManagerMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AB9B4F257589110098B10E /* SpeechRecognitionRealtimeMediaSourceManagerMessageReceiver.cpp */; };
14591459 93AB9B562575A28B0098B10E /* SpeechRecognitionRemoteRealtimeMediaSourceManagerMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AB9B51257589110098B10E /* SpeechRecognitionRemoteRealtimeMediaSourceManagerMessageReceiver.cpp */; };
 1460 93AEC161278F8CD30066666F /* StorageAreaMapIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 93AEC160278F8CD20066666F /* StorageAreaMapIdentifier.h */; };
14601461 93B0A67526D5ADCF00AA21E4 /* WebPermissionController.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B0A67426D5A72E00AA21E4 /* WebPermissionController.h */; };
14611462 93B2614D227D149E00B97A76 /* StorageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B26149227D147200B97A76 /* StorageManager.h */; };
14621463 93B2614E227D14B100B97A76 /* LocalStorageDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B26145227D147000B97A76 /* LocalStorageDatabase.h */; };

53055306 93AB9B52257589120098B10E /* SpeechRecognitionRemoteRealtimeMediaSourceManagerMessagesReplies.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpeechRecognitionRemoteRealtimeMediaSourceManagerMessagesReplies.h; sourceTree = "<group>"; };
53065307 93AB9B53257589120098B10E /* SpeechRecognitionRemoteRealtimeMediaSourceManagerMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpeechRecognitionRemoteRealtimeMediaSourceManagerMessages.h; sourceTree = "<group>"; };
53075308 93AB9B54257589120098B10E /* SpeechRecognitionRealtimeMediaSourceManagerMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpeechRecognitionRealtimeMediaSourceManagerMessages.h; sourceTree = "<group>"; };
 5309 93AEC160278F8CD20066666F /* StorageAreaMapIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageAreaMapIdentifier.h; sourceTree = "<group>"; };
53085310 93B0A67326D5A72E00AA21E4 /* WebPermissionController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebPermissionController.cpp; sourceTree = "<group>"; };
53095311 93B0A67426D5A72E00AA21E4 /* WebPermissionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPermissionController.h; sourceTree = "<group>"; };
53105312 93B26145227D147000B97A76 /* LocalStorageDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalStorageDatabase.h; sourceTree = "<group>"; };

70617063 1ACECD2217162DB1001FC9EF /* StorageAreaMap.cpp */,
70627064 1ACECD2317162DB1001FC9EF /* StorageAreaMap.h */,
70637065 1A334DEA16DE8B68006A8E38 /* StorageAreaMap.messages.in */,
 7066 93AEC160278F8CD20066666F /* StorageAreaMapIdentifier.h */,
70647067 465F4E05230B2E7C003CEDB7 /* StorageNamespaceIdentifier.h */,
70657068 1A17635416B1D5D000D88FD6 /* StorageNamespaceImpl.cpp */,
70667069 1A17635516B1D5D000D88FD6 /* StorageNamespaceImpl.h */,

1326313266 93E799DC276121080074008A /* StorageAreaBase.h in Headers */,
1326413267 1AD3306F16B1D991004F60E7 /* StorageAreaImpl.h in Headers */,
1326513268 1ACECD2517162DB1001FC9EF /* StorageAreaMap.h in Headers */,
 13269 93AEC161278F8CD30066666F /* StorageAreaMapIdentifier.h in Headers */,
1326613270 1A334DEE16DE8F88006A8E38 /* StorageAreaMapMessages.h in Headers */,
1326713271 93E799C7276027460074008A /* StorageAreaRegistry.h in Headers */,
1326813272 93B2614D227D149E00B97A76 /* StorageManager.h in Headers */,

Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp

@@void NetworkProcessConnection::didReceiveMessage(IPC::Connection& connection, IP
117117 return;
118118 }
119119 if (decoder.messageReceiverName() == Messages::StorageAreaMap::messageReceiverName()) {
120  if (auto* storageAreaMap = WebProcess::singleton().storageAreaMap(makeObjectIdentifier<StorageAreaIdentifierType>(decoder.destinationID())))
 120 if (auto storageAreaMap = WebProcess::singleton().storageAreaMap(makeObjectIdentifier<StorageAreaMapIdentifierType>(decoder.destinationID())))
121121 storageAreaMap->didReceiveMessage(connection, decoder);
122122 return;
123123 }

Source/WebKit/WebProcess/WebProcess.cpp

@@void WebProcess::networkProcessConnectionClosed(NetworkProcessConnection* connec
11891189 ASSERT(m_networkProcessConnection);
11901190 ASSERT_UNUSED(connection, m_networkProcessConnection == connection);
11911191
1192  for (auto* storageAreaMap : copyToVector(m_storageAreaMaps.values()))
1193  storageAreaMap->disconnect();
 1192 for (auto key : copyToVector(m_storageAreaMaps.keys()))
 1193 m_storageAreaMaps.get(key)->disconnect();
11941194
11951195 for (auto& page : m_pageMap.values()) {
11961196 auto idbConnection = page->corePage()->optionalIDBConnection();

@@void WebProcess::nonVisibleProcessMemoryCleanupTimerFired()
16971697
16981698void WebProcess::registerStorageAreaMap(StorageAreaMap& storageAreaMap)
16991699{
1700  ASSERT(storageAreaMap.identifier());
1701  ASSERT(!m_storageAreaMaps.contains(*storageAreaMap.identifier()));
1702  m_storageAreaMaps.set(*storageAreaMap.identifier(), &storageAreaMap);
 1700 auto identifier = storageAreaMap.identifier();
 1701 ASSERT(!m_storageAreaMaps.contains(identifier));
 1702 m_storageAreaMaps.add(identifier, storageAreaMap);
17031703}
17041704
17051705void WebProcess::unregisterStorageAreaMap(StorageAreaMap& storageAreaMap)
17061706{
1707  ASSERT(storageAreaMap.identifier());
1708  ASSERT(m_storageAreaMaps.contains(*storageAreaMap.identifier()));
1709  ASSERT(m_storageAreaMaps.get(*storageAreaMap.identifier()) == &storageAreaMap);
1710  m_storageAreaMaps.remove(*storageAreaMap.identifier());
 1707 auto identifier = storageAreaMap.identifier();
 1708 ASSERT(m_storageAreaMaps.contains(identifier));
 1709 ASSERT(m_storageAreaMaps.get(identifier).get() == &storageAreaMap);
 1710 m_storageAreaMaps.remove(identifier);
17111711}
17121712
1713 StorageAreaMap* WebProcess::storageAreaMap(StorageAreaIdentifier identifier) const
 1713WeakPtr<StorageAreaMap> WebProcess::storageAreaMap(StorageAreaMapIdentifier identifier) const
17141714{
17151715 return m_storageAreaMaps.get(identifier);
17161716}

Source/WebKit/WebProcess/WebProcess.h

3030#include "CacheModel.h"
3131#include "IdentifierTypes.h"
3232#include "SandboxExtension.h"
33 #include "StorageAreaIdentifier.h"
 33#include "StorageAreaMapIdentifier.h"
3434#include "TextCheckerState.h"
3535#include "UserContentControllerIdentifier.h"
3636#include "ViewUpdateDispatcher.h"

@@public:
284284
285285 void registerStorageAreaMap(StorageAreaMap&);
286286 void unregisterStorageAreaMap(StorageAreaMap&);
287  StorageAreaMap* storageAreaMap(StorageAreaIdentifier) const;
 287 WeakPtr<StorageAreaMap> storageAreaMap(StorageAreaMapIdentifier) const;
288288
289289#if PLATFORM(COCOA)
290290 RetainPtr<CFDataRef> sourceApplicationAuditData() const;

@@private:
742742 HashCountedSet<WebCore::ServiceWorkerRegistrationIdentifier> m_swRegistrationCounts;
743743#endif
744744
745  HashMap<StorageAreaIdentifier, StorageAreaMap*> m_storageAreaMaps;
 745 HashMap<StorageAreaMapIdentifier, WeakPtr<StorageAreaMap>> m_storageAreaMaps;
746746
747747 // Prewarmed WebProcesses do not have an associated sessionID yet, which is why this is an optional.
748748 // By the time the WebProcess gets a WebPage, it is guaranteed to have a sessionID.

Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.cpp

@@size_t StorageAreaImpl::memoryBytesUsedByCache()
112112 return 0;
113113}
114114
115 void StorageAreaImpl::incrementAccessCount()
 115void StorageAreaImpl::prewarm()
116116{
117  // Storage access is handled in the network process, so there's nothing to do here.
118 }
119 
120 void StorageAreaImpl::decrementAccessCount()
121 {
122  // Storage access is handled in the network process, so there's nothing to do here.
123 }
124 
125 void StorageAreaImpl::closeDatabaseIfIdle()
126 {
127  // FIXME: Implement this.
128  ASSERT_NOT_REACHED();
 117 if (m_storageAreaMap)
 118 m_storageAreaMap->connect();
129119}
130120
131121} // namespace WebKit

Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.h

@@private:
6161 bool contains(const String& key) override;
6262 WebCore::StorageType storageType() const override;
6363 size_t memoryBytesUsedByCache() override;
64  void incrementAccessCount() override;
65  void decrementAccessCount() override;
66  void closeDatabaseIfIdle() override;
 64 void prewarm() final;
6765
6866 Identifier m_identifier;
6967 WeakPtr<StorageAreaMap> m_storageAreaMap;

Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp

@@namespace WebKit {
5151using namespace WebCore;
5252
5353StorageAreaMap::StorageAreaMap(StorageNamespaceImpl& storageNamespace, Ref<WebCore::SecurityOrigin>&& securityOrigin)
54  : m_namespace(storageNamespace)
 54 : m_identifier(StorageAreaMapIdentifier::generate())
 55 , m_namespace(storageNamespace)
5556 , m_securityOrigin(WTFMove(securityOrigin))
5657 , m_quotaInBytes(storageNamespace.quotaInBytes())
5758 , m_type(storageNamespace.storageType())
5859{
59  connect();
 60 WebProcess::singleton().registerStorageAreaMap(*this);
6061}
6162
6263StorageAreaMap::~StorageAreaMap()
6364{
6465 disconnect();
 66 WebProcess::singleton().unregisterStorageAreaMap(*this);
6567}
6668
6769unsigned StorageAreaMap::length()

@@void StorageAreaMap::setItem(Frame* sourceFrame, StorageAreaImpl* sourceArea, co
9597
9698 m_pendingValueChanges.add(key);
9799
98  if (m_mapID)
99  WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::SetItem(*m_mapID, sourceArea->identifier(), m_currentSeed, key, value, sourceFrame->document()->url().string()), 0);
 100 if (m_remoteAreaIdentifier)
 101 WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::SetItem(*m_remoteAreaIdentifier, sourceArea->identifier(), m_currentSeed, key, value, sourceFrame->document()->url().string()), 0);
100102 else
101103 RELEASE_LOG_ERROR(Storage, "StorageAreaMap::setItem failed because storage map ID is invalid");
102104}

@@void StorageAreaMap::removeItem(WebCore::Frame* sourceFrame, StorageAreaImpl* so
114116
115117 m_pendingValueChanges.add(key);
116118
117  if (m_mapID)
118  WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::RemoveItem(*m_mapID, sourceArea->identifier(), m_currentSeed, key, sourceFrame->document()->url().string()), 0);
 119 if (m_remoteAreaIdentifier)
 120 WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::RemoveItem(*m_remoteAreaIdentifier, sourceArea->identifier(), m_currentSeed, key, sourceFrame->document()->url().string()), 0);
119121 else
120122 RELEASE_LOG_ERROR(Storage, "StorageAreaMap::removeItem failed because storage map ID is invalid");
121123}
122124
123125void StorageAreaMap::clear(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea)
124126{
125  connect();
126 
 127 connectSync();
127128 resetValues();
128129
129130 m_hasPendingClear = true;
130131 m_map = makeUnique<StorageMap>(m_quotaInBytes);
131132
132  if (m_mapID)
133  WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::Clear(*m_mapID, sourceArea->identifier(), m_currentSeed, sourceFrame->document()->url().string()), 0);
 133 if (m_remoteAreaIdentifier)
 134 WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::Clear(*m_remoteAreaIdentifier, sourceArea->identifier(), m_currentSeed, sourceFrame->document()->url().string()), 0);
134135 else
135136 RELEASE_LOG_ERROR(Storage, "StorageAreaMap::clear failed because storage map ID is invalid");
136137}

@@void StorageAreaMap::resetValues()
151152
152153StorageMap& StorageAreaMap::ensureMap()
153154{
154  connect();
 155 connectSync();
155156
156  if (!m_map) {
 157 if (!m_map)
157158 m_map = makeUnique<StorageMap>(m_quotaInBytes);
158159
159  if (m_mapID) {
160  // We need to use a IPC::UnboundedSynchronousIPCScope to prevent UIProcess hangs in case we receive a synchronous IPC from the UIProcess while we're waiting for a response
161  // from our StorageManagerSet::GetValues() IPC. This IPC may be very slow because it may need to fetch the values from disk and there may be a lot of data.
162  IPC::UnboundedSynchronousIPCScope unboundedSynchronousIPCScope;
163  HashMap<String, String> values;
164  WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkStorageManager::GetValues(*m_mapID), Messages::StorageManagerSet::GetValues::Reply(values), 0);
165  m_map->importItems(WTFMove(values));
166  } else
167  RELEASE_LOG_ERROR(Storage, "StorageAreaMap::ensureMap failed to load from network process because storage map ID is invalid");
168  }
169160 return *m_map;
170161}
171162

@@void StorageAreaMap::applyChange(const String& key, const String& newValue)
259250 m_map->setItemIgnoringQuota(key, newValue);
260251}
261252
262 void StorageAreaMap::dispatchStorageEvent(const std::optional<StorageAreaImplIdentifier>& storageAreaImplID, const String& key, const String& oldValue, const String& newValue, const String& urlString)
 253void StorageAreaMap::dispatchStorageEvent(const std::optional<StorageAreaImplIdentifier>& storageAreaImplID, const String& key, const String& oldValue, const String& newValue, const String& urlString, uint64_t messageIdentifier)
263254{
 255 if (messageIdentifier < m_lastHandledMessageIdentifier)
 256 return;
 257
 258 m_lastHandledMessageIdentifier = messageIdentifier;
264259 if (!storageAreaImplID) {
265260 // This storage event originates from another process so we need to apply the change to our storage area map.
266261 applyChange(key, newValue);

@@void StorageAreaMap::dispatchStorageEvent(const std::optional<StorageAreaImplIde
272267 dispatchLocalStorageEvent(storageAreaImplID, key, oldValue, newValue, urlString);
273268}
274269
275 void StorageAreaMap::clearCache()
 270void StorageAreaMap::clearCache(uint64_t messageIdentifier)
276271{
 272 if (messageIdentifier < m_lastHandledMessageIdentifier)
 273 return;
 274
 275 m_lastHandledMessageIdentifier = messageIdentifier;
277276 resetValues();
278277}
279278

@@void StorageAreaMap::dispatchLocalStorageEvent(const std::optional<StorageAreaIm
344343 StorageEventDispatcher::dispatchLocalStorageEventsToFrames(pageGroup, frames, key, oldValue, newValue, urlString, m_securityOrigin->data());
345344}
346345
 346void StorageAreaMap::sendConnectMessage(SendMode mode)
 347{
 348 auto& ipcConnection = WebProcess::singleton().ensureNetworkProcessConnection().connection();
 349 auto namespaceIdentifier = m_namespace.storageNamespaceID();
 350 auto originData = m_securityOrigin->data();
 351 auto topOriginData = m_namespace.topLevelOrigin() ? m_namespace.topLevelOrigin()->data() : originData;
 352 auto origin = WebCore::ClientOrigin { topOriginData, originData };
 353 auto type = m_type;
 354 if ((type == StorageType::Local || type == StorageType::TransientLocal) && m_namespace.topLevelOrigin())
 355 type = StorageType::TransientLocal;
 356
 357 if (mode == SendMode::Sync) {
 358 StorageAreaIdentifier remoteAreaIdentifier;
 359 HashMap<String, String> items;
 360 uint64_t messageIdentifier;
 361 ipcConnection.sendSync(Messages::NetworkStorageManager::ConnectToStorageAreaSync(type, m_identifier, namespaceIdentifier, origin), Messages::NetworkStorageManager::ConnectToStorageAreaSync::Reply(remoteAreaIdentifier, items, messageIdentifier), 0);
 362 didConnect(remoteAreaIdentifier, WTFMove(items), messageIdentifier);
 363 return;
 364 }
 365
 366 auto completionHandler = [this, weakThis = WeakPtr { *this }, weakConnection = WeakPtr { ipcConnection }](auto remoteAreaIdentifier, auto items, auto messageIdentifier) mutable {
 367 if (weakThis)
 368 return didConnect(remoteAreaIdentifier, WTFMove(items), messageIdentifier);
 369
 370 if (weakConnection && remoteAreaIdentifier.isValid())
 371 weakConnection->send(Messages::NetworkStorageManager::DisconnectFromStorageArea(remoteAreaIdentifier), 0);
 372 };
 373
 374 ipcConnection.sendWithAsyncReply(Messages::NetworkStorageManager::ConnectToStorageArea(type, m_identifier, namespaceIdentifier, origin), WTFMove(completionHandler));
 375}
 376
 377void StorageAreaMap::connectSync()
 378{
 379 if (m_remoteAreaIdentifier)
 380 return;
 381
 382 sendConnectMessage(SendMode::Sync);
 383}
 384
347385void StorageAreaMap::connect()
348386{
349  if (m_mapID)
 387 if (m_remoteAreaIdentifier)
350388 return;
351389
352  StorageAreaIdentifier mapID;
353  switch (m_type) {
354  case StorageType::Local:
355  case StorageType::TransientLocal:
356  if (SecurityOrigin* topLevelOrigin = m_namespace.topLevelOrigin())
357  WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkStorageManager::ConnectToTransientLocalStorageArea(m_namespace.storageNamespaceID(), topLevelOrigin->data(), m_securityOrigin->data()), Messages::NetworkStorageManager::ConnectToTransientLocalStorageArea::Reply(mapID), 0);
358  else
359  WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkStorageManager::ConnectToLocalStorageArea(m_namespace.storageNamespaceID(), m_securityOrigin->data()), Messages::NetworkStorageManager::ConnectToLocalStorageArea::Reply(mapID), 0);
360  break;
361  case StorageType::Session:
362  WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkStorageManager::ConnectToSessionStorageArea(m_namespace.storageNamespaceID(), m_securityOrigin->data()), Messages::NetworkStorageManager::ConnectToSessionStorageArea::Reply(mapID), 0);
363  }
 390 sendConnectMessage(SendMode::Async);
 391}
364392
365  if (mapID.isValid()) {
366  m_mapID = mapID;
367  WebProcess::singleton().registerStorageAreaMap(*this);
368  }
 393void StorageAreaMap::didConnect(StorageAreaIdentifier remoteAreaIdentifier, HashMap<String, String>&& items, uint64_t messageIdentifier)
 394{
 395 if (messageIdentifier < m_lastHandledMessageIdentifier)
 396 return;
 397
 398 m_lastHandledMessageIdentifier = messageIdentifier;
 399 if (!remoteAreaIdentifier.isValid())
 400 return;
 401
 402 m_remoteAreaIdentifier = remoteAreaIdentifier;
 403 m_map = makeUnique<StorageMap>(m_quotaInBytes);
 404 m_map->importItems(WTFMove(items));
369405}
370406
371407void StorageAreaMap::disconnect()
372408{
373  if (!m_mapID)
 409 if (!m_remoteAreaIdentifier)
374410 return;
375411
376412 resetValues();
377  WebProcess::singleton().unregisterStorageAreaMap(*this);
378413
379414 if (auto* networkProcessConnection = WebProcess::singleton().existingNetworkProcessConnection())
380  networkProcessConnection->connection().send(Messages::NetworkStorageManager::DisconnectFromStorageArea(*m_mapID), 0);
 415 networkProcessConnection->connection().send(Messages::NetworkStorageManager::DisconnectFromStorageArea(*m_remoteAreaIdentifier), 0);
381416
382  m_mapID = { };
 417 m_remoteAreaIdentifier = { };
 418 m_lastHandledMessageIdentifier = 0;
383419}
384420
385421void StorageAreaMap::incrementUseCount()

Source/WebKit/WebProcess/WebStorage/StorageAreaMap.h

2828#include "MessageReceiver.h"
2929#include "StorageAreaIdentifier.h"
3030#include "StorageAreaImplIdentifier.h"
 31#include "StorageAreaMapIdentifier.h"
3132#include <WebCore/SecurityOrigin.h>
3233#include <WebCore/StorageArea.h>
3334#include <wtf/Forward.h>

@@public:
6667 void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
6768
6869 const WebCore::SecurityOrigin& securityOrigin() const { return m_securityOrigin.get(); }
69  const std::optional<StorageAreaIdentifier>& identifier() const { return m_mapID; }
 70 StorageAreaMapIdentifier identifier() const { return m_identifier; }
7071
 72 void connect();
7173 void disconnect();
7274
7375 void incrementUseCount();

@@private:
7880 void didRemoveItem(uint64_t mapSeed, const String& key);
7981 void didClear(uint64_t mapSeed);
8082
81  void dispatchStorageEvent(const std::optional<StorageAreaImplIdentifier>& sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString);
82  void clearCache();
 83 void dispatchStorageEvent(const std::optional<StorageAreaImplIdentifier>& sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString, uint64_t messageIdentifier);
 84 void clearCache(uint64_t messageIdentifier);
8385
8486 void resetValues();
8587 WebCore::StorageMap& ensureMap();

@@private:
9092 void dispatchSessionStorageEvent(const std::optional<StorageAreaImplIdentifier>&, const String& key, const String& oldValue, const String& newValue, const String& urlString);
9193 void dispatchLocalStorageEvent(const std::optional<StorageAreaImplIdentifier>&, const String& key, const String& oldValue, const String& newValue, const String& urlString);
9294
93  void connect();
 95 enum class SendMode : bool { Async, Sync };
 96 void sendConnectMessage(SendMode);
 97 void connectSync();
 98 void didConnect(StorageAreaIdentifier, HashMap<String, String>&&, uint64_t messageIdentifier);
9499
 100 StorageAreaMapIdentifier m_identifier;
 101 uint64_t m_lastHandledMessageIdentifier { 0 };
95102 StorageNamespaceImpl& m_namespace;
96103 Ref<WebCore::SecurityOrigin> m_securityOrigin;
97104 std::unique_ptr<WebCore::StorageMap> m_map;
98  std::optional<StorageAreaIdentifier> m_mapID;
 105 std::optional<StorageAreaIdentifier> m_remoteAreaIdentifier;
99106 HashCountedSet<String> m_pendingValueChanges;
100107 uint64_t m_currentSeed { 0 };
101108 unsigned m_quotaInBytes;

Source/WebKit/WebProcess/WebStorage/StorageAreaMap.messages.in

@@messages -> StorageAreaMap NotRefCounted {
2525 DidRemoveItem(uint64_t storageMapSeed, String key)
2626 DidClear(uint64_t storageMapSeed)
2727
28  DispatchStorageEvent(std::optional<WebKit::StorageAreaImplIdentifier> storageAreaImplID, String key, String oldValue, String newValue, String urlString)
29  ClearCache()
 28 DispatchStorageEvent(std::optional<WebKit::StorageAreaImplIdentifier> storageAreaImplID, String key, String oldValue, String newValue, String urlString, uint64_t messageIdentifier)
 29 ClearCache(uint64_t messageIdentifier)
3030}

Source/WebKit/WebProcess/WebStorage/StorageAreaMapIdentifier.h

 1/*
 2 * Copyright (C) 2022 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#pragma once
 27
 28#include <wtf/ObjectIdentifier.h>
 29
 30namespace WebKit {
 31
 32enum StorageAreaMapIdentifierType { };
 33using StorageAreaMapIdentifier = ObjectIdentifier<StorageAreaMapIdentifierType>;
 34
 35} // namespace WebKit
 36

Tools/Scripts/libraries/webkitbugspy/webkitbugspy/tests/radar_unittest.py

@@class TestGitHub(unittest.TestCase):
9999 def test_comments(self):
100100 with mocks.Radar(issues=mocks.ISSUES):
101101 comments = radar.Tracker().issue(1).comments
 102 print(comments)
102103 self.assertEqual(len(comments), 2)
103104 self.assertEqual(comments[0].timestamp, 1639511020)
104105 self.assertEqual(comments[0].content, 'Was able to reproduce on version 1.2.3')