Add infrastructure for handling website data in the network process
https://bugs.webkit.org/show_bug.cgi?id=142092

Reviewed by Andreas Kling.

Source/WebKit2:

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::fetchWebsiteData):
(WebKit::NetworkProcess::deleteWebsiteDataForOrigins):
Send back "Did" messages without actually doing anything for now.

* NetworkProcess/NetworkProcess.h:
Add new members.

* NetworkProcess/NetworkProcess.messages.in:
Add FetchWebsiteData and DeleteWebsiteDataForOrigins messages.

* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::~NetworkProcessProxy):
Assert that all maps are empty.

(WebKit::NetworkProcessProxy::fetchWebsiteData):
(WebKit::NetworkProcessProxy::deleteWebsiteDataForOrigins):
Add callbacks and send fetch and delete messages respectively.

(WebKit::NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch):
Make sure to invoke all callbacks.

(WebKit::NetworkProcessProxy::didFetchWebsiteData):
Find the callback and invoke it.

(WebKit::NetworkProcessProxy::didDeleteWebsiteDataForOrigins):
Ditto.

* UIProcess/Network/NetworkProcessProxy.h:
Add new members.

* UIProcess/Network/NetworkProcessProxy.messages.in:
Add DidFetchWebsiteData and DidDeleteWebsiteDataForOrigins messages.

* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::connectionDidClose):
Just pass an empty WebsiteData object.

Tools:

Add a menu item that will fetch all website data, delete the returned data records, and
fetch all website data again so we can confirm that it's all empty.

* MiniBrowser/mac/WK2BrowserWindowController.m:
(-[WK2BrowserWindowController fetchAndClearWebsiteData:]):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@180773 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog
index 0c29192..a0a3af1 100644
--- a/Source/WebKit2/ChangeLog
+++ b/Source/WebKit2/ChangeLog
@@ -1,3 +1,48 @@
+2015-02-27  Anders Carlsson  <andersca@apple.com>
+
+        Add infrastructure for handling website data in the network process
+        https://bugs.webkit.org/show_bug.cgi?id=142092
+
+        Reviewed by Andreas Kling.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::fetchWebsiteData):
+        (WebKit::NetworkProcess::deleteWebsiteDataForOrigins):
+        Send back "Did" messages without actually doing anything for now.
+
+        * NetworkProcess/NetworkProcess.h:
+        Add new members.
+
+        * NetworkProcess/NetworkProcess.messages.in:
+        Add FetchWebsiteData and DeleteWebsiteDataForOrigins messages.
+
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::~NetworkProcessProxy):
+        Assert that all maps are empty.
+
+        (WebKit::NetworkProcessProxy::fetchWebsiteData):
+        (WebKit::NetworkProcessProxy::deleteWebsiteDataForOrigins):
+        Add callbacks and send fetch and delete messages respectively.
+
+        (WebKit::NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch):
+        Make sure to invoke all callbacks.
+
+        (WebKit::NetworkProcessProxy::didFetchWebsiteData):
+        Find the callback and invoke it.
+
+        (WebKit::NetworkProcessProxy::didDeleteWebsiteDataForOrigins):
+        Ditto.
+
+        * UIProcess/Network/NetworkProcessProxy.h:
+        Add new members.
+
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+        Add DidFetchWebsiteData and DidDeleteWebsiteDataForOrigins messages.
+
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::connectionDidClose):
+        Just pass an empty WebsiteData object.
+
 2015-02-26  Enrica Casucci  <enrica@apple.com>
 
         [WK2] REGRESSION(r180465): WebKit::WebPage::editorState() triggers a layout.
diff --git a/Source/WebKit2/NetworkProcess/NetworkProcess.cpp b/Source/WebKit2/NetworkProcess/NetworkProcess.cpp
index c50d67c..9baaa2d 100644
--- a/Source/WebKit2/NetworkProcess/NetworkProcess.cpp
+++ b/Source/WebKit2/NetworkProcess/NetworkProcess.cpp
@@ -39,11 +39,12 @@
 #include "NetworkProcessProxyMessages.h"
 #include "NetworkResourceLoader.h"
 #include "RemoteNetworkingContext.h"
+#include "SecurityOriginData.h"
 #include "SessionTracker.h"
 #include "StatisticsData.h"
 #include "WebCookieManager.h"
 #include "WebProcessPoolMessages.h"
-#include "WebsiteDataTypes.h"
+#include "WebsiteData.h"
 #include <WebCore/Logging.h>
 #include <WebCore/MemoryPressureHandler.h>
 #include <WebCore/PlatformCookieJar.h>
@@ -240,7 +241,15 @@
     SessionTracker::destroySession(sessionID);
 }
 
-void NetworkProcess::deleteWebsiteData(WebCore::SessionID sessionID, uint64_t websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID)
+void NetworkProcess::fetchWebsiteData(SessionID sessionID, uint64_t websiteDataTypes, uint64_t callbackID)
+{
+    // FIXME: Actually return data.
+    WebsiteData websiteData;
+
+    parentProcessConnection()->send(Messages::NetworkProcessProxy::DidFetchWebsiteData(callbackID, websiteData), 0);
+}
+
+void NetworkProcess::deleteWebsiteData(SessionID sessionID, uint64_t websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID)
 {
     if (websiteDataTypes & WebsiteDataTypeCookies) {
         if (auto* networkStorageSession = SessionTracker::session(sessionID))
@@ -259,6 +268,17 @@
     completionHandler();
 }
 
+void NetworkProcess::deleteWebsiteDataForOrigins(SessionID sessionID, uint64_t websiteDataTypes, const Vector<SecurityOriginData>& origins, uint64_t callbackID)
+{
+    // FIXME: Actually delete something.
+
+    auto completionHandler = [this, callbackID] {
+        parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteDataForOrigins(callbackID), 0);
+    };
+
+    completionHandler();
+}
+
 void NetworkProcess::downloadRequest(uint64_t downloadID, const ResourceRequest& request)
 {
     downloadManager().startDownload(downloadID, request);
diff --git a/Source/WebKit2/NetworkProcess/NetworkProcess.h b/Source/WebKit2/NetworkProcess/NetworkProcess.h
index 1d5fb5b..c9cc054 100644
--- a/Source/WebKit2/NetworkProcess/NetworkProcess.h
+++ b/Source/WebKit2/NetworkProcess/NetworkProcess.h
@@ -48,6 +48,7 @@
 class NetworkConnectionToWebProcess;
 class NetworkProcessSupplement;
 struct NetworkProcessCreationParameters;
+struct SecurityOriginData;
 
 class NetworkProcess : public ChildProcess, private DownloadManager::Client {
     WTF_MAKE_NONCOPYABLE(NetworkProcess);
@@ -120,7 +121,9 @@
     void ensurePrivateBrowsingSession(WebCore::SessionID);
     void destroyPrivateBrowsingSession(WebCore::SessionID);
 
+    void fetchWebsiteData(WebCore::SessionID, uint64_t websiteDataTypes, uint64_t callbackID);
     void deleteWebsiteData(WebCore::SessionID, uint64_t websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID);
+    void deleteWebsiteDataForOrigins(WebCore::SessionID, uint64_t websiteDataTypes, const Vector<SecurityOriginData>& origins, uint64_t callbackID);
 
     // FIXME: This should take a session ID so we can identify which disk cache to delete.
     void clearDiskCache(std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler);
diff --git a/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in
index a418020..7127dcd 100644
--- a/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in
+++ b/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in
@@ -37,7 +37,9 @@
     EnsurePrivateBrowsingSession(WebCore::SessionID sessionID)
     DestroyPrivateBrowsingSession(WebCore::SessionID sessionID)
 
+    FetchWebsiteData(WebCore::SessionID sessionID, uint64_t websiteDataTypes, uint64_t callbackID)
     DeleteWebsiteData(WebCore::SessionID sessionID, uint64_t websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID)
+    DeleteWebsiteDataForOrigins(WebCore::SessionID sessionID, uint64_t websiteDataTypes, Vector<WebKit::SecurityOriginData> origins, uint64_t callbackID)
 
     DownloadRequest(uint64_t downloadID, WebCore::ResourceRequest request)
     ResumeDownload(uint64_t downloadID, IPC::DataReference resumeData, String path, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
diff --git a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp
index e970a26..9e32667 100644
--- a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp
+++ b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp
@@ -35,6 +35,7 @@
 #include "NetworkProcessMessages.h"
 #include "WebProcessMessages.h"
 #include "WebProcessPool.h"
+#include "WebsiteData.h"
 #include <wtf/RunLoop.h>
 
 #if ENABLE(SEC_ITEM_SHIM)
@@ -73,7 +74,9 @@
 
 NetworkProcessProxy::~NetworkProcessProxy()
 {
+    ASSERT(m_pendingFetchWebsiteDataCallbacks.isEmpty());
     ASSERT(m_pendingDeleteWebsiteDataCallbacks.isEmpty());
+    ASSERT(m_pendingDeleteWebsiteDataForOriginsCallbacks.isEmpty());
 }
 
 void NetworkProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions)
@@ -111,6 +114,16 @@
     return m_downloadProxyMap->createDownloadProxy(m_processPool, resourceRequest);
 }
 
+void NetworkProcessProxy::fetchWebsiteData(SessionID sessionID, WebsiteDataTypes dataTypes, std::function<void (WebsiteData)> completionHandler)
+{
+    ASSERT(canSendMessage());
+
+    uint64_t callbackID = generateCallbackID();
+    m_pendingFetchWebsiteDataCallbacks.add(callbackID, WTF::move(completionHandler));
+
+    send(Messages::WebProcess::FetchWebsiteData(sessionID, dataTypes, callbackID), 0);
+}
+
 void NetworkProcessProxy::deleteWebsiteData(WebCore::SessionID sessionID, WebsiteDataTypes dataTypes, std::chrono::system_clock::time_point modifiedSince,  std::function<void ()> completionHandler)
 {
     auto callbackID = generateCallbackID();
@@ -119,6 +132,20 @@
     send(Messages::NetworkProcess::DeleteWebsiteData(sessionID, dataTypes, modifiedSince, callbackID), 0);
 }
 
+void NetworkProcessProxy::deleteWebsiteDataForOrigins(SessionID sessionID, WebsiteDataTypes dataTypes, const Vector<RefPtr<WebCore::SecurityOrigin>>& origins, std::function<void ()> completionHandler)
+{
+    ASSERT(canSendMessage());
+
+    uint64_t callbackID = generateCallbackID();
+    m_pendingDeleteWebsiteDataForOriginsCallbacks.add(callbackID, WTF::move(completionHandler));
+
+    Vector<SecurityOriginData> originData;
+    for (auto& origin : origins)
+        originData.append(SecurityOriginData::fromSecurityOrigin(*origin));
+
+    send(Messages::WebProcess::DeleteWebsiteDataForOrigins(sessionID, dataTypes, originData, callbackID), 0);
+}
+
 void NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch()
 {
     // The network process must have crashed or exited, send any pending sync replies we might have.
@@ -134,10 +161,18 @@
 #endif
     }
 
+    for (const auto& callback : m_pendingFetchWebsiteDataCallbacks.values())
+        callback(WebsiteData());
+    m_pendingFetchWebsiteDataCallbacks.clear();
+
     for (const auto& callback : m_pendingDeleteWebsiteDataCallbacks.values())
         callback();
     m_pendingDeleteWebsiteDataCallbacks.clear();
 
+    for (const auto& callback : m_pendingDeleteWebsiteDataForOriginsCallbacks.values())
+        callback();
+    m_pendingDeleteWebsiteDataForOriginsCallbacks.clear();
+
     // Tell the network process manager to forget about this network process proxy. This may cause us to be deleted.
     m_processPool.networkProcessCrashed(this);
 }
@@ -199,12 +234,24 @@
     page->didReceiveAuthenticationChallengeProxy(frameID, authenticationChallenge.release());
 }
 
+void NetworkProcessProxy::didFetchWebsiteData(uint64_t callbackID, const WebsiteData& websiteData)
+{
+    auto callback = m_pendingFetchWebsiteDataCallbacks.take(callbackID);
+    callback(websiteData);
+}
+
 void NetworkProcessProxy::didDeleteWebsiteData(uint64_t callbackID)
 {
     auto callback = m_pendingDeleteWebsiteDataCallbacks.take(callbackID);
     callback();
 }
 
+void NetworkProcessProxy::didDeleteWebsiteDataForOrigins(uint64_t callbackID)
+{
+    auto callback = m_pendingDeleteWebsiteDataForOriginsCallbacks.take(callbackID);
+    callback();
+}
+
 void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier)
 {
     ChildProcessProxy::didFinishLaunching(launcher, connectionIdentifier);
diff --git a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h
index 550b3b8..9e74a3c 100644
--- a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h
+++ b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h
@@ -43,6 +43,7 @@
 namespace WebCore {
 class AuthenticationChallenge;
 class ResourceRequest;
+class SecurityOrigin;
 class SessionID;
 }
 
@@ -62,7 +63,9 @@
 
     DownloadProxy* createDownloadProxy(const WebCore::ResourceRequest&);
 
+    void fetchWebsiteData(WebCore::SessionID, WebsiteDataTypes, std::function<void (WebsiteData)> completionHandler);
     void deleteWebsiteData(WebCore::SessionID, WebsiteDataTypes, std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler);
+    void deleteWebsiteDataForOrigins(WebCore::SessionID, WebsiteDataTypes, const Vector<RefPtr<WebCore::SecurityOrigin>>& origins, std::function<void ()> completionHandler);
 
 #if PLATFORM(COCOA)
     void setProcessSuppressionEnabled(bool);
@@ -90,7 +93,9 @@
     void didReceiveNetworkProcessProxyMessage(IPC::Connection&, IPC::MessageDecoder&);
     void didCreateNetworkConnectionToWebProcess(const IPC::Attachment&);
     void didReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, const WebCore::AuthenticationChallenge&, uint64_t challengeID);
+    void didFetchWebsiteData(uint64_t callbackID, const WebsiteData&);
     void didDeleteWebsiteData(uint64_t callbackID);
+    void didDeleteWebsiteDataForOrigins(uint64_t callbackID);
     void logDiagnosticMessage(uint64_t pageID, const String& message, const String& description, bool shouldSample);
     void logDiagnosticMessageWithResult(uint64_t pageID, const String& message, const String& description, uint32_t result, bool shouldSample);
     void logDiagnosticMessageWithValue(uint64_t pageID, const String& message, const String& description, const String& value, bool shouldSample);
@@ -103,7 +108,9 @@
     unsigned m_numPendingConnectionRequests;
     Deque<RefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>> m_pendingConnectionReplies;
 
+    HashMap<uint64_t, std::function<void (WebsiteData)>> m_pendingFetchWebsiteDataCallbacks;
     HashMap<uint64_t, std::function<void ()>> m_pendingDeleteWebsiteDataCallbacks;
+    HashMap<uint64_t, std::function<void ()>> m_pendingDeleteWebsiteDataForOriginsCallbacks;
 
     std::unique_ptr<DownloadProxyMap> m_downloadProxyMap;
     CustomProtocolManagerProxy m_customProtocolManagerProxy;
diff --git a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in
index c519ce6..2d953d4 100644
--- a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in
+++ b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in
@@ -27,7 +27,9 @@
 
     DidReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, WebCore::AuthenticationChallenge challenge, uint64_t challengeID)
 
+    DidFetchWebsiteData(uint64_t callbackID, struct WebKit::WebsiteData websiteData)
     DidDeleteWebsiteData(uint64_t callbackID)
+    DidDeleteWebsiteDataForOrigins(uint64_t callbackID)
 
     # Diagnostic messages logging
     LogDiagnosticMessage(uint64_t pageID, String message, String description, bool shouldSample)
diff --git a/Source/WebKit2/UIProcess/WebProcessProxy.cpp b/Source/WebKit2/UIProcess/WebProcessProxy.cpp
index 7a8ac3c..aed7d25 100644
--- a/Source/WebKit2/UIProcess/WebProcessProxy.cpp
+++ b/Source/WebKit2/UIProcess/WebProcessProxy.cpp
@@ -150,7 +150,7 @@
     ASSERT(this->connection() == &connection);
 
     for (const auto& callback : m_pendingFetchWebsiteDataCallbacks.values())
-        callback({Vector<WebsiteData::Entry>()});
+        callback(WebsiteData());
     m_pendingFetchWebsiteDataCallbacks.clear();
 
     for (const auto& callback : m_pendingDeleteWebsiteDataCallbacks.values())
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index b1ef8fb..52c49f6 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,16 @@
+2015-02-27  Anders Carlsson  <andersca@apple.com>
+
+        Add infrastructure for handling website data in the network process
+        https://bugs.webkit.org/show_bug.cgi?id=142092
+
+        Reviewed by Andreas Kling.
+
+        Add a menu item that will fetch all website data, delete the returned data records, and
+        fetch all website data again so we can confirm that it's all empty.
+
+        * MiniBrowser/mac/WK2BrowserWindowController.m:
+        (-[WK2BrowserWindowController fetchAndClearWebsiteData:]):
+
 2015-02-26  Brent Fulgham  <bfulgham@apple.com>
 
         [Win] Remove remaining SafariTheme cruft
diff --git a/Tools/MiniBrowser/mac/MainMenu.xib b/Tools/MiniBrowser/mac/MainMenu.xib
index 3098b39..f889173 100644
--- a/Tools/MiniBrowser/mac/MainMenu.xib
+++ b/Tools/MiniBrowser/mac/MainMenu.xib
@@ -469,6 +469,12 @@
                                     <action selector="clearWebsiteData:" target="-1" id="pEC-gb-vGm"/>
                                 </connections>
                             </menuItem>
+                            <menuItem title="Fetch And Clear Website Data" id="VDP-iU-836">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="fetchAndClearWebsiteData:" target="-1" id="R06-l2-tP0"/>
+                                </connections>
+                            </menuItem>
                         </items>
                     </menu>
                 </menuItem>
diff --git a/Tools/MiniBrowser/mac/WK2BrowserWindowController.m b/Tools/MiniBrowser/mac/WK2BrowserWindowController.m
index 6b209b7..c0105f5 100644
--- a/Tools/MiniBrowser/mac/WK2BrowserWindowController.m
+++ b/Tools/MiniBrowser/mac/WK2BrowserWindowController.m
@@ -414,6 +414,17 @@
     }];
 }
 
+- (IBAction)fetchAndClearWebsiteData:(id)sender
+{
+    [_configuration._websiteDataStore fetchDataRecordsOfTypes:WKWebsiteDataTypeAll completionHandler:^(NSArray *websiteDataRecords) {
+        [_configuration._websiteDataStore removeDataOfTypes:WKWebsiteDataTypeAll forDataRecords:websiteDataRecords completionHandler:^{
+            [_configuration._websiteDataStore fetchDataRecordsOfTypes:WKWebsiteDataTypeAll completionHandler:^(NSArray *websiteDataRecords) {
+                NSLog(@"did clear website data, after clearing data is %@.", websiteDataRecords);
+            }];
+        }];
+    }];
+}
+
 - (IBAction)clearWebsiteData:(id)sender
 {
     [_configuration._websiteDataStore removeDataOfTypes:WKWebsiteDataTypeAll modifiedSince:[NSDate distantPast] completionHandler:^{