<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[214078] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/214078">214078</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2017-03-16 16:30:09 -0700 (Thu, 16 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Update the WKHTTPCookieStore API to be simpler and add observers.
&lt;rdar://problem/31096000&gt; and https://bugs.webkit.org/show_bug.cgi?id=169776

Reviewed by Alex Christensen.
Source/WebKit2:

When reviewing the API internally we realized the NSHTTPCookieStorage model doesn't
necessarily fit perfectly, and that to handle partitioned cookies going forward we
need to be much simpler right now.

We also realized that we should implement the &quot;cookie store changed&quot; observer for
any clients that might be providing a cookie viewing API.

* UIProcess/API/APIHTTPCookieStore.cpp:
(API::HTTPCookieStore::~HTTPCookieStore):
(API::HTTPCookieStore::deleteCookie):
(API::APIWebCookieManagerProxyObserver::APIWebCookieManagerProxyObserver):
(API::HTTPCookieStore::registerObserver):
(API::HTTPCookieStore::unregisterObserver):
(API::HTTPCookieStore::cookiesDidChange):
(API::HTTPCookieStore::cookieManagerDestroyed):
(API::HTTPCookieStore::registerForNewProcessPoolNotifications):
(API::HTTPCookieStore::unregisterForNewProcessPoolNotifications):
(API::HTTPCookieStore::setCookies): Deleted.
(API::HTTPCookieStore::removeCookiesSinceDate): Deleted.
(API::HTTPCookieStore::setHTTPCookieAcceptPolicy): Deleted.
(API::HTTPCookieStore::getHTTPCookieAcceptPolicy): Deleted.
* UIProcess/API/APIHTTPCookieStore.h:

* UIProcess/API/Cocoa/WKHTTPCookieStore.h:
* UIProcess/API/Cocoa/WKHTTPCookieStore.mm:
(WKHTTPCookieStoreObserver::WKHTTPCookieStoreObserver):
(-[WKHTTPCookieStore dealloc]):
(-[WKHTTPCookieStore allCookies:]):
(-[WKHTTPCookieStore addObserver:]):
(-[WKHTTPCookieStore removeObserver:]):
(-[WKHTTPCookieStore fetchCookies:]): Deleted.
(-[WKHTTPCookieStore fetchCookiesForURL:completionHandler:]): Deleted.
(-[WKHTTPCookieStore setCookies:forURL:mainDocumentURL:completionHandler:]): Deleted.
(-[WKHTTPCookieStore removeCookiesSinceDate:completionHandler:]): Deleted.
(-[WKHTTPCookieStore setCookieAcceptPolicy:completionHandler:]): Deleted.
(kitCookiePolicyToNSCookiePolicy): Deleted.
(-[WKHTTPCookieStore fetchCookieAcceptPolicy:]): Deleted.

* UIProcess/Cocoa/WebProcessPoolCocoa.mm:
(WebKit::WebProcessPool::platformInitializeNetworkProcess):

* UIProcess/WebCookieManagerProxy.cpp:
(WebKit::WebCookieManagerProxy::~WebCookieManagerProxy):
(WebKit::WebCookieManagerProxy::processPoolDestroyed):
(WebKit::WebCookieManagerProxy::registerObserver):
(WebKit::WebCookieManagerProxy::unregisterObserver):
(WebKit::WebCookieManagerProxy::cookiesDidChange):
(WebKit::WebCookieManagerProxy::setCookieObserverCallback): Deleted.
* UIProcess/WebCookieManagerProxy.h:
(WebKit::WebCookieManagerProxy::Observer::~Observer):

Add the ability for interested clients to listen for the creation of new WebProcessPools,
which is needed by APIHTTPCookieStore:
* UIProcess/WebProcessPool.cpp:
(WebKit::generateListenerIdentifier):
(WebKit::processPoolCreationListenerFunctionMap):
(WebKit::WebProcessPool::registerProcessPoolCreationListener):
(WebKit::WebProcessPool::unregisterProcessPoolCreationListener):
(WebKit::WebProcessPool::create):
* UIProcess/WebProcessPool.h:

* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::processPoolForCookieStorageNotifications):
(WebKit::WebsiteDataStore::isAssociatedProcessPool):
(WebKit::WebsiteDataStore::processPools):
* UIProcess/WebsiteData/WebsiteDataStore.h:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStore.mm: Renamed from Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStorage.mm.
(-[CookieObserver cookiesDidChangeInCookieStore:]):
(TEST): Also test delete and observers.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIAPIHTTPCookieStorecpp">trunk/Source/WebKit2/UIProcess/API/APIHTTPCookieStore.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIAPIHTTPCookieStoreh">trunk/Source/WebKit2/UIProcess/API/APIHTTPCookieStore.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKHTTPCookieStoreh">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKHTTPCookieStore.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKHTTPCookieStoremm">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKHTTPCookieStore.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessCocoaWebProcessPoolCocoamm">trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebCookieManagerProxycpp">trunk/Source/WebKit2/UIProcess/WebCookieManagerProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebCookieManagerProxyh">trunk/Source/WebKit2/UIProcess/WebCookieManagerProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessPoolcpp">trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessPoolh">trunk/Source/WebKit2/UIProcess/WebProcessPool.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebsiteDataWebsiteDataStorecpp">trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebsiteDataWebsiteDataStoreh">trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2CocoaWKHTTPCookieStoremm">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStore.mm</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkToolsTestWebKitAPITestsWebKit2CocoaWKHTTPCookieStoragemm">trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStorage.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/ChangeLog        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -1,3 +1,77 @@
</span><ins>+2017-03-16  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Update the WKHTTPCookieStore API to be simpler and add observers.
+        &lt;rdar://problem/31096000&gt; and https://bugs.webkit.org/show_bug.cgi?id=169776
+
+        Reviewed by Alex Christensen.
+        
+        When reviewing the API internally we realized the NSHTTPCookieStorage model doesn't
+        necessarily fit perfectly, and that to handle partitioned cookies going forward we
+        need to be much simpler right now.
+        
+        We also realized that we should implement the &quot;cookie store changed&quot; observer for
+        any clients that might be providing a cookie viewing API.
+        
+        * UIProcess/API/APIHTTPCookieStore.cpp:
+        (API::HTTPCookieStore::~HTTPCookieStore):
+        (API::HTTPCookieStore::deleteCookie):
+        (API::APIWebCookieManagerProxyObserver::APIWebCookieManagerProxyObserver):
+        (API::HTTPCookieStore::registerObserver):
+        (API::HTTPCookieStore::unregisterObserver):
+        (API::HTTPCookieStore::cookiesDidChange):
+        (API::HTTPCookieStore::cookieManagerDestroyed):
+        (API::HTTPCookieStore::registerForNewProcessPoolNotifications):
+        (API::HTTPCookieStore::unregisterForNewProcessPoolNotifications):
+        (API::HTTPCookieStore::setCookies): Deleted.
+        (API::HTTPCookieStore::removeCookiesSinceDate): Deleted.
+        (API::HTTPCookieStore::setHTTPCookieAcceptPolicy): Deleted.
+        (API::HTTPCookieStore::getHTTPCookieAcceptPolicy): Deleted.
+        * UIProcess/API/APIHTTPCookieStore.h:
+        
+        * UIProcess/API/Cocoa/WKHTTPCookieStore.h:
+        * UIProcess/API/Cocoa/WKHTTPCookieStore.mm:
+        (WKHTTPCookieStoreObserver::WKHTTPCookieStoreObserver):
+        (-[WKHTTPCookieStore dealloc]):
+        (-[WKHTTPCookieStore allCookies:]):
+        (-[WKHTTPCookieStore addObserver:]):
+        (-[WKHTTPCookieStore removeObserver:]):
+        (-[WKHTTPCookieStore fetchCookies:]): Deleted.
+        (-[WKHTTPCookieStore fetchCookiesForURL:completionHandler:]): Deleted.
+        (-[WKHTTPCookieStore setCookies:forURL:mainDocumentURL:completionHandler:]): Deleted.
+        (-[WKHTTPCookieStore removeCookiesSinceDate:completionHandler:]): Deleted.
+        (-[WKHTTPCookieStore setCookieAcceptPolicy:completionHandler:]): Deleted.
+        (kitCookiePolicyToNSCookiePolicy): Deleted.
+        (-[WKHTTPCookieStore fetchCookieAcceptPolicy:]): Deleted.
+
+        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+        (WebKit::WebProcessPool::platformInitializeNetworkProcess):
+
+        * UIProcess/WebCookieManagerProxy.cpp:
+        (WebKit::WebCookieManagerProxy::~WebCookieManagerProxy):
+        (WebKit::WebCookieManagerProxy::processPoolDestroyed):
+        (WebKit::WebCookieManagerProxy::registerObserver):
+        (WebKit::WebCookieManagerProxy::unregisterObserver):
+        (WebKit::WebCookieManagerProxy::cookiesDidChange):
+        (WebKit::WebCookieManagerProxy::setCookieObserverCallback): Deleted.
+        * UIProcess/WebCookieManagerProxy.h:
+        (WebKit::WebCookieManagerProxy::Observer::~Observer):
+
+        Add the ability for interested clients to listen for the creation of new WebProcessPools,
+        which is needed by APIHTTPCookieStore:
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::generateListenerIdentifier):
+        (WebKit::processPoolCreationListenerFunctionMap):
+        (WebKit::WebProcessPool::registerProcessPoolCreationListener):
+        (WebKit::WebProcessPool::unregisterProcessPoolCreationListener):
+        (WebKit::WebProcessPool::create):
+        * UIProcess/WebProcessPool.h:
+
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::processPoolForCookieStorageNotifications):
+        (WebKit::WebsiteDataStore::isAssociatedProcessPool):
+        (WebKit::WebsiteDataStore::processPools):
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+
</ins><span class="cx"> 2017-03-16  Brian Burg  &lt;bburg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS WK2] Web Automation: implement platform methods for simulating keyboard events
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIAPIHTTPCookieStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/APIHTTPCookieStore.cpp (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/APIHTTPCookieStore.cpp        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/API/APIHTTPCookieStore.cpp        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -42,6 +42,11 @@
</span><span class="cx"> 
</span><span class="cx"> HTTPCookieStore::~HTTPCookieStore()
</span><span class="cx"> {
</span><ins>+    ASSERT(m_observers.isEmpty());
+    ASSERT(!m_observedCookieManagerProxy);
+    ASSERT(!m_cookieManagerProxyObserver);
+
+    unregisterForNewProcessPoolNotifications();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTTPCookieStore::cookies(Function&lt;void (const Vector&lt;WebCore::Cookie&gt;&amp;)&gt;&amp;&amp; completionHandler)
</span><span class="lines">@@ -55,17 +60,6 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HTTPCookieStore::cookies(const WebCore::URL&amp; url, Function&lt;void (const Vector&lt;WebCore::Cookie&gt;&amp;)&gt;&amp;&amp; completionHandler)
-{
-    auto&amp; dataStore = m_owningDataStore.websiteDataStore();
-    auto pool = dataStore.processPoolForCookieStorageOperations();
-    auto* cookieManager = pool-&gt;supplement&lt;WebKit::WebCookieManagerProxy&gt;();
-
-    cookieManager-&gt;getCookies(dataStore.sessionID(), url, [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)](const Vector&lt;WebCore::Cookie&gt;&amp; cookies, CallbackBase::Error error) {
-        completionHandler(cookies);
-    });
-}
-
</del><span class="cx"> void HTTPCookieStore::setCookie(const WebCore::Cookie&amp; cookie, Function&lt;void ()&gt;&amp;&amp; completionHandler)
</span><span class="cx"> {
</span><span class="cx">     auto&amp; dataStore = m_owningDataStore.websiteDataStore();
</span><span class="lines">@@ -77,62 +71,125 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HTTPCookieStore::setCookies(const Vector&lt;WebCore::Cookie&gt;&amp; cookies, const WebCore::URL&amp; url, const WebCore::URL&amp; mainDocumentURL, Function&lt;void ()&gt;&amp;&amp; completionHandler)
</del><ins>+void HTTPCookieStore::deleteCookie(const WebCore::Cookie&amp; cookie, Function&lt;void ()&gt;&amp;&amp; completionHandler)
</ins><span class="cx"> {
</span><span class="cx">     auto&amp; dataStore = m_owningDataStore.websiteDataStore();
</span><span class="cx">     auto pool = dataStore.processPoolForCookieStorageOperations();
</span><span class="cx">     auto* cookieManager = pool-&gt;supplement&lt;WebKit::WebCookieManagerProxy&gt;();
</span><span class="cx"> 
</span><del>-    cookieManager-&gt;setCookies(dataStore.sessionID(), cookies, url, mainDocumentURL, [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)](CallbackBase::Error error) {
</del><ins>+    cookieManager-&gt;deleteCookie(dataStore.sessionID(), cookie, [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)](CallbackBase::Error error) {
</ins><span class="cx">         completionHandler();
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HTTPCookieStore::deleteCookie(const WebCore::Cookie&amp; cookie, Function&lt;void ()&gt;&amp;&amp; completionHandler)
</del><ins>+class APIWebCookieManagerProxyObserver : public WebCookieManagerProxy::Observer {
+public:
+    explicit APIWebCookieManagerProxyObserver(API::HTTPCookieStore&amp; cookieStore)
+        : m_cookieStore(cookieStore)
+    {
+    }
+
+private:
+    void cookiesDidChange() final
+    {
+        m_cookieStore.cookiesDidChange();
+    }
+
+    void managerDestroyed() final
+    {
+        m_cookieStore.cookieManagerDestroyed();
+    }
+
+    API::HTTPCookieStore&amp; m_cookieStore;
+};
+
+void HTTPCookieStore::registerObserver(Observer&amp; observer)
</ins><span class="cx"> {
</span><ins>+    m_observers.add(&amp;observer);
+
+    if (m_cookieManagerProxyObserver)
+        return;
+
+    ASSERT(!m_observedCookieManagerProxy);
+
+    m_cookieManagerProxyObserver = std::make_unique&lt;APIWebCookieManagerProxyObserver&gt;(*this);
+
</ins><span class="cx">     auto&amp; dataStore = m_owningDataStore.websiteDataStore();
</span><del>-    auto pool = dataStore.processPoolForCookieStorageOperations();
-    auto* cookieManager = pool-&gt;supplement&lt;WebKit::WebCookieManagerProxy&gt;();
</del><ins>+    auto* pool = dataStore.processPoolForCookieStorageNotifications();
</ins><span class="cx"> 
</span><del>-    cookieManager-&gt;deleteCookie(dataStore.sessionID(), cookie, [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)](CallbackBase::Error error) {
-        completionHandler();
-    });
</del><ins>+    if (!pool) {
+        registerForNewProcessPoolNotifications();
+        return;
+    }
+
+    m_observedCookieManagerProxy = pool-&gt;supplement&lt;WebKit::WebCookieManagerProxy&gt;();
+    m_observedCookieManagerProxy-&gt;registerObserver(dataStore.sessionID(), *m_cookieManagerProxyObserver);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HTTPCookieStore::removeCookiesSinceDate(std::chrono::system_clock::time_point date, Function&lt;void ()&gt;&amp;&amp; completionHandler)
</del><ins>+void HTTPCookieStore::unregisterObserver(Observer&amp; observer)
</ins><span class="cx"> {
</span><del>-    auto&amp; dataStore = m_owningDataStore.websiteDataStore();
-    auto pool = dataStore.processPoolForCookieStorageOperations();
-    auto* cookieManager = pool-&gt;supplement&lt;WebKit::WebCookieManagerProxy&gt;();
</del><ins>+    m_observers.remove(&amp;observer);
</ins><span class="cx"> 
</span><del>-    cookieManager-&gt;deleteAllCookiesModifiedSince(dataStore.sessionID(), date, [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)](CallbackBase::Error error) {
-        completionHandler();
-    });
</del><ins>+    if (!m_observers.isEmpty())
+        return;
+
+    if (m_observedCookieManagerProxy)
+        m_observedCookieManagerProxy-&gt;unregisterObserver(m_owningDataStore.websiteDataStore().sessionID(), *m_cookieManagerProxyObserver);
+
+    if (m_processPoolCreationListenerIdentifier)
+        WebProcessPool::unregisterProcessPoolCreationListener(m_processPoolCreationListenerIdentifier);
+
+    m_processPoolCreationListenerIdentifier = 0;
+    m_observedCookieManagerProxy = nullptr;
+    m_cookieManagerProxyObserver = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HTTPCookieStore::setHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy, Function&lt;void ()&gt;&amp;&amp; completionHandler)
</del><ins>+void HTTPCookieStore::cookiesDidChange()
</ins><span class="cx"> {
</span><ins>+    for (auto* observer : m_observers)
+        observer-&gt;cookiesDidChange(*this);
+}
+
+void HTTPCookieStore::cookieManagerDestroyed()
+{
</ins><span class="cx">     auto&amp; dataStore = m_owningDataStore.websiteDataStore();
</span><del>-    auto pool = dataStore.processPoolForCookieStorageOperations();
-    auto* cookieManager = pool-&gt;supplement&lt;WebKit::WebCookieManagerProxy&gt;();
</del><span class="cx"> 
</span><del>-    cookieManager-&gt;setHTTPCookieAcceptPolicy(dataStore.sessionID(), policy, [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)](CallbackBase::Error error) {
-        completionHandler();
-    });
</del><ins>+    m_observedCookieManagerProxy-&gt;unregisterObserver(dataStore.sessionID(), *m_cookieManagerProxyObserver);
+    m_observedCookieManagerProxy = nullptr;
+
+    auto* pool = dataStore.processPoolForCookieStorageNotifications();
+
+    if (!pool) {
+        registerForNewProcessPoolNotifications();
+        return;
+    }
+
+    m_observedCookieManagerProxy = pool-&gt;supplement&lt;WebKit::WebCookieManagerProxy&gt;();
+    m_observedCookieManagerProxy-&gt;registerObserver(dataStore.sessionID(), *m_cookieManagerProxyObserver);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HTTPCookieStore::getHTTPCookieAcceptPolicy(Function&lt;void (HTTPCookieAcceptPolicy)&gt;&amp;&amp; completionHandler)
</del><ins>+void HTTPCookieStore::registerForNewProcessPoolNotifications()
</ins><span class="cx"> {
</span><del>-    auto&amp; dataStore = m_owningDataStore.websiteDataStore();
-    auto pool = dataStore.processPoolForCookieStorageOperations();
-    auto* cookieManager = pool-&gt;supplement&lt;WebKit::WebCookieManagerProxy&gt;();
</del><ins>+    ASSERT(!m_processPoolCreationListenerIdentifier);
</ins><span class="cx"> 
</span><del>-    cookieManager-&gt;getHTTPCookieAcceptPolicy(dataStore.sessionID(), [pool = WTFMove(pool), completionHandler = WTFMove(completionHandler)](HTTPCookieAcceptPolicy policy, CallbackBase::Error error) {
-        if (error != CallbackBase::Error::None)
-            policy = HTTPCookieAcceptPolicyNever;
</del><ins>+    m_processPoolCreationListenerIdentifier = WebProcessPool::registerProcessPoolCreationListener([this](WebProcessPool&amp; newProcessPool) {
+        ASSERT(m_cookieManagerProxyObserver);
</ins><span class="cx"> 
</span><del>-        completionHandler(policy);
</del><ins>+        if (!m_owningDataStore.websiteDataStore().isAssociatedProcessPool(newProcessPool))
+            return;
+
+        m_observedCookieManagerProxy = newProcessPool.supplement&lt;WebKit::WebCookieManagerProxy&gt;();
+        m_observedCookieManagerProxy-&gt;registerObserver(m_owningDataStore.websiteDataStore().sessionID(), *m_cookieManagerProxyObserver);
+        unregisterForNewProcessPoolNotifications();
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void HTTPCookieStore::unregisterForNewProcessPoolNotifications()
+{
+    if (m_processPoolCreationListenerIdentifier)
+        WebProcessPool::unregisterProcessPoolCreationListener(m_processPoolCreationListenerIdentifier);
+
+    m_processPoolCreationListenerIdentifier = 0;
+}
+
</ins><span class="cx"> } // namespace API
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIAPIHTTPCookieStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/APIHTTPCookieStore.h (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/APIHTTPCookieStore.h        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/API/APIHTTPCookieStore.h        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #include &quot;APIObject.h&quot;
</span><span class="cx"> #include &quot;HTTPCookieAcceptPolicy.h&quot;
</span><span class="cx"> #include &lt;wtf/Function.h&gt;
</span><ins>+#include &lt;wtf/HashSet.h&gt;
</ins><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -35,8 +36,13 @@
</span><span class="cx"> struct Cookie;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+namespace WebKit {
+class WebCookieManagerProxy;
+}
+
</ins><span class="cx"> namespace API {
</span><span class="cx"> 
</span><ins>+class APIWebCookieManagerProxyObserver;
</ins><span class="cx"> class WebsiteDataStore;
</span><span class="cx"> 
</span><span class="cx"> class HTTPCookieStore final : public ObjectImpl&lt;Object::Type::HTTPCookieStore&gt; {
</span><span class="lines">@@ -49,21 +55,34 @@
</span><span class="cx">     virtual ~HTTPCookieStore();
</span><span class="cx"> 
</span><span class="cx">     void cookies(Function&lt;void (const Vector&lt;WebCore::Cookie&gt;&amp;)&gt;&amp;&amp; completionHandler);
</span><del>-    void cookies(const WebCore::URL&amp;, Function&lt;void (const Vector&lt;WebCore::Cookie&gt;&amp;)&gt;&amp;&amp; completionHandler);
-
</del><span class="cx">     void setCookie(const WebCore::Cookie&amp;, Function&lt;void ()&gt;&amp;&amp; completionHandler);
</span><del>-    void setCookies(const Vector&lt;WebCore::Cookie&gt;&amp;, const WebCore::URL&amp;, const WebCore::URL&amp; mainDocumentURL, Function&lt;void ()&gt;&amp;&amp; completionHandler);
</del><span class="cx">     void deleteCookie(const WebCore::Cookie&amp;, Function&lt;void ()&gt;&amp;&amp; completionHandler);
</span><span class="cx"> 
</span><del>-    void removeCookiesSinceDate(std::chrono::system_clock::time_point, Function&lt;void ()&gt;&amp;&amp; completionHandler);
</del><ins>+    class Observer {
+    public:
+        virtual ~Observer() { }
+        virtual void cookiesDidChange(HTTPCookieStore&amp;) = 0;
+    };
</ins><span class="cx"> 
</span><del>-    void setHTTPCookieAcceptPolicy(WebKit::HTTPCookieAcceptPolicy, Function&lt;void ()&gt;&amp;&amp; completionHandler);
-    void getHTTPCookieAcceptPolicy(Function&lt;void (WebKit::HTTPCookieAcceptPolicy)&gt;&amp;&amp; completionHandler);
-    
</del><ins>+    void registerObserver(Observer&amp;);
+    void unregisterObserver(Observer&amp;);
+
+    void cookiesDidChange();
+    void cookieManagerDestroyed();
+
</ins><span class="cx"> private:
</span><span class="cx">     HTTPCookieStore(WebsiteDataStore&amp;);
</span><span class="cx"> 
</span><ins>+    void registerForNewProcessPoolNotifications();
+    void unregisterForNewProcessPoolNotifications();
+
</ins><span class="cx">     WebsiteDataStore&amp; m_owningDataStore;
</span><ins>+    HashSet&lt;Observer*&gt; m_observers;
+
+    WebKit::WebCookieManagerProxy* m_observedCookieManagerProxy { nullptr };
+    std::unique_ptr&lt;APIWebCookieManagerProxyObserver&gt; m_cookieManagerProxyObserver;
+
+    uint64_t m_processPoolCreationListenerIdentifier { 0 };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKHTTPCookieStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKHTTPCookieStore.h (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKHTTPCookieStore.h        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKHTTPCookieStore.h        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -31,6 +31,13 @@
</span><span class="cx"> 
</span><span class="cx"> NS_ASSUME_NONNULL_BEGIN
</span><span class="cx"> 
</span><ins>+@class WKHTTPCookieStore;
+
+@protocol WKHTTPCookieStoreObserver &lt;NSObject&gt;
+@optional
+- (void)cookiesDidChangeInCookieStore:(WKHTTPCookieStore *)cookieStore;
+@end
+
</ins><span class="cx"> /*!
</span><span class="cx">  A WKHTTPCookieStore object allows managing the HTTP cookies associated with a particular WKWebsiteDataStore.
</span><span class="cx">  */
</span><span class="lines">@@ -42,13 +49,8 @@
</span><span class="cx"> /*! @abstract Fetches all stored cookies.
</span><span class="cx">  @param completionHandler A block to invoke with the fetched cookies.
</span><span class="cx">  */
</span><del>-- (void)fetchCookies:(void (^)(NSArray&lt;NSHTTPCookie *&gt; *))completionHandler;
</del><ins>+- (void)allCookies:(void (^)(NSArray&lt;NSHTTPCookie *&gt; *))completionHandler;
</ins><span class="cx"> 
</span><del>-/*! @abstract Fetches all of the stored cookies for the given URL.
- @param completionHandler A block to invoke with the fetched cookies.
- */
-- (void)fetchCookiesForURL:(NSURL *)url completionHandler:(void (^)(NSArray&lt;NSHTTPCookie *&gt; *))completionHandler;
-
</del><span class="cx"> /*! @abstract Set a cookie.
</span><span class="cx">  @param cookie The cookie to set.
</span><span class="cx">  @param completionHandler A block to invoke once the cookie has been stored.
</span><span class="lines">@@ -55,36 +57,23 @@
</span><span class="cx">  */
</span><span class="cx"> - (void)setCookie:(NSHTTPCookie *)cookie completionHandler:(nullable void (^)())completionHandler;
</span><span class="cx"> 
</span><del>-/*! @abstract Adds an array cookies to the cookie store, following the cookie accept policy.
- @param cookies The cookies to set.
- @param URL The URL from which the cookies were sent.
- @param mainDocumentURL The main document URL to be used as a base for the &quot;same domain as main document&quot; policy.
- @param completionHandler A block to invoke once the cookies have been stored.
- */
-- (void)setCookies:(NSArray&lt;NSHTTPCookie *&gt; *)cookies forURL:(NSURL *)url mainDocumentURL:(nullable NSURL *)mainDocumentURL completionHandler:(nullable void (^)())completionHandler;
-
</del><span class="cx"> /*! @abstract Delete the specified cookie.
</span><span class="cx">  @param completionHandler A block to invoke once the cookie has been deleted.
</span><span class="cx">  */
</span><span class="cx"> - (void)deleteCookie:(NSHTTPCookie *)cookie completionHandler:(nullable void (^)())completionHandler;
</span><span class="cx"> 
</span><del>-/*! @abstract Delete all cookies from the cookie storage since the provided date.
- @param date The date after which set cookies should be removed.
- @param completionHandler A block to invoke once the cookies have been deleted.
</del><ins>+/*! @abstract Adds a WKHTTPCookieStoreObserver object with the cookie store.
+ @param observer The observer object to add.
+ @discussion The observer is not retained by the receiver. It is your responsibility
+ to unregister the observer before it becomes invalid.
</ins><span class="cx">  */
</span><del>-- (void)removeCookiesSinceDate:(NSDate *)date completionHandler:(nullable void (^)())completionHandler;
</del><ins>+- (void)addObserver:(id&lt;WKHTTPCookieStoreObserver&gt;)observer;
</ins><span class="cx"> 
</span><del>-/*! @abstract Sets the cookie accept policy preference of the receiver.
- @param policy The cookie accept policy to set.
- @param completionHandler A block to invoke once the policy has been set.
</del><ins>+/*! @abstract Removes a WKHTTPCookieStoreObserver object from the cookie store.
+ @param observer The observer to remove.
</ins><span class="cx">  */
</span><del>-- (void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)policy completionHandler:(nullable void (^)())completionHandler;
</del><ins>+- (void)removeObserver:(id&lt;WKHTTPCookieStoreObserver&gt;)observer;
</ins><span class="cx"> 
</span><del>-/*! @abstract Fetches the cookie accept policy preference of the receiver.
- @param completionHandler A block to invoke with the fetched policy.
- */
-- (void)fetchCookieAcceptPolicy:(void (^)(NSHTTPCookieAcceptPolicy))completionHandler;
-
</del><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> NS_ASSUME_NONNULL_END
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKHTTPCookieStoremm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKHTTPCookieStore.mm (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKHTTPCookieStore.mm        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKHTTPCookieStore.mm        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -28,11 +28,13 @@
</span><span class="cx"> 
</span><span class="cx"> #if WK_API_ENABLED
</span><span class="cx"> 
</span><del>-#include &quot;HTTPCookieAcceptPolicy.h&quot;
-#include &lt;WebCore/CFNetworkSPI.h&gt;
-#include &lt;WebCore/Cookie.h&gt;
-#include &lt;WebCore/URL.h&gt;
-#include &lt;wtf/RetainPtr.h&gt;
</del><ins>+#import &quot;HTTPCookieAcceptPolicy.h&quot;
+#import &quot;WeakObjCPtr.h&quot;
+#import &lt;WebCore/CFNetworkSPI.h&gt;
+#import &lt;WebCore/Cookie.h&gt;
+#import &lt;WebCore/URL.h&gt;
+#import &lt;wtf/HashMap.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> static NSArray&lt;NSHTTPCookie *&gt; *coreCookiesToNSCookies(const Vector&lt;WebCore::Cookie&gt;&amp; coreCookies)
</span><span class="cx"> {
</span><span class="lines">@@ -44,16 +46,37 @@
</span><span class="cx">     return nsCookies;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-@implementation WKHTTPCookieStore
</del><ins>+class WKHTTPCookieStoreObserver : public API::HTTPCookieStore::Observer {
+public:
+    explicit WKHTTPCookieStoreObserver(id&lt;WKHTTPCookieStoreObserver&gt; observer)
+        : m_observer(observer)
+    {
+    }
</ins><span class="cx"> 
</span><ins>+private:
+    void cookiesDidChange(API::HTTPCookieStore&amp; cookieStore) final
+    {
+        [m_observer.get() cookiesDidChangeInCookieStore:WebKit::wrapper(cookieStore)];
+    }
+
+    WebKit::WeakObjCPtr&lt;id&lt;WKHTTPCookieStoreObserver&gt;&gt; m_observer;
+};
+
+@implementation WKHTTPCookieStore {
+    HashMap&lt;id&lt;WKHTTPCookieStoreObserver&gt;, std::unique_ptr&lt;WKHTTPCookieStoreObserver&gt;&gt; _observers;
+}
+
</ins><span class="cx"> - (void)dealloc
</span><span class="cx"> {
</span><ins>+    for (auto&amp; observer : _observers.values())
+        _cookieStore-&gt;unregisterObserver(*observer);
+
</ins><span class="cx">     _cookieStore-&gt;API::HTTPCookieStore::~HTTPCookieStore();
</span><span class="cx"> 
</span><span class="cx">     [super dealloc];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)fetchCookies:(void (^)(NSArray&lt;NSHTTPCookie *&gt; *))completionHandler
</del><ins>+- (void)allCookies:(void (^)(NSArray&lt;NSHTTPCookie *&gt; *))completionHandler
</ins><span class="cx"> {
</span><span class="cx">     _cookieStore-&gt;cookies([handler = adoptNS([completionHandler copy])](const Vector&lt;WebCore::Cookie&gt;&amp; cookies) {
</span><span class="cx">         auto rawHandler = (void (^)(NSArray&lt;NSHTTPCookie *&gt; *))handler.get();
</span><span class="lines">@@ -61,14 +84,6 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)fetchCookiesForURL:(NSURL *)url completionHandler:(void (^)(NSArray&lt;NSHTTPCookie *&gt; *))completionHandler
-{
-    _cookieStore-&gt;cookies(url, [handler = adoptNS([completionHandler copy])](const Vector&lt;WebCore::Cookie&gt;&amp; cookies) {
-        auto rawHandler = (void (^)(NSArray&lt;NSHTTPCookie *&gt; *))handler.get();
-        rawHandler(coreCookiesToNSCookies(cookies));
-    });
-}
-
</del><span class="cx"> - (void)setCookie:(NSHTTPCookie *)cookie completionHandler:(void (^)())completionHandler
</span><span class="cx"> {
</span><span class="cx">     _cookieStore-&gt;setCookie(cookie, [handler = adoptNS([completionHandler copy])]() {
</span><span class="lines">@@ -88,67 +103,25 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)setCookies:(NSArray&lt;NSHTTPCookie *&gt; *)cookies forURL:(NSURL *)URL mainDocumentURL:(NSURL *)mainDocumentURL completionHandler:(void (^)())completionHandler
</del><ins>+- (void)addObserver:(id&lt;WKHTTPCookieStoreObserver&gt;)observer
</ins><span class="cx"> {
</span><del>-    Vector&lt;WebCore::Cookie&gt; coreCookies;
-    coreCookies.reserveInitialCapacity(cookies.count);
-    for (NSHTTPCookie *cookie : cookies)
-        coreCookies.uncheckedAppend(cookie);
</del><ins>+    auto result = _observers.add(observer, nullptr);
+    if (!result.isNewEntry)
+        return;
</ins><span class="cx"> 
</span><del>-    _cookieStore-&gt;setCookies(coreCookies, URL, mainDocumentURL, [handler = adoptNS([completionHandler copy])]() {
-        auto rawHandler = (void (^)())handler.get();
-        if (rawHandler)
-            rawHandler();
-    });
</del><ins>+    result.iterator-&gt;value = std::make_unique&lt;WKHTTPCookieStoreObserver&gt;(observer);
+    _cookieStore-&gt;registerObserver(*result.iterator-&gt;value);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)removeCookiesSinceDate:(NSDate *)date completionHandler:(void (^)())completionHandler
</del><ins>+- (void)removeObserver:(id&lt;WKHTTPCookieStoreObserver&gt;)observer
</ins><span class="cx"> {
</span><del>-    auto systemClockTime = std::chrono::system_clock::time_point(std::chrono::duration_cast&lt;std::chrono::system_clock::duration&gt;(std::chrono::duration&lt;double&gt;(date.timeIntervalSince1970)));
</del><ins>+    auto result = _observers.take(observer);
+    if (!result)
+        return;
</ins><span class="cx"> 
</span><del>-    _cookieStore-&gt;removeCookiesSinceDate(systemClockTime, [handler = adoptNS([completionHandler copy])]() {
-        auto rawHandler = (void (^)())handler.get();
-        if (rawHandler)
-            rawHandler();
-    });
</del><ins>+    _cookieStore-&gt;unregisterObserver(*result);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)policy completionHandler:(void (^)())completionHandler
-{
-    _cookieStore-&gt;setHTTPCookieAcceptPolicy(policy, [handler = adoptNS([completionHandler copy])]() {
-        auto rawHandler = (void (^)())handler.get();
-        if (rawHandler)
-            rawHandler();
-    });
-}
-
-static NSHTTPCookieAcceptPolicy kitCookiePolicyToNSCookiePolicy(WebKit::HTTPCookieAcceptPolicy kitPolicy)
-{
-    switch (kitPolicy) {
-    case WebKit::HTTPCookieAcceptPolicyAlways:
-        return NSHTTPCookieAcceptPolicyAlways;
-    case WebKit::HTTPCookieAcceptPolicyNever:
-        return NSHTTPCookieAcceptPolicyNever;
-    case WebKit::HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:
-        return NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain;
-    case WebKit::HTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain:
-        // Cast required because of CFNetworkSPI.
-        return static_cast&lt;NSHTTPCookieAcceptPolicy&gt;(NSHTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain);
-    default:
-        ASSERT_NOT_REACHED();
-    }
-
-    return NSHTTPCookieAcceptPolicyNever;
-}
-
-- (void)fetchCookieAcceptPolicy:(void (^)(NSHTTPCookieAcceptPolicy))completionHandler
-{
-    _cookieStore-&gt;getHTTPCookieAcceptPolicy([handler = adoptNS([completionHandler copy])](WebKit::HTTPCookieAcceptPolicy policy) {
-        auto rawHandler = (void (^)(NSHTTPCookieAcceptPolicy))handler.get();
-        rawHandler(kitCookiePolicyToNSCookiePolicy(policy));
-    });
-}
-
</del><span class="cx"> #pragma mark WKObject protocol implementation
</span><span class="cx"> 
</span><span class="cx"> - (API::Object&amp;)_apiObject
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessCocoaWebProcessPoolCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -296,6 +296,10 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101100
</span><span class="cx">     RetainPtr&lt;CFDataRef&gt; cookieStorageData = adoptCF(CFHTTPCookieStorageCreateIdentifyingData(kCFAllocatorDefault, [[NSHTTPCookieStorage sharedHTTPCookieStorage] _cookieStorage]));
</span><ins>+
+    static int i = 0;
+    [(NSData *)cookieStorageData.get() writeToFile:[NSString stringWithFormat:@&quot;/Volumes/Data/FujiUser/dump%i.plist&quot;, i++] atomically:NO];
+
</ins><span class="cx">     ASSERT(parameters.uiProcessCookieStorageIdentifier.isEmpty());
</span><span class="cx">     parameters.uiProcessCookieStorageIdentifier.append(CFDataGetBytePtr(cookieStorageData.get()), CFDataGetLength(cookieStorageData.get()));
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebCookieManagerProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebCookieManagerProxy.cpp (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebCookieManagerProxy.cpp        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/WebCookieManagerProxy.cpp        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -60,6 +60,7 @@
</span><span class="cx"> 
</span><span class="cx"> WebCookieManagerProxy::~WebCookieManagerProxy()
</span><span class="cx"> {
</span><ins>+    ASSERT(m_cookieObservers.isEmpty());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebCookieManagerProxy::initializeClient(const WKCookieManagerClientBase* client)
</span><span class="lines">@@ -75,6 +76,17 @@
</span><span class="cx">     invalidateCallbackMap(m_httpCookieAcceptPolicyCallbacks, CallbackBase::Error::OwnerWasInvalidated);
</span><span class="cx">     invalidateCallbackMap(m_voidCallbacks, CallbackBase::Error::OwnerWasInvalidated);
</span><span class="cx">     invalidateCallbackMap(m_getCookiesCallbacks, CallbackBase::Error::OwnerWasInvalidated);
</span><ins>+
+    Vector&lt;Observer*&gt; observers;
+    for (auto&amp; observerSet : m_cookieObservers.values()) {
+        for (auto* observer : observerSet)
+            observers.append(observer);
+    }
+
+    for (auto* observer : observers)
+        observer-&gt;managerDestroyed();
+
+    ASSERT(m_cookieObservers.isEmpty());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebCookieManagerProxy::processDidClose(WebProcessProxy*)
</span><span class="lines">@@ -212,19 +224,50 @@
</span><span class="cx">     processPool()-&gt;sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::StopObservingCookieChanges(sessionID));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebCookieManagerProxy::setCookieObserverCallback(SessionID sessionID, std::function&lt;void ()&gt;&amp;&amp; callback)
</del><ins>+
+void WebCookieManagerProxy::setCookieObserverCallback(WebCore::SessionID sessionID, std::function&lt;void ()&gt;&amp;&amp; callback)
</ins><span class="cx"> {
</span><span class="cx">     if (callback)
</span><del>-        m_cookieObservers.set(sessionID, WTFMove(callback));
</del><ins>+        m_legacyCookieObservers.set(sessionID, WTFMove(callback));
</ins><span class="cx">     else
</span><del>-        m_cookieObservers.remove(sessionID);
</del><ins>+        m_legacyCookieObservers.remove(sessionID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebCookieManagerProxy::registerObserver(WebCore::SessionID sessionID, Observer&amp; observer)
+{
+    auto result = m_cookieObservers.set(sessionID, HashSet&lt;Observer*&gt;());
+    result.iterator-&gt;value.add(&amp;observer);
+
+    if (result.isNewEntry)
+        startObservingCookieChanges(sessionID);
+}
+
+void WebCookieManagerProxy::unregisterObserver(WebCore::SessionID sessionID, Observer&amp; observer)
+{
+    auto iterator = m_cookieObservers.find(sessionID);
+    if (iterator == m_cookieObservers.end())
+        return;
+
+    iterator-&gt;value.remove(&amp;observer);
+    if (!iterator-&gt;value.isEmpty())
+        return;
+
+    m_cookieObservers.remove(iterator);
+    stopObservingCookieChanges(sessionID);
+}
+
</ins><span class="cx"> void WebCookieManagerProxy::cookiesDidChange(SessionID sessionID)
</span><span class="cx"> {
</span><span class="cx">     m_client.cookiesDidChange(this);
</span><del>-    if (auto callback = m_cookieObservers.get(sessionID))
</del><ins>+    if (auto callback = m_legacyCookieObservers.get(sessionID))
</ins><span class="cx">         callback();
</span><ins>+
+    auto iterator = m_cookieObservers.find(sessionID);
+    if (iterator == m_cookieObservers.end())
+        return;
+
+    for (auto* observer : iterator-&gt;value)
+        observer-&gt;cookiesDidChange();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebCookieManagerProxy::setHTTPCookieAcceptPolicy(SessionID, HTTPCookieAcceptPolicy policy, Function&lt;void (CallbackBase::Error)&gt;&amp;&amp; callbackFunction)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebCookieManagerProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebCookieManagerProxy.h (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebCookieManagerProxy.h        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/WebCookieManagerProxy.h        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -88,6 +88,16 @@
</span><span class="cx"> 
</span><span class="cx">     void setCookieObserverCallback(WebCore::SessionID, std::function&lt;void ()&gt;&amp;&amp;);
</span><span class="cx"> 
</span><ins>+    class Observer {
+    public:
+        virtual ~Observer() { }
+        virtual void cookiesDidChange() = 0;
+        virtual void managerDestroyed() = 0;
+    };
+
+    void registerObserver(WebCore::SessionID, Observer&amp;);
+    void unregisterObserver(WebCore::SessionID, Observer&amp;);
+
</ins><span class="cx"> #if USE(SOUP)
</span><span class="cx">     void setCookiePersistentStorage(const String&amp; storagePath, uint32_t storageType);
</span><span class="cx">     void getCookiePersistentStorage(String&amp; storagePath, uint32_t&amp; storageType) const;
</span><span class="lines">@@ -128,7 +138,8 @@
</span><span class="cx">     HashMap&lt;uint64_t, RefPtr&lt;VoidCallback&gt;&gt; m_voidCallbacks;
</span><span class="cx">     HashMap&lt;uint64_t, RefPtr&lt;GetCookiesCallback&gt;&gt; m_getCookiesCallbacks;
</span><span class="cx"> 
</span><del>-    HashMap&lt;WebCore::SessionID, std::function&lt;void ()&gt;&gt; m_cookieObservers;
</del><ins>+    HashMap&lt;WebCore::SessionID, std::function&lt;void ()&gt;&gt; m_legacyCookieObservers;
+    HashMap&lt;WebCore::SessionID, HashSet&lt;Observer*&gt;&gt; m_cookieObservers;
</ins><span class="cx"> 
</span><span class="cx">     WebCookieManagerProxyClient m_client;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessPoolcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -115,10 +115,65 @@
</span><span class="cx"> 
</span><span class="cx"> DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, processPoolCounter, (&quot;WebProcessPool&quot;));
</span><span class="cx"> 
</span><ins>+static uint64_t generateListenerIdentifier()
+{
+    static uint64_t nextIdentifier = 1;
+    return nextIdentifier++;
+}
+
+static HashMap&lt;uint64_t, Function&lt;void(WebProcessPool&amp;)&gt;&gt;&amp; processPoolCreationListenerFunctionMap()
+{
+    static NeverDestroyed&lt;HashMap&lt;uint64_t, Function&lt;void(WebProcessPool&amp;)&gt;&gt;&gt; map;
+    return map;
+}
+
+uint64_t WebProcessPool::registerProcessPoolCreationListener(Function&lt;void(WebProcessPool&amp;)&gt;&amp;&amp; function)
+{
+    ASSERT(function);
+
+    auto identifier = generateListenerIdentifier();
+    processPoolCreationListenerFunctionMap().set(identifier, WTFMove(function));
+    return identifier;
+}
+
+void WebProcessPool::unregisterProcessPoolCreationListener(uint64_t identifier)
+{
+    processPoolCreationListenerFunctionMap().remove(identifier);
+}
+
</ins><span class="cx"> Ref&lt;WebProcessPool&gt; WebProcessPool::create(API::ProcessPoolConfiguration&amp; configuration)
</span><span class="cx"> {
</span><span class="cx">     InitializeWebKit2();
</span><del>-    return adoptRef(*new WebProcessPool(configuration));
</del><ins>+    auto newPool = adoptRef(*new WebProcessPool(configuration));
+
+    auto&amp; listenerMap = processPoolCreationListenerFunctionMap();
+
+    Vector&lt;uint64_t&gt; identifiers;
+    identifiers.reserveInitialCapacity(listenerMap.size());
+    for (auto identifier : listenerMap.keys())
+        identifiers.uncheckedAppend(identifier);
+
+    for (auto identifier : identifiers) {
+        auto iterator = listenerMap.find(identifier);
+        if (iterator == listenerMap.end())
+            continue;
+
+        // To make sure the Function object stays alive until after the function call has been made,
+        // we temporarily move it out of the map.
+        // This protects it from the Function calling unregisterProcessPoolCreationListener thereby
+        // removing itself from the map of listeners.
+        // If the identifier still exists in the map later, we move it back in.
+        Function&lt;void(WebProcessPool&amp;)&gt; function = WTFMove(iterator-&gt;value);
+        function(newPool.get());
+
+        iterator = listenerMap.find(identifier);
+        if (iterator != listenerMap.end()) {
+            ASSERT(!iterator-&gt;value);
+            iterator-&gt;value = WTFMove(function);
+        }
+    }
+
+    return newPool;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static Vector&lt;WebProcessPool*&gt;&amp; processPools()
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessPoolh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessPool.h (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessPool.h        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/WebProcessPool.h        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -399,6 +399,9 @@
</span><span class="cx">     void setCookieStoragePartitioningEnabled(bool);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    static uint64_t registerProcessPoolCreationListener(Function&lt;void(WebProcessPool&amp;)&gt;&amp;&amp;);
+    static void unregisterProcessPoolCreationListener(uint64_t identifier);
+
</ins><span class="cx"> private:
</span><span class="cx">     void platformInitialize();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebsiteDataWebsiteDataStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -127,6 +127,12 @@
</span><span class="cx">     return **pools.begin();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+WebProcessPool* WebsiteDataStore::processPoolForCookieStorageNotifications()
+{
+    auto pools = processPools(1, false);
+    return pools.isEmpty() ? nullptr : pools.begin()-&gt;get();
+}
+
</ins><span class="cx"> void WebsiteDataStore::resolveDirectoriesIfNecessary()
</span><span class="cx"> {
</span><span class="cx">     if (m_hasResolvedDirectories)
</span><span class="lines">@@ -1130,8 +1136,24 @@
</span><span class="cx">         m_storageManager-&gt;processDidCloseConnection(webProcessProxy, connection);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-HashSet&lt;RefPtr&lt;WebProcessPool&gt;&gt; WebsiteDataStore::processPools(size_t count) const
</del><ins>+bool WebsiteDataStore::isAssociatedProcessPool(WebProcessPool&amp; processPool) const
</ins><span class="cx"> {
</span><ins>+    if (auto dataStore = processPool.websiteDataStore()) {
+        if (&amp;dataStore-&gt;websiteDataStore() == this)
+            return true;
+    } else if (&amp;API::WebsiteDataStore::defaultDataStore()-&gt;websiteDataStore() == this) {
+        // If a process pool doesn't have an explicit data store and this is the default WebsiteDataStore,
+        // add that process pool to the set.
+        // FIXME: This behavior is weird and necessitated by the fact that process pools don't always
+        // have a data store; they should.
+        return true;
+    }
+
+    return false;
+}
+
+HashSet&lt;RefPtr&lt;WebProcessPool&gt;&gt; WebsiteDataStore::processPools(size_t count, bool ensureAPoolExists) const
+{
</ins><span class="cx">     HashSet&lt;RefPtr&lt;WebProcessPool&gt;&gt; processPools;
</span><span class="cx">     for (auto&amp; process : processes())
</span><span class="cx">         processPools.add(&amp;process-&gt;processPool());
</span><span class="lines">@@ -1139,25 +1161,17 @@
</span><span class="cx">     if (processPools.isEmpty()) {
</span><span class="cx">         // Check if we're one of the legacy data stores.
</span><span class="cx">         for (auto&amp; processPool : WebProcessPool::allProcessPools()) {
</span><del>-            if (auto dataStore = processPool-&gt;websiteDataStore()) {
-                if (&amp;dataStore-&gt;websiteDataStore() == this) {
-                    processPools.add(processPool);
-                    break;
-                }
-            } else if (&amp;API::WebsiteDataStore::defaultDataStore()-&gt;websiteDataStore() == this) {
-                // If a process pool doesn't have an explicit data store and this is the default WebsiteDataStore,
-                // add that process pool to the set.
-                // FIXME: This behavior is weird and necessitated by the fact that process pools don't always
-                // have a data store; they should.
-                processPools.add(processPool);
-            }
</del><ins>+            if (!isAssociatedProcessPool(*processPool))
+                continue;
</ins><span class="cx"> 
</span><ins>+            processPools.add(processPool);
+
</ins><span class="cx">             if (processPools.size() == count)
</span><span class="cx">                 break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (processPools.isEmpty() &amp;&amp; count) {
</del><ins>+    if (processPools.isEmpty() &amp;&amp; count &amp;&amp; ensureAPoolExists) {
</ins><span class="cx">         auto processPool = WebProcessPool::create(API::ProcessPoolConfiguration::createWithWebsiteDataStoreConfiguration(m_configuration));
</span><span class="cx">         processPools.add(processPool.ptr());
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebsiteDataWebsiteDataStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -104,6 +104,8 @@
</span><span class="cx">     StorageManager* storageManager() { return m_storageManager.get(); }
</span><span class="cx"> 
</span><span class="cx">     Ref&lt;WebProcessPool&gt; processPoolForCookieStorageOperations();
</span><ins>+    WebProcessPool* processPoolForCookieStorageNotifications();
+    bool isAssociatedProcessPool(WebProcessPool&amp;) const;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     explicit WebsiteDataStore(WebCore::SessionID);
</span><span class="lines">@@ -121,7 +123,7 @@
</span><span class="cx">     void platformDestroy();
</span><span class="cx">     static void platformRemoveRecentSearches(std::chrono::system_clock::time_point);
</span><span class="cx"> 
</span><del>-    HashSet&lt;RefPtr&lt;WebProcessPool&gt;&gt; processPools(size_t count = std::numeric_limits&lt;size_t&gt;::max()) const;
</del><ins>+    HashSet&lt;RefPtr&lt;WebProcessPool&gt;&gt; processPools(size_t count = std::numeric_limits&lt;size_t&gt;::max(), bool ensureAPoolExists = true) const;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(NETSCAPE_PLUGIN_API)
</span><span class="cx">     Vector&lt;PluginModuleInfo&gt; plugins() const;
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Tools/ChangeLog        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2017-03-16  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Update the WKHTTPCookieStore API to be simpler and add observers.
+        &lt;rdar://problem/31096000&gt; and https://bugs.webkit.org/show_bug.cgi?id=169776
+
+        Reviewed by Alex Christensen.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStore.mm: Renamed from Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStorage.mm.
+        (-[CookieObserver cookiesDidChangeInCookieStore:]):
+        (TEST): Also test delete and observers.
+
</ins><span class="cx"> 2017-03-16  Kocsen Chung  &lt;kocsen_chung@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix quotes around --pretty format git flag.
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -154,7 +154,7 @@
</span><span class="cx">                 51BCEE4F1C84F53B0042C82E /* IndexedDBMultiProcess-2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51BCEE4D1C84F52C0042C82E /* IndexedDBMultiProcess-2.html */; };
</span><span class="cx">                 51CD1C6C1B38CE4300142CA5 /* ModalAlerts.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51CD1C6A1B38CE3600142CA5 /* ModalAlerts.mm */; };
</span><span class="cx">                 51CD1C721B38D48400142CA5 /* modal-alerts-in-new-about-blank-window.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51CD1C711B38D48400142CA5 /* modal-alerts-in-new-about-blank-window.html */; };
</span><del>-                51D124981E763B02002B2820 /* WKHTTPCookieStorage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51D124971E763AF8002B2820 /* WKHTTPCookieStorage.mm */; };
</del><ins>+                51D124981E763B02002B2820 /* WKHTTPCookieStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51D124971E763AF8002B2820 /* WKHTTPCookieStore.mm */; };
</ins><span class="cx">                 51D1249B1E785425002B2820 /* CookieManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6F3F29013342FEB00A6BF19 /* CookieManager.cpp */; };
</span><span class="cx">                 51E5C7021919C3B200D8B3E1 /* simple2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51E780361919AFF8001829A2 /* simple2.html */; };
</span><span class="cx">                 51E5C7031919C3B200D8B3E1 /* simple3.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 51E780371919AFF8001829A2 /* simple3.html */; };
</span><span class="lines">@@ -1056,7 +1056,7 @@
</span><span class="cx">                 51CB4AD71B3A079C00C1B1C6 /* ModalAlertsSPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModalAlertsSPI.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51CD1C6A1B38CE3600142CA5 /* ModalAlerts.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ModalAlerts.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51CD1C711B38D48400142CA5 /* modal-alerts-in-new-about-blank-window.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = &quot;modal-alerts-in-new-about-blank-window.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                51D124971E763AF8002B2820 /* WKHTTPCookieStorage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKHTTPCookieStorage.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><ins>+                51D124971E763AF8002B2820 /* WKHTTPCookieStore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKHTTPCookieStore.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 51E5C7041919EA5F00D8B3E1 /* ShouldKeepCurrentBackForwardListItemInList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShouldKeepCurrentBackForwardListItemInList.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51E6A8921D2F1BEC00C004B6 /* LocalStorageClear.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LocalStorageClear.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51E6A8951D2F1C7700C004B6 /* LocalStorageClear.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = LocalStorageClear.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -1661,7 +1661,7 @@
</span><span class="cx">                                 5120C83C1E6750790025B250 /* WebsiteDataStoreCustomPaths.mm */,
</span><span class="cx">                                 5C9E56841DF9143D00C9EE33 /* WebsitePolicies.mm */,
</span><span class="cx">                                 1F83571A1D3FFB0E00E3967B /* WKBackForwardList.mm */,
</span><del>-                                51D124971E763AF8002B2820 /* WKHTTPCookieStorage.mm */,
</del><ins>+                                51D124971E763AF8002B2820 /* WKHTTPCookieStore.mm */,
</ins><span class="cx">                                 375E0E151D66674400EFEC2C /* WKNSNumber.mm */,
</span><span class="cx">                                 37B47E2E1D64E7CA005F4EFF /* WKObject.mm */,
</span><span class="cx">                                 A14AAB611E78D7DE00C1ADC2 /* WKPDFView.mm */,
</span><span class="lines">@@ -2746,7 +2746,7 @@
</span><span class="cx">                                 7CCE7EF41A411AE600447C4C /* FindMatches.mm in Sources */,
</span><span class="cx">                                 7C83E0401D0A63E300FEBCF3 /* FirstResponderScrollingPosition.mm in Sources */,
</span><span class="cx">                                 7C83E0BC1D0A650700FEBCF3 /* FixedLayoutSize.mm in Sources */,
</span><del>-                                51D124981E763B02002B2820 /* WKHTTPCookieStorage.mm in Sources */,
</del><ins>+                                51D124981E763B02002B2820 /* WKHTTPCookieStore.mm in Sources */,
</ins><span class="cx">                                 7CCE7EF51A411AE600447C4C /* ForceRepaint.cpp in Sources */,
</span><span class="cx">                                 37B47E301D64E7CA005F4EFF /* WKObject.mm in Sources */,
</span><span class="cx">                                 7CCE7EC01A411A7E00447C4C /* FragmentNavigation.mm in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2CocoaWKHTTPCookieStoragemm"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStorage.mm (214077 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStorage.mm        2017-03-16 23:19:39 UTC (rev 214077)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStorage.mm        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -1,119 +0,0 @@
</span><del>-/*
- * Copyright (C) 2017 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.
- */
-
-#include &quot;config.h&quot;
-
-#import &quot;PlatformUtilities.h&quot;
-#import &lt;WebKit/WKFoundation.h&gt;
-#import &lt;WebKit/WKHTTPCookieStore.h&gt;
-#import &lt;WebKit/WKWebsiteDataStorePrivate.h&gt;
-#import &lt;wtf/RetainPtr.h&gt;
-
-#if WK_API_ENABLED
-
-static bool gotFlag;
-
-TEST(WebKit2, WKHTTPCookieStorage)
-{
-    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
-    [webView loadHTMLString:@&quot;Oh hello&quot; baseURL:[NSURL URLWithString:@&quot;http://webkit.org&quot;]];
-
-    RetainPtr&lt;WKHTTPCookieStore&gt; cookieStore = [WKWebsiteDataStore defaultDataStore]._httpCookieStore;
-
-    NSArray&lt;NSHTTPCookie *&gt; *cookies = nil;
-    [cookieStore fetchCookies:[cookiesPtr = &amp;cookies](NSArray&lt;NSHTTPCookie *&gt; *nsCookies) {
-        *cookiesPtr = [nsCookies retain];
-        gotFlag = true;
-    }];
-
-    TestWebKitAPI::Util::run(&amp;gotFlag);
-
-    ASSERT_EQ(cookies.count, 0u);
-    [cookies release];
-
-    gotFlag = false;
-
-    RetainPtr&lt;NSHTTPCookie&gt; cookie1 = [NSHTTPCookie cookieWithProperties:@{
-        NSHTTPCookiePath: @&quot;/&quot;,
-        NSHTTPCookieName: @&quot;CookieName&quot;,
-        NSHTTPCookieValue: @&quot;CookieValue&quot;,
-        NSHTTPCookieDomain: @&quot;.www.webkit.org&quot;,
-        NSHTTPCookieSecure: @&quot;TRUE&quot;,
-        NSHTTPCookieDiscard: @&quot;TRUE&quot;,
-        NSHTTPCookieMaximumAge: @&quot;10000&quot;,
-    }];
-
-    RetainPtr&lt;NSHTTPCookie&gt; cookie2 = [NSHTTPCookie cookieWithProperties:@{
-        NSHTTPCookiePath: @&quot;/path&quot;,
-        NSHTTPCookieName: @&quot;OtherCookieName&quot;,
-        NSHTTPCookieValue: @&quot;OtherCookieValue&quot;,
-        NSHTTPCookieDomain: @&quot;.www.w3c.org&quot;,
-        NSHTTPCookieMaximumAge: @&quot;10000&quot;,
-    }];
-
-    [cookieStore setCookie:cookie1.get() completionHandler:[](){
-        gotFlag = true;
-    }];
-
-    TestWebKitAPI::Util::run(&amp;gotFlag);
-    gotFlag = false;
-
-    [cookieStore setCookie:cookie2.get() completionHandler:[](){
-        gotFlag = true;
-    }];
-
-    TestWebKitAPI::Util::run(&amp;gotFlag);
-    gotFlag = false;
-
-    [cookieStore fetchCookies:[cookiesPtr = &amp;cookies](NSArray&lt;NSHTTPCookie *&gt; *nsCookies) {
-        *cookiesPtr = [nsCookies retain];
-        gotFlag = true;
-    }];
-
-    TestWebKitAPI::Util::run(&amp;gotFlag);
-
-    ASSERT_EQ(cookies.count, 2u);
-
-    for (NSHTTPCookie *cookie : cookies) {
-        if ([cookie.name isEqual:@&quot;CookieName&quot;]) {
-            ASSERT_TRUE([cookie1.get().path isEqualToString:cookie.path]);
-            ASSERT_TRUE([cookie1.get().value isEqualToString:cookie.value]);
-            ASSERT_TRUE([cookie1.get().domain isEqualToString:cookie.domain]);
-            ASSERT_TRUE(cookie1.get().secure);
-            ASSERT_TRUE(cookie1.get().sessionOnly);
-        } else {
-            ASSERT_TRUE([cookie2.get().path isEqualToString:cookie.path]);
-            ASSERT_TRUE([cookie2.get().value isEqualToString:cookie.value]);
-            ASSERT_TRUE([cookie2.get().name isEqualToString:cookie.name]);
-            ASSERT_TRUE([cookie2.get().domain isEqualToString:cookie.domain]);
-            ASSERT_FALSE(cookie2.get().secure);
-            ASSERT_FALSE(cookie2.get().sessionOnly);
-        }
-    }
-
-    [cookies release];
-}
-
-#endif
</del></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKit2CocoaWKHTTPCookieStoremmfromrev214077trunkToolsTestWebKitAPITestsWebKit2CocoaWKHTTPCookieStoragemm"></a>
<div class="copfile"><h4>Copied: trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStore.mm (from rev 214077, trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStorage.mm) (0 => 214078)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStore.mm                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/WKHTTPCookieStore.mm        2017-03-16 23:30:09 UTC (rev 214078)
</span><span class="lines">@@ -0,0 +1,170 @@
</span><ins>+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include &quot;config.h&quot;
+
+#import &quot;PlatformUtilities.h&quot;
+#import &lt;WebKit/WKFoundation.h&gt;
+#import &lt;WebKit/WKHTTPCookieStore.h&gt;
+#import &lt;WebKit/WKWebsiteDataStorePrivate.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+
+#if WK_API_ENABLED
+
+static bool gotFlag;
+uint64_t observerCallbacks;
+RetainPtr&lt;WKHTTPCookieStore&gt; globalCookieStore;
+
+@interface CookieObserver : NSObject&lt;WKHTTPCookieStoreObserver&gt;
+- (void)cookiesDidChangeInCookieStore:(WKHTTPCookieStore *)cookieStore;
+@end
+
+@implementation CookieObserver
+
+- (void)cookiesDidChangeInCookieStore:(WKHTTPCookieStore *)cookieStore
+{
+    ASSERT_EQ(cookieStore, globalCookieStore.get());
+    ++observerCallbacks;
+}
+
+@end
+
+TEST(WebKit2, WKHTTPCookieStore)
+{
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView loadHTMLString:@&quot;Oh hello&quot; baseURL:[NSURL URLWithString:@&quot;http://webkit.org&quot;]];
+
+    globalCookieStore = [WKWebsiteDataStore defaultDataStore]._httpCookieStore;
+    RetainPtr&lt;CookieObserver&gt; observer1 = adoptNS([[CookieObserver alloc] init]);
+    RetainPtr&lt;CookieObserver&gt; observer2 = adoptNS([[CookieObserver alloc] init]);
+    [globalCookieStore addObserver:observer1.get()];
+    [globalCookieStore addObserver:observer2.get()];
+
+    NSArray&lt;NSHTTPCookie *&gt; *cookies = nil;
+    [globalCookieStore allCookies:[cookiesPtr = &amp;cookies](NSArray&lt;NSHTTPCookie *&gt; *nsCookies) {
+        *cookiesPtr = [nsCookies retain];
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&amp;gotFlag);
+
+    ASSERT_EQ(cookies.count, 0u);
+    [cookies release];
+
+    gotFlag = false;
+
+    RetainPtr&lt;NSHTTPCookie&gt; cookie1 = [NSHTTPCookie cookieWithProperties:@{
+        NSHTTPCookiePath: @&quot;/&quot;,
+        NSHTTPCookieName: @&quot;CookieName&quot;,
+        NSHTTPCookieValue: @&quot;CookieValue&quot;,
+        NSHTTPCookieDomain: @&quot;.www.webkit.org&quot;,
+        NSHTTPCookieSecure: @&quot;TRUE&quot;,
+        NSHTTPCookieDiscard: @&quot;TRUE&quot;,
+        NSHTTPCookieMaximumAge: @&quot;10000&quot;,
+    }];
+
+    RetainPtr&lt;NSHTTPCookie&gt; cookie2 = [NSHTTPCookie cookieWithProperties:@{
+        NSHTTPCookiePath: @&quot;/path&quot;,
+        NSHTTPCookieName: @&quot;OtherCookieName&quot;,
+        NSHTTPCookieValue: @&quot;OtherCookieValue&quot;,
+        NSHTTPCookieDomain: @&quot;.www.w3c.org&quot;,
+        NSHTTPCookieMaximumAge: @&quot;10000&quot;,
+    }];
+
+    [globalCookieStore setCookie:cookie1.get() completionHandler:[](){
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&amp;gotFlag);
+    gotFlag = false;
+
+    [globalCookieStore setCookie:cookie2.get() completionHandler:[](){
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&amp;gotFlag);
+    gotFlag = false;
+
+    [globalCookieStore allCookies:[cookiesPtr = &amp;cookies](NSArray&lt;NSHTTPCookie *&gt; *nsCookies) {
+        *cookiesPtr = [nsCookies retain];
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&amp;gotFlag);
+    gotFlag = false;
+
+    ASSERT_EQ(cookies.count, 2u);
+    ASSERT_EQ(observerCallbacks, 4u);
+
+    for (NSHTTPCookie *cookie : cookies) {
+        if ([cookie.name isEqual:@&quot;CookieName&quot;]) {
+            ASSERT_TRUE([cookie1.get().path isEqualToString:cookie.path]);
+            ASSERT_TRUE([cookie1.get().value isEqualToString:cookie.value]);
+            ASSERT_TRUE([cookie1.get().domain isEqualToString:cookie.domain]);
+            ASSERT_TRUE(cookie1.get().secure);
+            ASSERT_TRUE(cookie1.get().sessionOnly);
+        } else {
+            ASSERT_TRUE([cookie2.get().path isEqualToString:cookie.path]);
+            ASSERT_TRUE([cookie2.get().value isEqualToString:cookie.value]);
+            ASSERT_TRUE([cookie2.get().name isEqualToString:cookie.name]);
+            ASSERT_TRUE([cookie2.get().domain isEqualToString:cookie.domain]);
+            ASSERT_FALSE(cookie2.get().secure);
+            ASSERT_FALSE(cookie2.get().sessionOnly);
+        }
+    }
+    [cookies release];
+
+    [globalCookieStore deleteCookie:cookie2.get() completionHandler:[](){
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&amp;gotFlag);
+    gotFlag = false;
+
+    [globalCookieStore allCookies:[cookiesPtr = &amp;cookies](NSArray&lt;NSHTTPCookie *&gt; *nsCookies) {
+        *cookiesPtr = [nsCookies retain];
+        gotFlag = true;
+    }];
+
+    TestWebKitAPI::Util::run(&amp;gotFlag);
+    gotFlag = false;
+
+    ASSERT_EQ(cookies.count, 1u);
+    ASSERT_EQ(observerCallbacks, 6u);
+
+    for (NSHTTPCookie *cookie : cookies) {
+        ASSERT_TRUE([cookie1.get().path isEqualToString:cookie.path]);
+        ASSERT_TRUE([cookie1.get().value isEqualToString:cookie.value]);
+        ASSERT_TRUE([cookie1.get().domain isEqualToString:cookie.domain]);
+        ASSERT_TRUE(cookie1.get().secure);
+        ASSERT_TRUE(cookie1.get().sessionOnly);
+    }
+    [cookies release];
+
+    [globalCookieStore removeObserver:observer1.get()];
+    [globalCookieStore removeObserver:observer2.get()];
+}
+
+#endif
</ins></span></pre>
</div>
</div>

</body>
</html>