<!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>[212183] 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/212183">212183</a></dd>
<dt>Author</dt> <dd>wilander@apple.com</dd>
<dt>Date</dt> <dd>2017-02-10 23:34:40 -0800 (Fri, 10 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Updates to Resource Load Statistics: Get the right website data store and introduce timeout for user interaction
https://bugs.webkit.org/show_bug.cgi?id=167474
&lt;rdar://problem/24681808&gt;
&lt;rdar://problem/24703286&gt;
&lt;rdar://problem/30290270&gt;

Source/WebCore:

This patch does the following:
1. Gets the right website data store. API::WebsiteDataStore::defaultDataStore()
    does not provide the right data store.
2. Introduces timeout for user interaction. A domain needs interaction every 30
    days to stay in that category.
3. Adds grandfathered to the statistics model in preparation for grandfathering of
    existing data records.
4. Adds test infrastructure to allow testing of the various rules in place for
    data records removal.
5. Fixes various smaller bugs that were found as part of setting up the tests.
6. Regresses the data records removal counting. We need to come up with a thread
    safe way of gathering removal statistics from more than one data store now
    that we potentially interact with multiple stores.
7. Adds a first set of layout tests for resource load statistics.

Reviewed by Andy Estes.

Tests: http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction.html
       http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction.html
       http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout.html
       http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction.html
       http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction.html

* dom/Document.cpp:
(WebCore::Document::updateLastHandledUserGestureTimestamp):
    This now calls ResourceLoadObserver::logUserInteraction() every time since
    we want to keep track of the most recent user interaction.
* loader/ResourceLoadObserver.cpp:
(WebCore::ResourceLoadObserver::statisticsStore):
    New getter used by WebResourceLoadStatisticsManager::resetToConsistentState().
(WebCore::reduceTimeResolutionToOneDay):
    Convenience function.
(WebCore::ResourceLoadObserver::logUserInteractionWithReducedTimeResolution):
    Reduces time resolution for privacy reasons.
(WebCore::ResourceLoadObserver::logUserInteraction):
(WebCore::ResourceLoadObserver::clearUserInteraction):
(WebCore::ResourceLoadObserver::hasHadUserInteraction):
(WebCore::ResourceLoadObserver::setPrevalentResource):
(WebCore::ResourceLoadObserver::isPrevalentResource):
(WebCore::ResourceLoadObserver::clearPrevalentResource):
(WebCore::ResourceLoadObserver::setTimeToLiveUserInteraction):
(WebCore::ResourceLoadObserver::fireDataModificationHandler):
    New functions that allow WebKitTestRunner to stage exact
    statistics, fire the handler, and test the outcome.
* loader/ResourceLoadObserver.h:
* loader/ResourceLoadStatistics.cpp:
(WebCore::ResourceLoadStatistics::encode):
(WebCore::ResourceLoadStatistics::decode):
(WebCore::ResourceLoadStatistics::toString):
(WebCore::ResourceLoadStatistics::merge):
    Support for statistics mostRecentUserInteraction, grandfathered, and
    dataRecordsRemoved.
* loader/ResourceLoadStatistics.h:
* loader/ResourceLoadStatisticsStore.cpp:
(WebCore::ResourceLoadStatisticsStore::setTimeToLiveUserInteraction):
    New function that allows WebKitTestRunner to test
    aging out of user interaction.
(WebCore::ResourceLoadStatisticsStore::hasHadRecentUserInteraction):
    Now takes into account the timestamp and ages
    out user interaction.
(WebCore::ResourceLoadStatisticsStore::prevalentResourceDomainsWithoutUserInteraction):
    Now makes use of ResourceLoadStatisticsStore::hasHadRecentUserInteraction().
* loader/ResourceLoadStatisticsStore.h:

Source/WebKit2:

This patch does the following:
1. Gets the right website data store. API::WebsiteDataStore::defaultDataStore()
    does not provide the right data store.
2. Introduces timeout for user interaction. A domain needs interaction every 30
    days to stay in that category.
3. Adds grandfathered to the statistics model in preparation for grandfathering of
    existing data records.
4. Adds test infrastructure to allow testing of the various rules in place for
    data records removal.
5. Fixes various smaller bugs that were found as part of setting up the tests.
6. Regresses the data records removal counting. We need to come up with a thread
    safe way of gathering removal statistics from more than one data store now
    that we potentially interact with multiple stores.
7. Adds a first set of layout tests for resource load statistics.

Reviewed by Andy Estes.

* PlatformEfl.cmake:
    Added UIProcess/WebResourceLoadStatisticsManager.cpp and
    UIProcess/API/C/WKResourceLoadStatisticsManager.cpp.
* PlatformGTK.cmake:
    Added UIProcess/WebResourceLoadStatisticsManager.cpp and
    UIProcess/API/C/WKResourceLoadStatisticsManager.cpp.
* PlatformMac.cmake:
    Added UIProcess/WebResourceLoadStatisticsManager.cpp and
    UIProcess/API/C/WKResourceLoadStatisticsManager.cpp.
* Shared/API/APIObject.h:
    Adds WebResourceLoadStatisticsManager to the Type enum.
* Shared/API/c/WKBase.h:
    Typedef of WKResourceLoadStatisticsManagerRef.
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder&lt;ResourceLoadStatistics&gt;::encode):
(IPC::ArgumentCoder&lt;ResourceLoadStatistics&gt;::decode):
    Adds support for statistics mostRecentUserInteraction, grandfathered, and
    dataRecordsRemoved.
* UIProcess/API/C/WKAPICast.h:
    Adds API mapping between WKResourceLoadStatisticsManagerRef and
    WebResourceLoadStatisticsManager.
* UIProcess/API/C/WKResourceLoadStatisticsManager.cpp: Added.
(WKResourceLoadStatisticsManagerGetTypeID):
(WKResourceLoadStatisticsManagerSetPrevalentResource):
(WKResourceLoadStatisticsManagerIsPrevalentResource):
(WKResourceLoadStatisticsManagerSetHasHadUserInteraction):
(WKResourceLoadStatisticsManagerIsHasHadUserInteraction):
(WKResourceLoadStatisticsManagerSetTimeToLiveUserInteraction):
(WKResourceLoadStatisticsManagerFireDataModificationHandler):
(WKResourceLoadStatisticsManagerSetNotifyPagesWhenDataRecordsWereScanned):
(WKResourceLoadStatisticsManagerSetShouldClassifyResourcesBeforeDataRecordsRemoval):
(WKResourceLoadStatisticsManagerSetMinimumTimeBetweeenDataRecordsRemoval):
(WKResourceLoadStatisticsManagerResetToConsistentState):
    API level bridge to WebResourceLoadStatisticsManager functions.
* UIProcess/API/C/WKResourceLoadStatisticsManager.h: Added.
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::deleteWebsiteDataForTopPrivatelyOwnedDomainsInAllPersistentDataStores):
    A way to delete website data in persistent store(s) configured by the
    embedding client. API::WebsiteDataStore::defaultDataStore() does not
    do this which caused us to skip session storage.
* UIProcess/WebProcessProxy.h:
* UIProcess/WebResourceLoadStatisticsManager.cpp: Added.
(WebKit::WebResourceLoadStatisticsManager::setPrevalentResource):
(WebKit::WebResourceLoadStatisticsManager::isPrevalentResource):
(WebKit::WebResourceLoadStatisticsManager::setHasHadUserInteraction):
(WebKit::WebResourceLoadStatisticsManager::hasHadUserInteraction):
(WebKit::WebResourceLoadStatisticsManager::setTimeToLiveUserInteraction):
(WebKit::WebResourceLoadStatisticsManager::fireDataModificationHandler):
(WebKit::WebResourceLoadStatisticsManager::setNotifyPagesWhenDataRecordsWereScanned):
(WebKit::WebResourceLoadStatisticsManager::setShouldClassifyResourcesBeforeDataRecordsRemoval):
(WebKit::WebResourceLoadStatisticsManager::setMinimumTimeBetweeenDataRecordsRemoval):
(WebKit::WebResourceLoadStatisticsManager::resetToConsistentState):
    Static functions to manage the state and behavior of the UI process'
    resource load statistics store.
* UIProcess/WebResourceLoadStatisticsManager.h: Added.
(WebKit::WebResourceLoadStatisticsManager::create):
* UIProcess/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
    An effect of a member variable rename. See header file comment below.
(WebKit::WebResourceLoadStatisticsStore::setNotifyPagesWhenDataRecordsWereScanned):
(WebKit::WebResourceLoadStatisticsStore::setShouldClassifyResourcesBeforeDataRecordsRemoval):
(WebKit::WebResourceLoadStatisticsStore::setMinimumTimeBetweeenDataRecordsRemoval):
    Three static functions for controlling the behavior of the store.
(WebKit::WebResourceLoadStatisticsStore::removeDataRecords):
    Changes:
    1. Covers all data record types.
    2. Allows data removal when m_lastTimeDataRecordsWereRemoved is not set.
    3. Moves the heavy lifting to WebsiteDataStore (see below).
    4. No longer counts removed data regressions.
(WebKit::WebResourceLoadStatisticsStore::processStatisticsAndDataRecords):
    See next comment.
(WebKit::WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated):
    WebResourceLoadStatisticsStore::processStatisticsAndDataRecords() is
    broken out of WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated
    to allow for statistics processing without prior classification.
    Tests need to set statistics and a run of the classifier may
    reset the data.
(WebKit::WebResourceLoadStatisticsStore::registerSharedResourceLoadObserver):
    Sets the notification callback which calls
    WebResourceLoadStatisticsStore::processStatisticsAndDataRecords().
* UIProcess/WebResourceLoadStatisticsStore.h:
(WebKit::WebResourceLoadStatisticsStore::coreStore):
    Renamed m_resourceStatisticsStore to m_resourceLoadStatisticsStore to
    harmonize with other naming.
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::fetchDataForTopPrivatelyOwnedDomains):
    This is now where matching is made between prevalent resources
    and data records. This function is used by
    WebsiteDataStore::removeDataForTopPrivatelyOwnedDomains().
(WebKit::WebsiteDataStore::removeDataForTopPrivatelyOwnedDomains):
    The function WebResourceLoadStatisticsStore::removeDataRecords()
    calls to get data records removed in all persistent stores.
* UIProcess/WebsiteData/WebsiteDataStore.h:
* WebKit2.xcodeproj/project.pbxproj:
* WebProcess/WebProcess.cpp:
(WebKit::m_resourceLoadStatisticsStore):
(WebKit::WebProcess::statisticsChangedTimerFired):
(WebKit::m_resourceLoadStatisticsStorage): Deleted.
    Renamed m_resourceLoadStatisticsStorage to m_resourceLoadStatisticsStore
    to harmonize with other naming.
* WebProcess/WebProcess.h:

Tools:

This patch adds test infrastructure to allow testing
of the various rules in place for data records removal.

Reviewed by Andy Estes.

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::didReceiveMessageToPage):
    Callback mechanism to tell pages that a website data store
    scan has happened.
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setStatisticsPrevalentResource):
(WTR::TestRunner::isStatisticsPrevalentResource):
(WTR::TestRunner::setStatisticsHasHadUserInteraction):
(WTR::TestRunner::isStatisticsHasHadUserInteraction):
(WTR::TestRunner::setStatisticsTimeToLiveUserInteraction):
(WTR::TestRunner::installStatisticsDidModifyDataRecordsCallback):
(WTR::TestRunner::statisticsDidModifyDataRecordsCallback):
(WTR::TestRunner::statisticsFireDataModificationHandler):
(WTR::TestRunner::setStatisticsNotifyPagesWhenDataRecordsWereScanned):
(WTR::TestRunner::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval):
(WTR::TestRunner::setStatisticsMinimumTimeBetweeenDataRecordsRemoval):
(WTR::TestRunner::statisticsResetToConsistentState):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::setStatisticsPrevalentResource):
(WTR::TestController::isStatisticsPrevalentResource):
(WTR::TestController::setStatisticsHasHadUserInteraction):
(WTR::TestController::isStatisticsHasHadUserInteraction):
(WTR::TestController::setStatisticsTimeToLiveUserInteraction):
(WTR::TestController::statisticsFireDataModificationHandler):
(WTR::TestController::setStatisticsNotifyPagesWhenDataRecordsWereScanned):
(WTR::TestController::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval):
(WTR::TestController::setStatisticsMinimumTimeBetweeenDataRecordsRemoval):
(WTR::TestController::statisticsResetToConsistentState):
* WebKitTestRunner/TestController.h:
    These are all configuration and test functions.
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):

LayoutTests:

Reviewed by Andy Estes.

* TestExpectations:
    Marked as general skip (see WK2 expectations below).
* http/tests/loading/resourceLoadStatistics: Added.
* http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction-expected.txt: Added.
* http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction.html: Added.
* http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction-expected.txt: Added.
* http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction.html: Added.
* http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-expected.txt: Added.
* http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout-expected.txt: Added.
* http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout.html: Added.
* http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction.html: Added.
* http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction-expected.txt: Added.
* http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction.html: Added.
* platform/wk2/TestExpectations:
    Marked as valid for WebKit2 only.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsTestExpectations">trunk/LayoutTests/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformwk2TestExpectations">trunk/LayoutTests/platform/wk2/TestExpectations</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadObservercpp">trunk/Source/WebCore/loader/ResourceLoadObserver.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadObserverh">trunk/Source/WebCore/loader/ResourceLoadObserver.h</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadStatisticscpp">trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadStatisticsh">trunk/Source/WebCore/loader/ResourceLoadStatistics.h</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadStatisticsStorecpp">trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadStatisticsStoreh">trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2PlatformEflcmake">trunk/Source/WebKit2/PlatformEfl.cmake</a></li>
<li><a href="#trunkSourceWebKit2PlatformGTKcmake">trunk/Source/WebKit2/PlatformGTK.cmake</a></li>
<li><a href="#trunkSourceWebKit2PlatformMaccmake">trunk/Source/WebKit2/PlatformMac.cmake</a></li>
<li><a href="#trunkSourceWebKit2SharedAPIAPIObjecth">trunk/Source/WebKit2/Shared/API/APIObject.h</a></li>
<li><a href="#trunkSourceWebKit2SharedAPIcWKBaseh">trunk/Source/WebKit2/Shared/API/c/WKBase.h</a></li>
<li><a href="#trunkSourceWebKit2SharedWebCoreArgumentCoderscpp">trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKAPICasth">trunk/Source/WebKit2/UIProcess/API/C/WKAPICast.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessProxycpp">trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessProxyh">trunk/Source/WebKit2/UIProcess/WebProcessProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebResourceLoadStatisticsStorecpp">trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebResourceLoadStatisticsStoreh">trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.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="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcesscpp">trunk/Source/WebKit2/WebProcess/WebProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcessh">trunk/Source/WebKit2/WebProcess/WebProcess.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleBindingsTestRunneridl">trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleInjectedBundlecpp">trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleTestRunnercpp">trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleTestRunnerh">trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestControllercpp">trunk/Tools/WebKitTestRunner/TestController.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestControllerh">trunk/Tools/WebKitTestRunner/TestController.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestInvocationcpp">trunk/Tools/WebKitTestRunner/TestInvocation.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/</li>
<li><a href="#trunkLayoutTestshttptestsloadingresourceLoadStatisticsnonprevalentresourcewithuserinteractionexpectedtxt">trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingresourceLoadStatisticsnonprevalentresourcewithuserinteractionhtml">trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction.html</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingresourceLoadStatisticsnonprevalentresourcewithoutuserinteractionexpectedtxt">trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingresourceLoadStatisticsnonprevalentresourcewithoutuserinteractionhtml">trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction.html</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithuserinteractionexpectedtxt">trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithuserinteractiontimeoutexpectedtxt">trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithuserinteractiontimeouthtml">trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout.html</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithuserinteractionhtml">trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction.html</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithoutuserinteractionexpectedtxt">trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithoutuserinteractionhtml">trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction.html</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKResourceLoadStatisticsManagercpp">trunk/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICWKResourceLoadStatisticsManagerh">trunk/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebResourceLoadStatisticsManagercpp">trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebResourceLoadStatisticsManagerh">trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/LayoutTests/ChangeLog        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2017-02-10  John Wilander  &lt;wilander@apple.com&gt;
+
+        Updates to Resource Load Statistics: Get the right website data store and introduce timeout for user interaction
+        https://bugs.webkit.org/show_bug.cgi?id=167474
+        &lt;rdar://problem/24681808&gt;
+        &lt;rdar://problem/24703286&gt;
+        &lt;rdar://problem/30290270&gt;
+
+        Reviewed by Andy Estes.
+
+        * TestExpectations:
+            Marked as general skip (see WK2 expectations below).
+        * http/tests/loading/resourceLoadStatistics: Added.
+        * http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction-expected.txt: Added.
+        * http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction.html: Added.
+        * http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction-expected.txt: Added.
+        * http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction.html: Added.
+        * http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-expected.txt: Added.
+        * http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout-expected.txt: Added.
+        * http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout.html: Added.
+        * http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction.html: Added.
+        * http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction-expected.txt: Added.
+        * http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction.html: Added.
+        * platform/wk2/TestExpectations:
+            Marked as valid for WebKit2 only.
+
</ins><span class="cx"> 2017-02-10  Sam Weinig  &lt;sam@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [WebIDL] Cleanup XMLHttpRequest's bindings
</span></span></pre></div>
<a id="trunkLayoutTestsTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/TestExpectations (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/TestExpectations        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/LayoutTests/TestExpectations        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -64,6 +64,7 @@
</span><span class="cx"> # These tests are WebKit2-only
</span><span class="cx"> http/tests/appcache/decide-navigation-policy-after-delay.html [ Skip ]
</span><span class="cx"> http/tests/misc/will-send-request-with-client-provided-http-body.html [ Skip ]
</span><ins>+http/tests/loading/resourceLoadStatistics/ [ Skip ]
</ins><span class="cx"> 
</span><span class="cx"> # Only Mac and iOS have an implementation of UIScriptController::doAsyncTask().
</span><span class="cx"> fast/harness/uiscriptcontroller [ Skip ]
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourceLoadStatisticsnonprevalentresourcewithuserinteractionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction-expected.txt (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction-expected.txt        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didReceiveTitle: Tests for Non-Prevalent Resource With User Interaction
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+PASS Cookie not deleted.
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourceLoadStatisticsnonprevalentresourcewithuserinteractionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction.html (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction.html        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html lang=&quot;en&quot;&gt;
+&lt;head&gt;
+    &lt;meta charset=&quot;UTF-8&quot;&gt;
+    &lt;title&gt;Tests for Non-Prevalent Resource With User Interaction&lt;/title&gt;
+    &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+    const hostUnderTest = &quot;127.0.0.1:8000&quot;;
+    const statisticsUrl = &quot;http://&quot; + hostUnderTest + &quot;/temp&quot;;
+    const otherPrevalentUrl = &quot;http://localhost:8000/temp&quot;;
+    function runTestRunnerTest() {
+        if (document.cookie !== &quot;&quot;)
+            testFailed(&quot;document.cookie not empty.&quot;);
+        const cookie = &quot;testCookie=testValue&quot;;
+        document.cookie = cookie + &quot;; max-age=100;&quot;;
+        if (document.cookie !== cookie)
+            testFailed(&quot;document.cookie did not get set.&quot;);
+
+        testRunner.setStatisticsPrevalentResource(statisticsUrl, false);
+        if (testRunner.isStatisticsPrevalentResource(statisticsUrl))
+            testFailed(&quot;Host did not get set as non-prevalent resource.&quot;);
+
+        // This is done to not have an empty set of prevalent resources.
+        // Otherwise data records are never scanned.
+        testRunner.setStatisticsPrevalentResource(otherPrevalentUrl, true);
+        if (!testRunner.isStatisticsPrevalentResource(otherPrevalentUrl))
+            testFailed(&quot;Other host did not get set as prevalent resource.&quot;);
+
+        testRunner.setStatisticsHasHadUserInteraction(statisticsUrl, true);
+        if (!testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
+            testFailed(&quot;Host did not get logged for user interaction.&quot;);
+
+        testRunner.installStatisticsDidModifyDataRecordsCallback(function() {
+            if (document.cookie === cookie)
+                testPassed(&quot;Cookie not deleted.&quot;);
+            else
+                testFailed(&quot;Cookie deleted or document.cookie contains other cookies: &quot; + document.cookie);
+            testRunner.statisticsResetToConsistentState();
+            testRunner.notifyDone();
+        });
+        testRunner.setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(false);
+        testRunner.setStatisticsMinimumTimeBetweeenDataRecordsRemoval(0);
+        testRunner.statisticsFireDataModificationHandler();
+    }
+
+    if (document.location.host === hostUnderTest &amp;&amp; window.testRunner &amp;&amp; window.internals) {
+        testRunner.waitUntilDone();
+        internals.setResourceLoadStatisticsEnabled(true);
+        testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
+        runTestRunnerTest();
+    }
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourceLoadStatisticsnonprevalentresourcewithoutuserinteractionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction-expected.txt (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction-expected.txt        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didReceiveTitle: Tests for Non-Prevalent Resource Without User Interaction
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+PASS Cookie not deleted.
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourceLoadStatisticsnonprevalentresourcewithoutuserinteractionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction.html (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction.html        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html lang=&quot;en&quot;&gt;
+&lt;head&gt;
+    &lt;meta charset=&quot;UTF-8&quot;&gt;
+    &lt;title&gt;Tests for Non-Prevalent Resource Without User Interaction&lt;/title&gt;
+    &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+    const hostUnderTest = &quot;127.0.0.1:8000&quot;;
+    const statisticsUrl = &quot;http://&quot; + hostUnderTest + &quot;/temp&quot;;
+    const otherPrevalentUrl = &quot;http://localhost:8000/temp&quot;;
+    function runTestRunnerTest() {
+        if (document.cookie !== &quot;&quot;)
+            testFailed(&quot;document.cookie not empty.&quot;);
+        const cookie = &quot;testCookie=testValue&quot;;
+        document.cookie = cookie + &quot;; max-age=100;&quot;;
+        if (document.cookie !== cookie)
+            testFailed(&quot;document.cookie did not get set.&quot;);
+
+        testRunner.setStatisticsPrevalentResource(statisticsUrl, false);
+        if (testRunner.isStatisticsPrevalentResource(statisticsUrl))
+            testFailed(&quot;Host did not get set as non-prevalent resource.&quot;);
+
+        // This is done to not have an empty set of prevalent resources.
+        // Otherwise data records are never scanned.
+        testRunner.setStatisticsPrevalentResource(otherPrevalentUrl, true);
+        if (!testRunner.isStatisticsPrevalentResource(otherPrevalentUrl))
+            testFailed(&quot;Other host did not get set as prevalent resource.&quot;);
+
+        testRunner.setStatisticsHasHadUserInteraction(statisticsUrl, false);
+        if (testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
+            testFailed(&quot;Host did not get cleared of user interaction.&quot;);
+
+        testRunner.installStatisticsDidModifyDataRecordsCallback(function() {
+            if (document.cookie === cookie)
+                testPassed(&quot;Cookie not deleted.&quot;);
+            else
+                testFailed(&quot;Cookie deleted or document.cookie contains other cookies: &quot; + document.cookie);
+            testRunner.statisticsResetToConsistentState();
+            testRunner.notifyDone();
+        });
+        testRunner.setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(false);
+        testRunner.setStatisticsMinimumTimeBetweeenDataRecordsRemoval(0);
+        testRunner.statisticsFireDataModificationHandler();
+    }
+
+    if (document.location.host === hostUnderTest &amp;&amp; window.testRunner &amp;&amp; window.internals) {
+        testRunner.waitUntilDone();
+        internals.setResourceLoadStatisticsEnabled(true);
+        testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
+        runTestRunnerTest();
+    }
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithuserinteractionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-expected.txt (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-expected.txt        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didReceiveTitle: Tests for Prevalent Resource With User Interaction
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+PASS Cookie not deleted.
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithuserinteractiontimeoutexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout-expected.txt (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout-expected.txt        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didReceiveTitle: Tests for Prevalent Resource With User Interaction Timeout
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+PASS Cookie deleted.
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithuserinteractiontimeouthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout.html (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout.html        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html lang=&quot;en&quot;&gt;
+&lt;head&gt;
+    &lt;meta charset=&quot;UTF-8&quot;&gt;
+    &lt;title&gt;Tests for Prevalent Resource With User Interaction Timeout&lt;/title&gt;
+    &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+    const hostUnderTest = &quot;127.0.0.1:8000&quot;;
+    const statisticsUrl = &quot;http://&quot; + hostUnderTest + &quot;/temp&quot;;
+    function runTestRunnerTest() {
+        if (document.cookie !== &quot;&quot;)
+            testFailed(&quot;document.cookie not empty.&quot;);
+        const cookie = &quot;testCookie=testValue&quot;;
+        document.cookie = cookie + &quot;; max-age=100;&quot;;
+        if (document.cookie !== cookie)
+            testFailed(&quot;document.cookie did not get set.&quot;);
+
+        testRunner.setStatisticsPrevalentResource(statisticsUrl, true);
+        if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
+            testFailed(&quot;Host did not get set as prevalent resource.&quot;);
+
+        testRunner.setStatisticsHasHadUserInteraction(statisticsUrl, true);
+        if (!testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
+            testFailed(&quot;Host did not get logged for user interaction.&quot;);
+
+        testRunner.installStatisticsDidModifyDataRecordsCallback(function() {
+            if (document.cookie !== &quot;&quot;)
+                testFailed(&quot;Cookie not deleted: &quot; + document.cookie);
+            else
+                testPassed(&quot;Cookie deleted.&quot;);
+            testRunner.statisticsResetToConsistentState();
+            testRunner.notifyDone();
+        });
+        testRunner.setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(false);
+        testRunner.setStatisticsMinimumTimeBetweeenDataRecordsRemoval(0);
+        testRunner.setStatisticsTimeToLiveUserInteraction(0);
+        setTimeout(&quot;testRunner.statisticsFireDataModificationHandler()&quot;, 1000);
+    }
+
+    if (document.location.host === hostUnderTest &amp;&amp; window.testRunner &amp;&amp; window.internals) {
+        testRunner.waitUntilDone();
+        internals.setResourceLoadStatisticsEnabled(true);
+        testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
+        runTestRunnerTest();
+    }
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithuserinteractionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction.html (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction.html        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html lang=&quot;en&quot;&gt;
+&lt;head&gt;
+    &lt;meta charset=&quot;UTF-8&quot;&gt;
+    &lt;title&gt;Tests for Prevalent Resource With User Interaction&lt;/title&gt;
+    &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+    const hostUnderTest = &quot;127.0.0.1:8000&quot;;
+    const statisticsUrl = &quot;http://&quot; + hostUnderTest + &quot;/temp&quot;;
+    const otherPrevalentUrl = &quot;http://localhost:8000/temp&quot;;
+    function runTestRunnerTest() {
+        if (document.cookie !== &quot;&quot;)
+            testFailed(&quot;document.cookie not empty.&quot;);
+        const cookie = &quot;testCookie=testValue&quot;;
+        document.cookie = cookie + &quot;; max-age=100;&quot;;
+        if (document.cookie !== cookie)
+            testFailed(&quot;document.cookie did not get set.&quot;);
+
+        testRunner.setStatisticsPrevalentResource(statisticsUrl, true);
+        if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
+            testFailed(&quot;Host did not get set as prevalent resource.&quot;);
+
+        // This is done to not have an empty set of prevalent resources.
+        // Otherwise data records are never scanned.
+        testRunner.setStatisticsPrevalentResource(otherPrevalentUrl, true);
+        if (!testRunner.isStatisticsPrevalentResource(otherPrevalentUrl))
+            testFailed(&quot;Other host did not get set as prevalent resource.&quot;);
+
+        testRunner.setStatisticsHasHadUserInteraction(statisticsUrl, true);
+        if (!testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
+            testFailed(&quot;Host did not get logged for user interaction.&quot;);
+
+        testRunner.installStatisticsDidModifyDataRecordsCallback(function() {
+            if (document.cookie === cookie)
+                testPassed(&quot;Cookie not deleted.&quot;);
+            else
+                testFailed(&quot;Cookie deleted or document.cookie contains other cookies: &quot; + document.cookie);
+            testRunner.statisticsResetToConsistentState();
+            testRunner.notifyDone();
+        });
+        testRunner.setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(false);
+        testRunner.setStatisticsMinimumTimeBetweeenDataRecordsRemoval(0);
+        testRunner.statisticsFireDataModificationHandler();
+    }
+
+    if (document.location.host === hostUnderTest &amp;&amp; window.testRunner &amp;&amp; window.internals) {
+        testRunner.waitUntilDone();
+        internals.setResourceLoadStatisticsEnabled(true);
+        testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
+        runTestRunnerTest();
+    }
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithoutuserinteractionexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction-expected.txt (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction-expected.txt        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didReceiveTitle: Tests for Prevalent Resource Without User Interaction
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+PASS Cookie deleted.
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsloadingresourceLoadStatisticsprevalentresourcewithoutuserinteractionhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction.html (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction.html        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html lang=&quot;en&quot;&gt;
+&lt;head&gt;
+    &lt;meta charset=&quot;UTF-8&quot;&gt;
+    &lt;title&gt;Tests for Prevalent Resource Without User Interaction&lt;/title&gt;
+    &lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+    const hostUnderTest = &quot;127.0.0.1:8000&quot;;
+    const statisticsUrl = &quot;http://&quot; + hostUnderTest + &quot;/temp&quot;;
+    function runTestRunnerTest() {
+        if (document.cookie !== &quot;&quot;)
+            testFailed(&quot;document.cookie not empty.&quot;);
+        const cookie = &quot;testCookie=testValue&quot;;
+        document.cookie = cookie + &quot;; max-age=100;&quot;;
+        if (document.cookie !== cookie)
+            testFailed(&quot;document.cookie did not get set.&quot;);
+
+        testRunner.setStatisticsPrevalentResource(statisticsUrl, true);
+        if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
+            testFailed(&quot;Host did not get set as prevalent resource.&quot;);
+
+        testRunner.setStatisticsHasHadUserInteraction(statisticsUrl, false);
+        if (testRunner.isStatisticsHasHadUserInteraction(statisticsUrl))
+            testFailed(&quot;Host did not get cleared of user interaction.&quot;);
+
+        testRunner.installStatisticsDidModifyDataRecordsCallback(function() {
+            if (document.cookie !== &quot;&quot;)
+                testFailed(&quot;Cookie not deleted: &quot; + document.cookie);
+            else
+                testPassed(&quot;Cookie deleted.&quot;);
+            testRunner.statisticsResetToConsistentState();
+            testRunner.notifyDone();
+        });
+        testRunner.setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(false);
+        testRunner.setStatisticsMinimumTimeBetweeenDataRecordsRemoval(0);
+        testRunner.statisticsFireDataModificationHandler();
+    }
+
+    if (document.location.host === hostUnderTest &amp;&amp; window.testRunner &amp;&amp; window.internals) {
+        testRunner.waitUntilDone();
+        internals.setResourceLoadStatisticsEnabled(true);
+        testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
+        runTestRunnerTest();
+    }
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsplatformwk2TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/wk2/TestExpectations (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/wk2/TestExpectations        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/LayoutTests/platform/wk2/TestExpectations        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -698,6 +698,9 @@
</span><span class="cx"> # bug 162281
</span><span class="cx"> imported/w3c/web-platform-tests/fetch/api/request/request-cache-only-if-cached.html [ Failure ]
</span><span class="cx"> 
</span><ins>+# Resource Load Statistics are only supported in WebKit2
+http/tests/loading/resourceLoadStatistics/ [ Pass ]
+
</ins><span class="cx"> ### END OF (5) Progressions, expected successes that are expected failures in WebKit1.
</span><span class="cx"> ########################################
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebCore/ChangeLog        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,3 +1,75 @@
</span><ins>+2017-02-10  John Wilander  &lt;wilander@apple.com&gt;
+
+        Updates to Resource Load Statistics: Get the right website data store and introduce timeout for user interaction
+        https://bugs.webkit.org/show_bug.cgi?id=167474
+        &lt;rdar://problem/24681808&gt;
+        &lt;rdar://problem/24703286&gt;
+        &lt;rdar://problem/30290270&gt;
+
+        This patch does the following:
+        1. Gets the right website data store. API::WebsiteDataStore::defaultDataStore()
+            does not provide the right data store.
+        2. Introduces timeout for user interaction. A domain needs interaction every 30
+            days to stay in that category.
+        3. Adds grandfathered to the statistics model in preparation for grandfathering of
+            existing data records.
+        4. Adds test infrastructure to allow testing of the various rules in place for
+            data records removal.
+        5. Fixes various smaller bugs that were found as part of setting up the tests.
+        6. Regresses the data records removal counting. We need to come up with a thread
+            safe way of gathering removal statistics from more than one data store now
+            that we potentially interact with multiple stores.
+        7. Adds a first set of layout tests for resource load statistics.
+
+        Reviewed by Andy Estes.
+
+        Tests: http/tests/loading/resourceLoadStatistics/non-prevalent-resource-with-user-interaction.html
+               http/tests/loading/resourceLoadStatistics/non-prevalent-resource-without-user-interaction.html
+               http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction-timeout.html
+               http/tests/loading/resourceLoadStatistics/prevalent-resource-with-user-interaction.html
+               http/tests/loading/resourceLoadStatistics/prevalent-resource-without-user-interaction.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::updateLastHandledUserGestureTimestamp):
+            This now calls ResourceLoadObserver::logUserInteraction() every time since
+            we want to keep track of the most recent user interaction.
+        * loader/ResourceLoadObserver.cpp:
+        (WebCore::ResourceLoadObserver::statisticsStore):
+            New getter used by WebResourceLoadStatisticsManager::resetToConsistentState().
+        (WebCore::reduceTimeResolutionToOneDay):
+            Convenience function.
+        (WebCore::ResourceLoadObserver::logUserInteractionWithReducedTimeResolution):
+            Reduces time resolution for privacy reasons.
+        (WebCore::ResourceLoadObserver::logUserInteraction):
+        (WebCore::ResourceLoadObserver::clearUserInteraction):
+        (WebCore::ResourceLoadObserver::hasHadUserInteraction):
+        (WebCore::ResourceLoadObserver::setPrevalentResource):
+        (WebCore::ResourceLoadObserver::isPrevalentResource):
+        (WebCore::ResourceLoadObserver::clearPrevalentResource):
+        (WebCore::ResourceLoadObserver::setTimeToLiveUserInteraction):
+        (WebCore::ResourceLoadObserver::fireDataModificationHandler):
+            New functions that allow WebKitTestRunner to stage exact
+            statistics, fire the handler, and test the outcome.
+        * loader/ResourceLoadObserver.h:
+        * loader/ResourceLoadStatistics.cpp:
+        (WebCore::ResourceLoadStatistics::encode):
+        (WebCore::ResourceLoadStatistics::decode):
+        (WebCore::ResourceLoadStatistics::toString):
+        (WebCore::ResourceLoadStatistics::merge):
+            Support for statistics mostRecentUserInteraction, grandfathered, and
+            dataRecordsRemoved.
+        * loader/ResourceLoadStatistics.h:
+        * loader/ResourceLoadStatisticsStore.cpp:
+        (WebCore::ResourceLoadStatisticsStore::setTimeToLiveUserInteraction):
+            New function that allows WebKitTestRunner to test 
+            aging out of user interaction.
+        (WebCore::ResourceLoadStatisticsStore::hasHadRecentUserInteraction):
+            Now takes into account the timestamp and ages
+            out user interaction.
+        (WebCore::ResourceLoadStatisticsStore::prevalentResourceDomainsWithoutUserInteraction):
+            Now makes use of ResourceLoadStatisticsStore::hasHadRecentUserInteraction().
+        * loader/ResourceLoadStatisticsStore.h:
+
</ins><span class="cx"> 2017-02-10  Sam Weinig  &lt;sam@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [WebIDL] Cleanup XMLHttpRequest's bindings
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebCore/dom/Document.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -6356,10 +6356,8 @@
</span><span class="cx"> 
</span><span class="cx"> void Document::updateLastHandledUserGestureTimestamp()
</span><span class="cx"> {
</span><del>-    if (!m_lastHandledUserGestureTimestamp)
-        ResourceLoadObserver::sharedObserver().logUserInteraction(*this);
-
</del><span class="cx">     m_lastHandledUserGestureTimestamp = monotonicallyIncreasingTime();
</span><ins>+    ResourceLoadObserver::sharedObserver().logUserInteractionWithReducedTimeResolution(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Document::startTrackingStyleRecalcs()
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadObservercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadObserver.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadObserver.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebCore/loader/ResourceLoadObserver.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -42,11 +42,15 @@
</span><span class="cx"> #include &quot;Settings.h&quot;
</span><span class="cx"> #include &quot;SharedBuffer.h&quot;
</span><span class="cx"> #include &quot;URL.h&quot;
</span><ins>+#include &lt;wtf/CurrentTime.h&gt;
</ins><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringBuilder.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+// One day in seconds.
+static auto timestampResolution = 86400;
+
</ins><span class="cx"> ResourceLoadObserver&amp; ResourceLoadObserver::sharedObserver()
</span><span class="cx"> {
</span><span class="cx">     static NeverDestroyed&lt;ResourceLoadObserver&gt; resourceLoadObserver;
</span><span class="lines">@@ -53,6 +57,12 @@
</span><span class="cx">     return resourceLoadObserver;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RefPtr&lt;ResourceLoadStatisticsStore&gt; ResourceLoadObserver::statisticsStore()
+{
+    ASSERT(m_store);
+    return m_store;
+}
+
</ins><span class="cx"> void ResourceLoadObserver::setStatisticsStore(Ref&lt;ResourceLoadStatisticsStore&gt;&amp;&amp; store)
</span><span class="cx"> {
</span><span class="cx">     m_store = WTFMove(store);
</span><span class="lines">@@ -278,8 +288,13 @@
</span><span class="cx">         m_store-&gt;fireDataModificationHandler();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoadObserver::logUserInteraction(const Document&amp; document)
</del><ins>+static double reduceTimeResolutionToOneDay(double seconds)
</ins><span class="cx"> {
</span><ins>+    return std::floor(seconds / timestampResolution) * timestampResolution;
+}
+
+void ResourceLoadObserver::logUserInteractionWithReducedTimeResolution(const Document&amp; document)
+{
</ins><span class="cx">     ASSERT(document.page());
</span><span class="cx"> 
</span><span class="cx">     if (!shouldLog(document.page()))
</span><span class="lines">@@ -286,15 +301,90 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     auto&amp; url = document.url();
</span><ins>+    if (url.isBlankURL() || url.isEmpty())
+        return;
</ins><span class="cx"> 
</span><ins>+    auto&amp; statistics = m_store-&gt;ensureResourceStatisticsForPrimaryDomain(primaryDomain(url));
+    double newTimestamp = reduceTimeResolutionToOneDay(WTF::currentTime());
+    if (newTimestamp == statistics.mostRecentUserInteraction)
+        return;
+
+    statistics.hadUserInteraction = true;
+    statistics.mostRecentUserInteraction = newTimestamp;
+    m_store-&gt;fireDataModificationHandler();
+}
+
+void ResourceLoadObserver::logUserInteraction(const URL&amp; url)
+{
</ins><span class="cx">     if (url.isBlankURL() || url.isEmpty())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     auto&amp; statistics = m_store-&gt;ensureResourceStatisticsForPrimaryDomain(primaryDomain(url));
</span><span class="cx">     statistics.hadUserInteraction = true;
</span><ins>+    statistics.mostRecentUserInteraction = WTF::currentTime();
+}
+
+void ResourceLoadObserver::clearUserInteraction(const URL&amp; url)
+{
+    if (url.isBlankURL() || url.isEmpty())
+        return;
+
+    auto&amp; statistics = m_store-&gt;ensureResourceStatisticsForPrimaryDomain(primaryDomain(url));
+    
+    statistics.hadUserInteraction = false;
+    statistics.mostRecentUserInteraction = 0;
+}
+
+bool ResourceLoadObserver::hasHadUserInteraction(const URL&amp; url)
+{
+    if (url.isBlankURL() || url.isEmpty())
+        return false;
+
+    auto&amp; statistics = m_store-&gt;ensureResourceStatisticsForPrimaryDomain(primaryDomain(url));
+    
+    return m_store-&gt;hasHadRecentUserInteraction(statistics);
+}
+
+void ResourceLoadObserver::setPrevalentResource(const URL&amp; url)
+{
+    if (url.isBlankURL() || url.isEmpty())
+        return;
+
+    auto&amp; statistics = m_store-&gt;ensureResourceStatisticsForPrimaryDomain(primaryDomain(url));
+    
+    statistics.isPrevalentResource = true;
+}
+
+bool ResourceLoadObserver::isPrevalentResource(const URL&amp; url)
+{
+    if (url.isBlankURL() || url.isEmpty())
+        return false;
+
+    auto&amp; statistics = m_store-&gt;ensureResourceStatisticsForPrimaryDomain(primaryDomain(url));
+    
+    return statistics.isPrevalentResource;
+}
+    
+void ResourceLoadObserver::clearPrevalentResource(const URL&amp; url)
+{
+    if (url.isBlankURL() || url.isEmpty())
+        return;
+
+    auto&amp; statistics = m_store-&gt;ensureResourceStatisticsForPrimaryDomain(primaryDomain(url));
+    
+    statistics.isPrevalentResource = false;
+}
+
+void ResourceLoadObserver::setTimeToLiveUserInteraction(double seconds)
+{
+    m_store-&gt;setTimeToLiveUserInteraction(seconds);
+}
+
+void ResourceLoadObserver::fireDataModificationHandler()
+{
</ins><span class="cx">     m_store-&gt;fireDataModificationHandler();
</span><span class="cx"> }
</span><del>-    
</del><ins>+
</ins><span class="cx"> String ResourceLoadObserver::primaryDomain(const URL&amp; url)
</span><span class="cx"> {
</span><span class="cx">     String primaryDomain;
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadObserverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadObserver.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadObserver.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebCore/loader/ResourceLoadObserver.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc.  All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -48,9 +48,22 @@
</span><span class="cx">     void logFrameNavigation(const Frame&amp; frame, const Frame&amp; topFrame, const ResourceRequest&amp; newRequest, const ResourceResponse&amp; redirectResponse);
</span><span class="cx">     void logSubresourceLoading(const Frame*, const ResourceRequest&amp; newRequest, const ResourceResponse&amp; redirectResponse);
</span><span class="cx">     void logWebSocketLoading(const Frame*, const URL&amp;);
</span><ins>+    void logUserInteractionWithReducedTimeResolution(const Document&amp;);
</ins><span class="cx"> 
</span><del>-    void logUserInteraction(const Document&amp;);
-    
</del><ins>+    WEBCORE_EXPORT void logUserInteraction(const URL&amp;);
+    WEBCORE_EXPORT bool hasHadUserInteraction(const URL&amp;);
+    WEBCORE_EXPORT void clearUserInteraction(const URL&amp;);
+
+    WEBCORE_EXPORT void setPrevalentResource(const URL&amp;);
+    WEBCORE_EXPORT bool isPrevalentResource(const URL&amp;);
+    WEBCORE_EXPORT void clearPrevalentResource(const URL&amp;);
+
+    WEBCORE_EXPORT void setTimeToLiveUserInteraction(double seconds);
+    WEBCORE_EXPORT void setReducedTimestampResolution(double seconds);
+
+    WEBCORE_EXPORT void fireDataModificationHandler();
+
+    WEBCORE_EXPORT RefPtr&lt;ResourceLoadStatisticsStore&gt; statisticsStore();
</ins><span class="cx">     WEBCORE_EXPORT void setStatisticsStore(Ref&lt;ResourceLoadStatisticsStore&gt;&amp;&amp;);
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT String statisticsForOrigin(const String&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadStatisticscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc.  All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -51,6 +51,8 @@
</span><span class="cx">     
</span><span class="cx">     // User interaction
</span><span class="cx">     encoder.encodeBool(&quot;hadUserInteraction&quot;, hadUserInteraction);
</span><ins>+    encoder.encodeDouble(&quot;mostRecentUserInteraction&quot;, mostRecentUserInteraction);
+    encoder.encodeBool(&quot;grandfathered&quot;, grandfathered);
</ins><span class="cx">     
</span><span class="cx">     // Top frame stats
</span><span class="cx">     encoder.encodeBool(&quot;topFrameHasBeenNavigatedToBefore&quot;, topFrameHasBeenNavigatedToBefore);
</span><span class="lines">@@ -177,7 +179,16 @@
</span><span class="cx"> 
</span><span class="cx">     if (!decoder.decodeUInt32(&quot;dataRecordsRemoved&quot;, dataRecordsRemoved))
</span><span class="cx">         return false;
</span><del>-    
</del><ins>+
+    if (version &lt; 3)
+        return true;
+
+    if (!decoder.decodeDouble(&quot;mostRecentUserInteraction&quot;, mostRecentUserInteraction))
+        return false;
+
+    if (!decoder.decodeBool(&quot;grandfathered&quot;, grandfathered))
+        return false;
+
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -214,6 +225,11 @@
</span><span class="cx">     // User interaction
</span><span class="cx">     appendBoolean(builder, &quot;hadUserInteraction&quot;, hadUserInteraction);
</span><span class="cx">     builder.append('\n');
</span><ins>+    builder.appendLiteral(&quot;    mostRecentUserInteraction: &quot;);
+    builder.appendNumber(mostRecentUserInteraction);
+    builder.append('\n');
+    appendBoolean(builder, &quot;    grandfathered&quot;, grandfathered);
+    builder.append('\n');
</ins><span class="cx">     
</span><span class="cx">     // Top frame stats
</span><span class="cx">     appendBoolean(builder, &quot;topFrameHasBeenNavigatedToBefore&quot;, topFrameHasBeenNavigatedToBefore);
</span><span class="lines">@@ -294,7 +310,19 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(other.highLevelDomain == highLevelDomain);
</span><span class="cx"> 
</span><del>-    hadUserInteraction |= other.hadUserInteraction;
</del><ins>+    if (!other.hadUserInteraction) {
+        // If user interaction has been reset do so here too.
+        // Else, do nothing.
+        if (!other.mostRecentUserInteraction) {
+            hadUserInteraction = false;
+            mostRecentUserInteraction = 0;
+        }
+    } else {
+        hadUserInteraction = true;
+        if (mostRecentUserInteraction &lt; other.mostRecentUserInteraction)
+            mostRecentUserInteraction = other.mostRecentUserInteraction;
+    }
+    grandfathered |= other.grandfathered;
</ins><span class="cx">     
</span><span class="cx">     // Top frame stats
</span><span class="cx">     topFrameHasBeenRedirectedTo += other.topFrameHasBeenRedirectedTo;
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadStatisticsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadStatistics.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadStatistics.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebCore/loader/ResourceLoadStatistics.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc.  All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -53,7 +53,10 @@
</span><span class="cx"> 
</span><span class="cx">     // User interaction
</span><span class="cx">     bool hadUserInteraction { false };
</span><del>-    
</del><ins>+    // Timestamp. Default value is negative, 0 means it was reset.
+    double mostRecentUserInteraction { -1 };
+    bool grandfathered { false };
+
</ins><span class="cx">     // Top frame stats
</span><span class="cx">     unsigned topFrameHasBeenRedirectedTo { 0 };
</span><span class="cx">     unsigned topFrameHasBeenRedirectedFrom { 0 };
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadStatisticsStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -33,11 +33,14 @@
</span><span class="cx"> #include &quot;ResourceLoadStatistics.h&quot;
</span><span class="cx"> #include &quot;SharedBuffer.h&quot;
</span><span class="cx"> #include &quot;URL.h&quot;
</span><ins>+#include &lt;wtf/CurrentTime.h&gt;
</ins><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-static const auto statisticsModelVersion = 2;
</del><ins>+static const auto statisticsModelVersion = 3;
+// 30 days in seconds
+static auto timeToLiveUserInteraction = 2592000;
</ins><span class="cx"> 
</span><span class="cx"> Ref&lt;ResourceLoadStatisticsStore&gt; ResourceLoadStatisticsStore::create()
</span><span class="cx"> {
</span><span class="lines">@@ -144,6 +147,12 @@
</span><span class="cx">         m_dataAddedHandler();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ResourceLoadStatisticsStore::setTimeToLiveUserInteraction(double seconds)
+{
+    if (seconds &gt;= 0)
+        timeToLiveUserInteraction = seconds;
+}
+
</ins><span class="cx"> void ResourceLoadStatisticsStore::processStatistics(std::function&lt;void(ResourceLoadStatistics&amp;)&gt;&amp;&amp; processFunction)
</span><span class="cx"> {
</span><span class="cx">     for (auto&amp; resourceStatistic : m_resourceStatisticsMap.values())
</span><span class="lines">@@ -150,11 +159,28 @@
</span><span class="cx">         processFunction(resourceStatistic);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool ResourceLoadStatisticsStore::hasHadRecentUserInteraction(ResourceLoadStatistics&amp; resourceStatistic)
+{
+    if (!resourceStatistic.hadUserInteraction)
+        return false;
+
+    if (currentTime() &gt; resourceStatistic.mostRecentUserInteraction + timeToLiveUserInteraction) {
+        // Drop privacy sensitive data because we no longer need it.
+        // Set timestamp to 0.0 so that statistics merge will know
+        // it has been reset as opposed to its default -1.
+        resourceStatistic.mostRecentUserInteraction = 0;
+        resourceStatistic.hadUserInteraction = false;
+        return false;
+    }
+
+    return true;
+}
+
</ins><span class="cx"> Vector&lt;String&gt; ResourceLoadStatisticsStore::prevalentResourceDomainsWithoutUserInteraction()
</span><span class="cx"> {
</span><span class="cx">     Vector&lt;String&gt; prevalentResources;
</span><span class="cx">     for (auto&amp; resourceStatistic : m_resourceStatisticsMap.values()) {
</span><del>-        if (resourceStatistic.isPrevalentResource &amp;&amp; !resourceStatistic.hadUserInteraction)
</del><ins>+        if (resourceStatistic.isPrevalentResource &amp;&amp; !hasHadRecentUserInteraction(resourceStatistic))
</ins><span class="cx">             prevalentResources.append(resourceStatistic.highLevelDomain);
</span><span class="cx">     }
</span><span class="cx">     return prevalentResources;
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadStatisticsStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2016 Apple Inc.  All rights reserved.
</del><ins>+ * Copyright (C) 2016-2017 Apple Inc.  All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -59,9 +59,11 @@
</span><span class="cx">     WEBCORE_EXPORT void setNotificationCallback(std::function&lt;void()&gt; handler);
</span><span class="cx"> 
</span><span class="cx">     void fireDataModificationHandler();
</span><ins>+    void setTimeToLiveUserInteraction(double seconds);
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void processStatistics(std::function&lt;void(ResourceLoadStatistics&amp;)&gt;&amp;&amp;);
</span><span class="cx"> 
</span><ins>+    WEBCORE_EXPORT bool hasHadRecentUserInteraction(ResourceLoadStatistics&amp;);
</ins><span class="cx">     WEBCORE_EXPORT Vector&lt;String&gt; prevalentResourceDomainsWithoutUserInteraction();
</span><span class="cx">     WEBCORE_EXPORT void updateStatisticsForRemovedDataRecords(const Vector&lt;String&gt;&amp; prevalentResourceDomains);
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/ChangeLog        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,3 +1,130 @@
</span><ins>+2017-02-10  John Wilander  &lt;wilander@apple.com&gt;
+
+        Updates to Resource Load Statistics: Get the right website data store and introduce timeout for user interaction
+        https://bugs.webkit.org/show_bug.cgi?id=167474
+        &lt;rdar://problem/24681808&gt;
+        &lt;rdar://problem/24703286&gt;
+        &lt;rdar://problem/30290270&gt;
+
+        This patch does the following:
+        1. Gets the right website data store. API::WebsiteDataStore::defaultDataStore()
+            does not provide the right data store.
+        2. Introduces timeout for user interaction. A domain needs interaction every 30
+            days to stay in that category.
+        3. Adds grandfathered to the statistics model in preparation for grandfathering of
+            existing data records.
+        4. Adds test infrastructure to allow testing of the various rules in place for
+            data records removal.
+        5. Fixes various smaller bugs that were found as part of setting up the tests.
+        6. Regresses the data records removal counting. We need to come up with a thread
+            safe way of gathering removal statistics from more than one data store now
+            that we potentially interact with multiple stores.
+        7. Adds a first set of layout tests for resource load statistics.
+
+        Reviewed by Andy Estes.
+
+        * PlatformEfl.cmake:
+            Added UIProcess/WebResourceLoadStatisticsManager.cpp and
+            UIProcess/API/C/WKResourceLoadStatisticsManager.cpp.
+        * PlatformGTK.cmake:
+            Added UIProcess/WebResourceLoadStatisticsManager.cpp and
+            UIProcess/API/C/WKResourceLoadStatisticsManager.cpp.
+        * PlatformMac.cmake:
+            Added UIProcess/WebResourceLoadStatisticsManager.cpp and
+            UIProcess/API/C/WKResourceLoadStatisticsManager.cpp.
+        * Shared/API/APIObject.h:
+            Adds WebResourceLoadStatisticsManager to the Type enum.
+        * Shared/API/c/WKBase.h:
+            Typedef of WKResourceLoadStatisticsManagerRef.
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder&lt;ResourceLoadStatistics&gt;::encode):
+        (IPC::ArgumentCoder&lt;ResourceLoadStatistics&gt;::decode):
+            Adds support for statistics mostRecentUserInteraction, grandfathered, and
+            dataRecordsRemoved.
+        * UIProcess/API/C/WKAPICast.h:
+            Adds API mapping between WKResourceLoadStatisticsManagerRef and 
+            WebResourceLoadStatisticsManager.
+        * UIProcess/API/C/WKResourceLoadStatisticsManager.cpp: Added.
+        (WKResourceLoadStatisticsManagerGetTypeID):
+        (WKResourceLoadStatisticsManagerSetPrevalentResource):
+        (WKResourceLoadStatisticsManagerIsPrevalentResource):
+        (WKResourceLoadStatisticsManagerSetHasHadUserInteraction):
+        (WKResourceLoadStatisticsManagerIsHasHadUserInteraction):
+        (WKResourceLoadStatisticsManagerSetTimeToLiveUserInteraction):
+        (WKResourceLoadStatisticsManagerFireDataModificationHandler):
+        (WKResourceLoadStatisticsManagerSetNotifyPagesWhenDataRecordsWereScanned):
+        (WKResourceLoadStatisticsManagerSetShouldClassifyResourcesBeforeDataRecordsRemoval):
+        (WKResourceLoadStatisticsManagerSetMinimumTimeBetweeenDataRecordsRemoval):
+        (WKResourceLoadStatisticsManagerResetToConsistentState):
+            API level bridge to WebResourceLoadStatisticsManager functions.
+        * UIProcess/API/C/WKResourceLoadStatisticsManager.h: Added.
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::deleteWebsiteDataForTopPrivatelyOwnedDomainsInAllPersistentDataStores):
+            A way to delete website data in persistent store(s) configured by the 
+            embedding client. API::WebsiteDataStore::defaultDataStore() does not 
+            do this which caused us to skip session storage.
+        * UIProcess/WebProcessProxy.h:
+        * UIProcess/WebResourceLoadStatisticsManager.cpp: Added.
+        (WebKit::WebResourceLoadStatisticsManager::setPrevalentResource):
+        (WebKit::WebResourceLoadStatisticsManager::isPrevalentResource):
+        (WebKit::WebResourceLoadStatisticsManager::setHasHadUserInteraction):
+        (WebKit::WebResourceLoadStatisticsManager::hasHadUserInteraction):
+        (WebKit::WebResourceLoadStatisticsManager::setTimeToLiveUserInteraction):
+        (WebKit::WebResourceLoadStatisticsManager::fireDataModificationHandler):
+        (WebKit::WebResourceLoadStatisticsManager::setNotifyPagesWhenDataRecordsWereScanned):
+        (WebKit::WebResourceLoadStatisticsManager::setShouldClassifyResourcesBeforeDataRecordsRemoval):
+        (WebKit::WebResourceLoadStatisticsManager::setMinimumTimeBetweeenDataRecordsRemoval):
+        (WebKit::WebResourceLoadStatisticsManager::resetToConsistentState):
+            Static functions to manage the state and behavior of the UI process' 
+            resource load statistics store.
+        * UIProcess/WebResourceLoadStatisticsManager.h: Added.
+        (WebKit::WebResourceLoadStatisticsManager::create):
+        * UIProcess/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
+            An effect of a member variable rename. See header file comment below.
+        (WebKit::WebResourceLoadStatisticsStore::setNotifyPagesWhenDataRecordsWereScanned):
+        (WebKit::WebResourceLoadStatisticsStore::setShouldClassifyResourcesBeforeDataRecordsRemoval):
+        (WebKit::WebResourceLoadStatisticsStore::setMinimumTimeBetweeenDataRecordsRemoval):
+            Three static functions for controlling the behavior of the store.
+        (WebKit::WebResourceLoadStatisticsStore::removeDataRecords):
+            Changes:
+            1. Covers all data record types.
+            2. Allows data removal when m_lastTimeDataRecordsWereRemoved is not set.
+            3. Moves the heavy lifting to WebsiteDataStore (see below).
+            4. No longer counts removed data regressions.
+        (WebKit::WebResourceLoadStatisticsStore::processStatisticsAndDataRecords):
+            See next comment.
+        (WebKit::WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated):
+            WebResourceLoadStatisticsStore::processStatisticsAndDataRecords() is 
+            broken out of WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated
+            to allow for statistics processing without prior classification.
+            Tests need to set statistics and a run of the classifier may
+            reset the data.
+        (WebKit::WebResourceLoadStatisticsStore::registerSharedResourceLoadObserver):
+            Sets the notification callback which calls 
+            WebResourceLoadStatisticsStore::processStatisticsAndDataRecords().
+        * UIProcess/WebResourceLoadStatisticsStore.h:
+        (WebKit::WebResourceLoadStatisticsStore::coreStore):
+            Renamed m_resourceStatisticsStore to m_resourceLoadStatisticsStore to
+            harmonize with other naming.
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::fetchDataForTopPrivatelyOwnedDomains):
+            This is now where matching is made between prevalent resources
+            and data records. This function is used by 
+            WebsiteDataStore::removeDataForTopPrivatelyOwnedDomains().
+        (WebKit::WebsiteDataStore::removeDataForTopPrivatelyOwnedDomains):
+            The function WebResourceLoadStatisticsStore::removeDataRecords()
+            calls to get data records removed in all persistent stores.
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+        * WebKit2.xcodeproj/project.pbxproj:
+        * WebProcess/WebProcess.cpp:
+        (WebKit::m_resourceLoadStatisticsStore):
+        (WebKit::WebProcess::statisticsChangedTimerFired):
+        (WebKit::m_resourceLoadStatisticsStorage): Deleted.
+            Renamed m_resourceLoadStatisticsStorage to m_resourceLoadStatisticsStore 
+            to harmonize with other naming.
+        * WebProcess/WebProcess.h:
+
</ins><span class="cx"> 2017-02-10  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Zero out some WKWebView state in the case of a web content crash
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformEflcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PlatformEfl.cmake (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PlatformEfl.cmake        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/PlatformEfl.cmake        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -62,10 +62,13 @@
</span><span class="cx">     UIProcess/BackingStore.cpp
</span><span class="cx">     UIProcess/DefaultUndoController.cpp
</span><span class="cx">     UIProcess/LegacySessionStateCodingNone.cpp
</span><ins>+    UIProcess/WebResourceLoadStatisticsManager.cpp
</ins><span class="cx">     UIProcess/WebResourceLoadStatisticsStore.cpp
</span><span class="cx">     UIProcess/WebTextChecker.cpp
</span><span class="cx">     UIProcess/WebTextCheckerClient.cpp
</span><span class="cx"> 
</span><ins>+    UIProcess/API/C/WKResourceLoadStatisticsManager.cpp
+
</ins><span class="cx">     UIProcess/API/C/CoordinatedGraphics/WKView.cpp
</span><span class="cx"> 
</span><span class="cx">     UIProcess/API/C/cairo/WKIconDatabaseCairo.cpp
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformGTKcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PlatformGTK.cmake (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PlatformGTK.cmake        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/PlatformGTK.cmake        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -88,10 +88,13 @@
</span><span class="cx">     UIProcess/DefaultUndoController.cpp
</span><span class="cx">     UIProcess/DrawingAreaProxyImpl.cpp
</span><span class="cx">     UIProcess/LegacySessionStateCodingNone.cpp
</span><ins>+    UIProcess/WebResourceLoadStatisticsManager.cpp
</ins><span class="cx">     UIProcess/WebResourceLoadStatisticsStore.cpp
</span><span class="cx">     UIProcess/WebTextChecker.cpp
</span><span class="cx">     UIProcess/WebTextCheckerClient.cpp
</span><span class="cx"> 
</span><ins>+    UIProcess/API/C/WKResourceLoadStatisticsManager.cpp
+
</ins><span class="cx">     UIProcess/API/C/cairo/WKIconDatabaseCairo.cpp
</span><span class="cx"> 
</span><span class="cx">     UIProcess/API/C/gtk/WKFullScreenClientGtk.cpp
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformMaccmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PlatformMac.cmake (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PlatformMac.cmake        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/PlatformMac.cmake        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -160,6 +160,7 @@
</span><span class="cx">     UIProcess/HighPerformanceGraphicsUsageSampler.cpp
</span><span class="cx">     UIProcess/PerActivityStateCPUUsageSampler.cpp
</span><span class="cx">     UIProcess/WebContextMenuListenerProxy.cpp
</span><ins>+    UIProcess/WebResourceLoadStatisticsManager.cpp
</ins><span class="cx">     UIProcess/WebResourceLoadStatisticsStore.cpp
</span><span class="cx"> 
</span><span class="cx">     UIProcess/Automation/WebAutomationSession.cpp
</span><span class="lines">@@ -172,6 +173,8 @@
</span><span class="cx">     UIProcess/API/APIUserStyleSheet.cpp
</span><span class="cx">     UIProcess/API/APIWebsiteDataRecord.cpp
</span><span class="cx"> 
</span><ins>+    UIProcess/API/C/WKResourceLoadStatisticsManager.cpp
+
</ins><span class="cx">     UIProcess/API/C/mac/WKContextPrivateMac.mm
</span><span class="cx">     UIProcess/API/C/mac/WKPagePrivateMac.mm
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAPIAPIObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/API/APIObject.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/API/APIObject.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/Shared/API/APIObject.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -154,6 +154,7 @@
</span><span class="cx">         Vibration,
</span><span class="cx">         ViewportAttributes,
</span><span class="cx">         VisitedLinkStore,
</span><ins>+        WebResourceLoadStatisticsManager,
</ins><span class="cx">         WebsiteDataRecord,
</span><span class="cx">         WebsiteDataStore,
</span><span class="cx">         WebsitePolicies,
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAPIcWKBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/API/c/WKBase.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/API/c/WKBase.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/Shared/API/c/WKBase.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -127,6 +127,7 @@
</span><span class="cx"> typedef const struct OpaqueWKPageRunJavaScriptAlertResultListener* WKPageRunJavaScriptAlertResultListenerRef;
</span><span class="cx"> typedef const struct OpaqueWKPageRunJavaScriptConfirmResultListener* WKPageRunJavaScriptConfirmResultListenerRef;
</span><span class="cx"> typedef const struct OpaqueWKPageRunJavaScriptPromptResultListener* WKPageRunJavaScriptPromptResultListenerRef;
</span><ins>+typedef const struct OpaqueWKResourceLoadStatisticsManager* WKResourceLoadStatisticsManagerRef;
</ins><span class="cx"> typedef const struct OpaqueWKTextChecker* WKTextCheckerRef;
</span><span class="cx"> typedef const struct OpaqueWKSession* WKSessionRef;
</span><span class="cx"> typedef const struct OpaqueWKSessionState* WKSessionStateRef;
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebCoreArgumentCoderscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -2247,6 +2247,8 @@
</span><span class="cx">     
</span><span class="cx">     // User interaction
</span><span class="cx">     encoder &lt;&lt; statistics.hadUserInteraction;
</span><ins>+    encoder &lt;&lt; statistics.mostRecentUserInteraction;
+    encoder &lt;&lt; statistics.grandfathered;
</ins><span class="cx">     
</span><span class="cx">     // Top frame stats
</span><span class="cx">     encoder &lt;&lt; statistics.topFrameHasBeenNavigatedToBefore;
</span><span class="lines">@@ -2277,6 +2279,7 @@
</span><span class="cx">     // Prevalent Resource
</span><span class="cx">     encoder &lt;&lt; statistics.redirectedToOtherPrevalentResourceOrigins;
</span><span class="cx">     encoder &lt;&lt; statistics.isPrevalentResource;
</span><ins>+    encoder &lt;&lt; statistics.dataRecordsRemoved;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ArgumentCoder&lt;ResourceLoadStatistics&gt;::decode(Decoder&amp; decoder, WebCore::ResourceLoadStatistics&amp; statistics)
</span><span class="lines">@@ -2287,6 +2290,12 @@
</span><span class="cx">     // User interaction
</span><span class="cx">     if (!decoder.decode(statistics.hadUserInteraction))
</span><span class="cx">         return false;
</span><ins>+
+    if (!decoder.decode(statistics.mostRecentUserInteraction))
+        return false;
+
+    if (!decoder.decode(statistics.grandfathered))
+        return false;
</ins><span class="cx">     
</span><span class="cx">     // Top frame stats
</span><span class="cx">     if (!decoder.decode(statistics.topFrameHasBeenNavigatedToBefore))
</span><span class="lines">@@ -2357,7 +2366,10 @@
</span><span class="cx">     
</span><span class="cx">     if (!decoder.decode(statistics.isPrevalentResource))
</span><span class="cx">         return false;
</span><del>-    
</del><ins>+
+    if (!decoder.decode(statistics.dataRecordsRemoved))
+        return false;
+
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKAPICasth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/C/WKAPICast.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKAPICast.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKAPICast.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -107,6 +107,7 @@
</span><span class="cx"> class WebProtectionSpace;
</span><span class="cx"> class WebRenderLayer;
</span><span class="cx"> class WebRenderObject;
</span><ins>+class WebResourceLoadStatisticsManager;
</ins><span class="cx"> class WebTextChecker;
</span><span class="cx"> class WebUserContentControllerProxy;
</span><span class="cx"> class WebVibrationProxy;
</span><span class="lines">@@ -156,6 +157,7 @@
</span><span class="cx"> WK_ADD_API_MAPPING(WKProtectionSpaceRef, WebProtectionSpace)
</span><span class="cx"> WK_ADD_API_MAPPING(WKRenderLayerRef, WebRenderLayer)
</span><span class="cx"> WK_ADD_API_MAPPING(WKRenderObjectRef, WebRenderObject)
</span><ins>+WK_ADD_API_MAPPING(WKResourceLoadStatisticsManagerRef, WebResourceLoadStatisticsManager)
</ins><span class="cx"> WK_ADD_API_MAPPING(WKSessionStateRef, API::SessionState)
</span><span class="cx"> WK_ADD_API_MAPPING(WKTextCheckerRef, WebTextChecker)
</span><span class="cx"> WK_ADD_API_MAPPING(WKUserContentControllerRef, WebUserContentControllerProxy)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKResourceLoadStatisticsManagercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.cpp (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.cpp                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,87 @@
</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;
+#include &quot;WKResourceLoadStatisticsManager.h&quot;
+
+#include &quot;WKAPICast.h&quot;
+#include &quot;WebResourceLoadStatisticsManager.h&quot;
+
+using namespace WebKit;
+
+WKTypeID WKResourceLoadStatisticsManagerGetTypeID()
+{
+    return toAPI(WebResourceLoadStatisticsManager::APIType);
+}
+
+void WKResourceLoadStatisticsManagerSetPrevalentResource(WKStringRef hostName, bool value)
+{
+    WebResourceLoadStatisticsManager::setPrevalentResource(toWTFString(hostName), value);
+}
+
+bool WKResourceLoadStatisticsManagerIsPrevalentResource(WKStringRef hostName)
+{
+    return WebResourceLoadStatisticsManager::isPrevalentResource(toWTFString(hostName));
+}
+
+void WKResourceLoadStatisticsManagerSetHasHadUserInteraction(WKStringRef hostName, bool value)
+{
+    WebResourceLoadStatisticsManager::setHasHadUserInteraction(toWTFString(hostName), value);
+}
+
+bool WKResourceLoadStatisticsManagerIsHasHadUserInteraction(WKStringRef hostName)
+{
+    return WebResourceLoadStatisticsManager::hasHadUserInteraction(toWTFString(hostName));
+}
+
+void WKResourceLoadStatisticsManagerSetTimeToLiveUserInteraction(double seconds)
+{
+    WebResourceLoadStatisticsManager::setTimeToLiveUserInteraction(seconds);
+}
+
+void WKResourceLoadStatisticsManagerFireDataModificationHandler()
+{
+    WebResourceLoadStatisticsManager::fireDataModificationHandler();
+}
+
+void WKResourceLoadStatisticsManagerSetNotifyPagesWhenDataRecordsWereScanned(bool value)
+{
+    WebResourceLoadStatisticsManager::setNotifyPagesWhenDataRecordsWereScanned(value);
+}
+
+void WKResourceLoadStatisticsManagerSetShouldClassifyResourcesBeforeDataRecordsRemoval(bool value)
+{
+    WebResourceLoadStatisticsManager::setShouldClassifyResourcesBeforeDataRecordsRemoval(value);
+}
+
+void WKResourceLoadStatisticsManagerSetMinimumTimeBetweeenDataRecordsRemoval(double seconds)
+{
+    WebResourceLoadStatisticsManager::setMinimumTimeBetweeenDataRecordsRemoval(seconds);
+}
+
+void WKResourceLoadStatisticsManagerResetToConsistentState()
+{
+    WebResourceLoadStatisticsManager::resetToConsistentState();
+}
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICWKResourceLoadStatisticsManagerh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.h (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,51 @@
</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.
+ */
+
+#pragma once
+
+#include &lt;WebKit/WKBase.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+#ifdef __cplusplus
+extern &quot;C&quot; {
+#endif
+    
+    WK_EXPORT WKTypeID WKResourceLoadStatisticsManagerGetTypeID();
+    
+    WK_EXPORT void WKResourceLoadStatisticsManagerSetPrevalentResource(WKStringRef hostName, bool value);
+    WK_EXPORT bool WKResourceLoadStatisticsManagerIsPrevalentResource(WKStringRef hostName);
+    WK_EXPORT void WKResourceLoadStatisticsManagerSetHasHadUserInteraction(WKStringRef hostName, bool value);
+    WK_EXPORT bool WKResourceLoadStatisticsManagerIsHasHadUserInteraction(WKStringRef hostName);
+    WK_EXPORT void WKResourceLoadStatisticsManagerSetTimeToLiveUserInteraction(double seconds);
+    WK_EXPORT void WKResourceLoadStatisticsManagerSetReducedTimestampResolution(double seconds);
+    WK_EXPORT void WKResourceLoadStatisticsManagerFireDataModificationHandler();
+    WK_EXPORT void WKResourceLoadStatisticsManagerSetNotifyPagesWhenDataRecordsWereScanned(bool value);
+    WK_EXPORT void WKResourceLoadStatisticsManagerSetShouldClassifyResourcesBeforeDataRecordsRemoval(bool value);
+    WK_EXPORT void WKResourceLoadStatisticsManagerSetMinimumTimeBetweeenDataRecordsRemoval(double seconds);
+    WK_EXPORT void WKResourceLoadStatisticsManagerResetToConsistentState();
+
+#ifdef __cplusplus
+}
+#endif
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -200,6 +200,53 @@
</span><span class="cx">     return globalPageMap().get(pageID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebProcessProxy::deleteWebsiteDataForTopPrivatelyOwnedDomainsInAllPersistentDataStores(OptionSet&lt;WebsiteDataType&gt; dataTypes, Vector&lt;String&gt;&amp; topPrivatelyOwnedDomains, bool shouldNotifyPage, std::function&lt;void()&gt; completionHandler)
+{
+    struct CallbackAggregator : ThreadSafeRefCounted&lt;CallbackAggregator&gt; {
+        explicit CallbackAggregator(std::function&lt;void()&gt; completionHandler)
+            : completionHandler(WTFMove(completionHandler))
+        {
+        }
+        
+        void addPendingCallback()
+        {
+            ++pendingCallbacks;
+        }
+        
+        void removePendingCallback()
+        {
+            ASSERT(pendingCallbacks);
+            --pendingCallbacks;
+            
+            callIfNeeded();
+        }
+        
+        void callIfNeeded()
+        {
+            if (!pendingCallbacks)
+                completionHandler();
+        }
+        
+        unsigned pendingCallbacks = 0;
+        std::function&lt;void()&gt; completionHandler;
+    };
+    
+    RefPtr&lt;CallbackAggregator&gt; callbackAggregator = adoptRef(new CallbackAggregator(WTFMove(completionHandler)));
+
+    for (auto&amp; page : globalPageMap()) {
+        if (!page.value-&gt;websiteDataStore().isPersistent())
+            continue;
+        callbackAggregator-&gt;addPendingCallback();
+        page.value-&gt;websiteDataStore().removeDataForTopPrivatelyOwnedDomains(dataTypes, { }, topPrivatelyOwnedDomains, [callbackAggregator, shouldNotifyPage, page]() {
+            if (shouldNotifyPage)
+                page.value-&gt;postMessageToInjectedBundle(&quot;WebsiteDataDeletionForTopPrivatelyOwnedDomainsFinished&quot;, nullptr);
+            WTF::RunLoop::main().dispatch([callbackAggregator] {
+                callbackAggregator-&gt;removePendingCallback();
+            });
+        });
+    }
+}
+
</ins><span class="cx"> Ref&lt;WebPageProxy&gt; WebProcessProxy::createWebPage(PageClient&amp; pageClient, Ref&lt;API::PageConfiguration&gt;&amp;&amp; pageConfiguration)
</span><span class="cx"> {
</span><span class="cx">     uint64_t pageID = generatePageID();
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessProxy.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessProxy.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/UIProcess/WebProcessProxy.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -120,6 +120,7 @@
</span><span class="cx">     void fetchWebsiteData(WebCore::SessionID, OptionSet&lt;WebsiteDataType&gt;, Function&lt;void(WebsiteData)&gt; completionHandler);
</span><span class="cx">     void deleteWebsiteData(WebCore::SessionID, OptionSet&lt;WebsiteDataType&gt;, std::chrono::system_clock::time_point modifiedSince, Function&lt;void()&gt; completionHandler);
</span><span class="cx">     void deleteWebsiteDataForOrigins(WebCore::SessionID, OptionSet&lt;WebsiteDataType&gt;, const Vector&lt;WebCore::SecurityOriginData&gt;&amp;, Function&lt;void()&gt; completionHandler);
</span><ins>+    static void deleteWebsiteDataForTopPrivatelyOwnedDomainsInAllPersistentDataStores(OptionSet&lt;WebsiteDataType&gt;, Vector&lt;String&gt;&amp; topPrivatelyOwnedDomains, bool shouldNotifyPages, std::function&lt;void()&gt; completionHandler);
</ins><span class="cx"> 
</span><span class="cx">     void enableSuddenTermination();
</span><span class="cx">     void disableSuddenTermination();
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebResourceLoadStatisticsManagercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.cpp (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.cpp                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,100 @@
</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;
+#include &quot;WebResourceLoadStatisticsManager.h&quot;
+
+#include &quot;Logging.h&quot;
+#include &quot;WebResourceLoadStatisticsStore.h&quot;
+#include &lt;WebCore/ResourceLoadObserver.h&gt;
+#include &lt;WebCore/URL.h&gt;
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void WebResourceLoadStatisticsManager::setPrevalentResource(const String&amp; hostName, bool value)
+{
+    if (value)
+        WebCore::ResourceLoadObserver::sharedObserver().setPrevalentResource(URL(URL(), hostName));
+    else
+        WebCore::ResourceLoadObserver::sharedObserver().clearPrevalentResource(URL(URL(), hostName));
+}
+
+bool WebResourceLoadStatisticsManager::isPrevalentResource(const String&amp; hostName)
+{
+    return WebCore::ResourceLoadObserver::sharedObserver().isPrevalentResource(URL(URL(), hostName));
+}
+    
+void WebResourceLoadStatisticsManager::setHasHadUserInteraction(const String&amp; hostName, bool value)
+{
+    if (value)
+        WebCore::ResourceLoadObserver::sharedObserver().logUserInteraction(URL(URL(), hostName));
+    else
+        WebCore::ResourceLoadObserver::sharedObserver().clearUserInteraction(URL(URL(), hostName));
+}
+
+bool WebResourceLoadStatisticsManager::hasHadUserInteraction(const String&amp; hostName)
+{
+    return WebCore::ResourceLoadObserver::sharedObserver().hasHadUserInteraction(URL(URL(), hostName));
+}
+
+void WebResourceLoadStatisticsManager::setTimeToLiveUserInteraction(double seconds)
+{
+    WebCore::ResourceLoadObserver::sharedObserver().setTimeToLiveUserInteraction(seconds);
+}
+
+void WebResourceLoadStatisticsManager::fireDataModificationHandler()
+{
+    WebCore::ResourceLoadObserver::sharedObserver().fireDataModificationHandler();
+}
+
+void WebResourceLoadStatisticsManager::setNotifyPagesWhenDataRecordsWereScanned(bool value)
+{
+    WebResourceLoadStatisticsStore::setNotifyPagesWhenDataRecordsWereScanned(value);
+}
+
+void WebResourceLoadStatisticsManager::setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value)
+{
+    WebResourceLoadStatisticsStore::setShouldClassifyResourcesBeforeDataRecordsRemoval(value);
+}
+
+void WebResourceLoadStatisticsManager::setMinimumTimeBetweeenDataRecordsRemoval(double seconds)
+{
+    WebResourceLoadStatisticsStore::setMinimumTimeBetweeenDataRecordsRemoval(seconds);
+}
+
+void WebResourceLoadStatisticsManager::resetToConsistentState()
+{
+    WebCore::ResourceLoadObserver::sharedObserver().setTimeToLiveUserInteraction(2592000);
+    WebResourceLoadStatisticsStore::setNotifyPagesWhenDataRecordsWereScanned(false);
+    WebResourceLoadStatisticsStore::setShouldClassifyResourcesBeforeDataRecordsRemoval(true);
+    WebResourceLoadStatisticsStore::setMinimumTimeBetweeenDataRecordsRemoval(60);
+    auto store = WebCore::ResourceLoadObserver::sharedObserver().statisticsStore();
+    if (store)
+        store-&gt;clear();
+}
+    
+} // namespace WebKit
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebResourceLoadStatisticsManagerh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.h (0 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -0,0 +1,56 @@
</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.
+ */
+
+#pragma once
+
+#include &quot;APIObject.h&quot;
+
+#include &lt;wtf/RefPtr.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebKit {
+
+class WebResourceLoadStatisticsManager : public API::ObjectImpl&lt;API::Object::Type::WebResourceLoadStatisticsManager&gt; {
+public:
+    static Ref&lt;WebResourceLoadStatisticsManager&gt; create()
+    {
+        return adoptRef(*new WebResourceLoadStatisticsManager());
+    }
+    static void setPrevalentResource(const String&amp; hostName, bool value);
+    static bool isPrevalentResource(const String&amp; hostName);
+    static void setHasHadUserInteraction(const String&amp; hostName, bool value);
+    static bool hasHadUserInteraction(const String&amp; hostName);
+    static void setTimeToLiveUserInteraction(double seconds);
+    static void setReducedTimestampResolution(double seconds);
+    static void fireDataModificationHandler();
+    static void setNotifyPagesWhenDataRecordsWereScanned(bool);
+    static void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value);
+    static void setMinimumTimeBetweeenDataRecordsRemoval(double seconds);
+    static void resetToConsistentState();
+
+private:
+};
+
+} // namespace WebKit
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebResourceLoadStatisticsStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -26,9 +26,9 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;WebResourceLoadStatisticsStore.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;APIWebsiteDataStore.h&quot;
</del><span class="cx"> #include &quot;WebProcessMessages.h&quot;
</span><span class="cx"> #include &quot;WebProcessPool.h&quot;
</span><ins>+#include &quot;WebProcessProxy.h&quot;
</ins><span class="cx"> #include &quot;WebResourceLoadStatisticsStoreMessages.h&quot;
</span><span class="cx"> #include &quot;WebsiteDataFetchOption.h&quot;
</span><span class="cx"> #include &quot;WebsiteDataType.h&quot;
</span><span class="lines">@@ -45,9 +45,11 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><del>-static const auto numberOfSecondsBetweenRemovingDataRecords = 60;
</del><span class="cx"> static const auto featureVectorLengthThreshold = 3;
</span><ins>+static auto minimumTimeBetweeenDataRecordsRemoval = 60;
</ins><span class="cx"> static OptionSet&lt;WebKit::WebsiteDataType&gt; dataTypesToRemove;
</span><ins>+static auto notifyPages = false;
+static auto shouldClassifyResourcesBeforeDataRecordsRemoval = true;
</ins><span class="cx"> 
</span><span class="cx"> Ref&lt;WebResourceLoadStatisticsStore&gt; WebResourceLoadStatisticsStore::create(const String&amp; resourceLoadStatisticsDirectory)
</span><span class="cx"> {
</span><span class="lines">@@ -55,7 +57,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String&amp; resourceLoadStatisticsDirectory)
</span><del>-    : m_resourceStatisticsStore(ResourceLoadStatisticsStore::create())
</del><ins>+    : m_resourceLoadStatisticsStore(ResourceLoadStatisticsStore::create())
</ins><span class="cx">     , m_statisticsQueue(WorkQueue::create(&quot;WebResourceLoadStatisticsStore Process Data Queue&quot;))
</span><span class="cx">     , m_storagePath(resourceLoadStatisticsDirectory)
</span><span class="cx"> {
</span><span class="lines">@@ -65,6 +67,22 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebResourceLoadStatisticsStore::setNotifyPagesWhenDataRecordsWereScanned(bool always)
+{
+    notifyPages = always;
+}
+
+void WebResourceLoadStatisticsStore::setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value)
+{
+    shouldClassifyResourcesBeforeDataRecordsRemoval = value;
+}
+
+void WebResourceLoadStatisticsStore::setMinimumTimeBetweeenDataRecordsRemoval(double seconds)
+{
+    if (seconds &gt;= 0)
+        minimumTimeBetweeenDataRecordsRemoval = seconds;
+}
+
</ins><span class="cx"> bool WebResourceLoadStatisticsStore::hasPrevalentResourceCharacteristics(const ResourceLoadStatistics&amp; resourceStatistic)
</span><span class="cx"> {
</span><span class="cx">     auto subresourceUnderTopFrameOriginsCount = resourceStatistic.subresourceUnderTopFrameOrigins.size();
</span><span class="lines">@@ -111,66 +129,49 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     double now = currentTime();
</span><del>-    if (!m_lastTimeDataRecordsWereRemoved) {
-        m_lastTimeDataRecordsWereRemoved = now;
</del><ins>+    if (m_lastTimeDataRecordsWereRemoved
+        &amp;&amp; now &lt; m_lastTimeDataRecordsWereRemoved + minimumTimeBetweeenDataRecordsRemoval)
</ins><span class="cx">         return;
</span><del>-    }
</del><span class="cx"> 
</span><del>-    if (now &lt; (m_lastTimeDataRecordsWereRemoved + numberOfSecondsBetweenRemovingDataRecords))
-        return;
-
</del><span class="cx">     m_dataRecordsRemovalPending = true;
</span><span class="cx">     m_lastTimeDataRecordsWereRemoved = now;
</span><span class="cx"> 
</span><span class="cx">     if (dataTypesToRemove.isEmpty()) {
</span><span class="cx">         dataTypesToRemove |= WebsiteDataType::Cookies;
</span><ins>+        dataTypesToRemove |= WebsiteDataType::DiskCache;
+        dataTypesToRemove |= WebsiteDataType::MemoryCache;
+        dataTypesToRemove |= WebsiteDataType::OfflineWebApplicationCache;
+        dataTypesToRemove |= WebsiteDataType::SessionStorage;
</ins><span class="cx">         dataTypesToRemove |= WebsiteDataType::LocalStorage;
</span><ins>+        dataTypesToRemove |= WebsiteDataType::WebSQLDatabases;
</ins><span class="cx">         dataTypesToRemove |= WebsiteDataType::IndexedDBDatabases;
</span><del>-        dataTypesToRemove |= WebsiteDataType::DiskCache;
-        dataTypesToRemove |= WebsiteDataType::MemoryCache;
</del><ins>+        dataTypesToRemove |= WebsiteDataType::MediaKeys;
+        dataTypesToRemove |= WebsiteDataType::HSTSCache;
+        dataTypesToRemove |= WebsiteDataType::SearchFieldRecentSearches;
+#if ENABLE(NETSCAPE_PLUGIN_API)
+        dataTypesToRemove |= WebsiteDataType::PlugInData;
+#endif
+#if ENABLE(MEDIA_STREAM)
+        dataTypesToRemove |= WebsiteDataType::MediaDeviceIdentifier;
+#endif
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Switch to the main thread to get the default website data store
</span><span class="cx">     RunLoop::main().dispatch([prevalentResourceDomains = WTFMove(prevalentResourceDomains), this] () mutable {
</span><del>-        auto&amp; websiteDataStore = API::WebsiteDataStore::defaultDataStore()-&gt;websiteDataStore();
-
-        websiteDataStore.fetchData(dataTypesToRemove, { }, [prevalentResourceDomains = WTFMove(prevalentResourceDomains), this](auto websiteDataRecords) {
-            Vector&lt;WebsiteDataRecord&gt; dataRecords;
-            Vector&lt;String&gt; prevalentResourceDomainsWithDataRecords;
-            for (auto&amp; websiteDataRecord : websiteDataRecords) {
-                for (auto&amp; prevalentResourceDomain : prevalentResourceDomains) {
-                    if (websiteDataRecord.displayName.endsWithIgnoringASCIICase(prevalentResourceDomain)) {
-                        auto suffixStart = websiteDataRecord.displayName.length() - prevalentResourceDomain.length();
-                        if (!suffixStart || websiteDataRecord.displayName[suffixStart - 1] == '.') {
-                            dataRecords.append(websiteDataRecord);
-                            prevalentResourceDomainsWithDataRecords.append(prevalentResourceDomain);
-                        }
-                    }
-                }
-            }
-
-            if (!dataRecords.size()) {
-                m_dataRecordsRemovalPending = false;
-                return;
-            }
-
-            auto&amp; websiteDataStore = API::WebsiteDataStore::defaultDataStore()-&gt;websiteDataStore();
-            websiteDataStore.removeData(dataTypesToRemove, dataRecords, [prevalentResourceDomainsWithDataRecords = WTFMove(prevalentResourceDomainsWithDataRecords), this] {
-                this-&gt;coreStore().updateStatisticsForRemovedDataRecords(prevalentResourceDomainsWithDataRecords);
-                m_dataRecordsRemovalPending = false;
-            });
</del><ins>+        WebProcessProxy::deleteWebsiteDataForTopPrivatelyOwnedDomainsInAllPersistentDataStores(dataTypesToRemove, prevalentResourceDomains, notifyPages, [this]() mutable {
+            m_dataRecordsRemovalPending = false;
</ins><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated(const Vector&lt;WebCore::ResourceLoadStatistics&gt;&amp; origins)
</del><ins>+void WebResourceLoadStatisticsStore::processStatisticsAndDataRecords()
</ins><span class="cx"> {
</span><del>-    coreStore().mergeStatistics(origins);
-
-    coreStore().processStatistics([this] (ResourceLoadStatistics&amp; resourceStatistic) {
-        classifyResource(resourceStatistic);
-        removeDataRecords();
-    });
</del><ins>+    if (shouldClassifyResourcesBeforeDataRecordsRemoval) {
+        coreStore().processStatistics([this] (ResourceLoadStatistics&amp; resourceStatistic) {
+            classifyResource(resourceStatistic);
+        });
+    }
+    removeDataRecords();
</ins><span class="cx">     
</span><span class="cx">     auto encoder = coreStore().createEncoderFromData();
</span><span class="cx">     
</span><span class="lines">@@ -177,6 +178,12 @@
</span><span class="cx">     writeEncoderToDisk(*encoder.get(), &quot;full_browsing_session&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated(const Vector&lt;WebCore::ResourceLoadStatistics&gt;&amp; origins)
+{
+    coreStore().mergeStatistics(origins);
+    processStatisticsAndDataRecords();
+}
+
</ins><span class="cx"> void WebResourceLoadStatisticsStore::setResourceLoadStatisticsEnabled(bool enabled)
</span><span class="cx"> {
</span><span class="cx">     if (enabled == m_resourceLoadStatisticsEnabled)
</span><span class="lines">@@ -192,9 +199,15 @@
</span><span class="cx">     return m_resourceLoadStatisticsEnabled;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> void WebResourceLoadStatisticsStore::registerSharedResourceLoadObserver()
</span><span class="cx"> {
</span><del>-    ResourceLoadObserver::sharedObserver().setStatisticsStore(m_resourceStatisticsStore.copyRef());
</del><ins>+    ResourceLoadObserver::sharedObserver().setStatisticsStore(m_resourceLoadStatisticsStore.copyRef());
+    m_resourceLoadStatisticsStore-&gt;setNotificationCallback([this] {
+        if (m_resourceLoadStatisticsStore-&gt;isEmpty())
+            return;
+        processStatisticsAndDataRecords();
+    });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebResourceLoadStatisticsStore::readDataFromDiskIfNeeded()
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebResourceLoadStatisticsStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -51,6 +51,9 @@
</span><span class="cx"> class WebResourceLoadStatisticsStore : public IPC::Connection::WorkQueueMessageReceiver {
</span><span class="cx"> public:
</span><span class="cx">     static Ref&lt;WebResourceLoadStatisticsStore&gt; create(const String&amp;);
</span><ins>+    static void setNotifyPagesWhenDataRecordsWereScanned(bool);
+    static void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool);
+    static void setMinimumTimeBetweeenDataRecordsRemoval(double);
</ins><span class="cx">     virtual ~WebResourceLoadStatisticsStore();
</span><span class="cx">     
</span><span class="cx">     void setResourceLoadStatisticsEnabled(bool);
</span><span class="lines">@@ -65,14 +68,14 @@
</span><span class="cx"> 
</span><span class="cx">     void readDataFromDiskIfNeeded();
</span><span class="cx"> 
</span><del>-    void mergeStatistics(const Vector&lt;WebCore::ResourceLoadStatistics&gt;&amp;);
</del><ins>+    WebCore::ResourceLoadStatisticsStore&amp; coreStore() { return m_resourceLoadStatisticsStore.get(); }
+    const WebCore::ResourceLoadStatisticsStore&amp; coreStore() const { return m_resourceLoadStatisticsStore.get(); }
</ins><span class="cx"> 
</span><del>-    WebCore::ResourceLoadStatisticsStore&amp; coreStore() { return m_resourceStatisticsStore.get(); }
-    const WebCore::ResourceLoadStatisticsStore&amp; coreStore() const { return m_resourceStatisticsStore.get(); }
-
</del><span class="cx"> private:
</span><span class="cx">     explicit WebResourceLoadStatisticsStore(const String&amp;);
</span><span class="cx"> 
</span><ins>+    void processStatisticsAndDataRecords();
+
</ins><span class="cx">     bool hasPrevalentResourceCharacteristics(const WebCore::ResourceLoadStatistics&amp;);
</span><span class="cx">     void classifyResource(WebCore::ResourceLoadStatistics&amp;);
</span><span class="cx">     void removeDataRecords();
</span><span class="lines">@@ -85,7 +88,7 @@
</span><span class="cx">     void writeEncoderToDisk(WebCore::KeyedEncoder&amp;, const String&amp; label) const;
</span><span class="cx">     std::unique_ptr&lt;WebCore::KeyedDecoder&gt; createDecoderFromDisk(const String&amp; label) const;
</span><span class="cx"> 
</span><del>-    Ref&lt;WebCore::ResourceLoadStatisticsStore&gt; m_resourceStatisticsStore;
</del><ins>+    Ref&lt;WebCore::ResourceLoadStatisticsStore&gt; m_resourceLoadStatisticsStore;
</ins><span class="cx">     Ref&lt;WTF::WorkQueue&gt; m_statisticsQueue;
</span><span class="cx">     String m_storagePath;
</span><span class="cx">     bool m_resourceLoadStatisticsEnabled { false };
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebsiteDataWebsiteDataStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -473,6 +473,35 @@
</span><span class="cx">     callbackAggregator-&gt;callIfNeeded();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebsiteDataStore::fetchDataForTopPrivatelyOwnedDomains(OptionSet&lt;WebsiteDataType&gt; dataTypes, OptionSet&lt;WebsiteDataFetchOption&gt; fetchOptions, const Vector&lt;String&gt;&amp; topPrivatelyOwnedDomains, std::function&lt;void(Vector&lt;WebsiteDataRecord&gt;)&gt; completionHandler)
+{
+    fetchData(dataTypes, fetchOptions, [topPrivatelyOwnedDomains, completionHandler, this](auto existingDataRecords) {
+        Vector&lt;WebsiteDataRecord&gt; matchingDataRecords;
+        Vector&lt;String&gt; domainsWithDataRecords;
+        for (auto&amp; dataRecord : existingDataRecords) {
+            bool dataRecordAdded;
+            for (auto&amp; dataRecordOriginData : dataRecord.origins) {
+                dataRecordAdded = false;
+                String dataRecordHost = dataRecordOriginData.securityOrigin().get().host();
+                for (auto&amp; topPrivatelyOwnedDomain : topPrivatelyOwnedDomains) {
+                    if (dataRecordHost.endsWithIgnoringASCIICase(topPrivatelyOwnedDomain)) {
+                        auto suffixStart = dataRecordHost.length() - topPrivatelyOwnedDomain.length();
+                        if (!suffixStart || dataRecordHost[suffixStart - 1] == '.') {
+                            matchingDataRecords.append(dataRecord);
+                            domainsWithDataRecords.append(topPrivatelyOwnedDomain);
+                            dataRecordAdded = true;
+                            break;
+                        }
+                    }
+                }
+                if (dataRecordAdded)
+                    break;
+            }
+        }
+        completionHandler(matchingDataRecords);
+    });
+}
+    
</ins><span class="cx"> static ProcessAccessType computeNetworkProcessAccessTypeForDataRemoval(OptionSet&lt;WebsiteDataType&gt; dataTypes, bool isNonPersistentStore)
</span><span class="cx"> {
</span><span class="cx">     ProcessAccessType processAccessType = ProcessAccessType::None;
</span><span class="lines">@@ -998,6 +1027,15 @@
</span><span class="cx">     callbackAggregator-&gt;callIfNeeded();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebsiteDataStore::removeDataForTopPrivatelyOwnedDomains(OptionSet&lt;WebsiteDataType&gt; dataTypes, OptionSet&lt;WebsiteDataFetchOption&gt; fetchOptions, const Vector&lt;String&gt;&amp; topPrivatelyOwnedDomains, std::function&lt;void()&gt; completionHandler)
+{
+    fetchDataForTopPrivatelyOwnedDomains(dataTypes, fetchOptions, topPrivatelyOwnedDomains, [dataTypes, completionHandler, this](auto websiteDataRecords) {
+        this-&gt;removeData(dataTypes, websiteDataRecords, [completionHandler]() {
+            completionHandler();
+        });
+    });
+}
+
</ins><span class="cx"> void WebsiteDataStore::webPageWasAdded(WebPageProxy&amp; webPageProxy)
</span><span class="cx"> {
</span><span class="cx">     if (m_storageManager)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebsiteDataWebsiteDataStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -84,8 +84,10 @@
</span><span class="cx">     static void cloneSessionData(WebPageProxy&amp; sourcePage, WebPageProxy&amp; newPage);
</span><span class="cx"> 
</span><span class="cx">     void fetchData(OptionSet&lt;WebsiteDataType&gt;, OptionSet&lt;WebsiteDataFetchOption&gt;, std::function&lt;void (Vector&lt;WebsiteDataRecord&gt;)&gt; completionHandler);
</span><ins>+    void fetchDataForTopPrivatelyOwnedDomains(OptionSet&lt;WebsiteDataType&gt;, OptionSet&lt;WebsiteDataFetchOption&gt;, const Vector&lt;String&gt;&amp; topPrivatelyOwnedDomains, std::function&lt;void(Vector&lt;WebsiteDataRecord&gt;)&gt; completionHandler);
</ins><span class="cx">     void removeData(OptionSet&lt;WebsiteDataType&gt;, std::chrono::system_clock::time_point modifiedSince, std::function&lt;void ()&gt; completionHandler);
</span><span class="cx">     void removeData(OptionSet&lt;WebsiteDataType&gt;, const Vector&lt;WebsiteDataRecord&gt;&amp;, std::function&lt;void ()&gt; completionHandler);
</span><ins>+    void removeDataForTopPrivatelyOwnedDomains(OptionSet&lt;WebsiteDataType&gt;, OptionSet&lt;WebsiteDataFetchOption&gt;, const Vector&lt;String&gt;&amp; topPrivatelyOwnedDomains, std::function&lt;void()&gt; completionHandler);
</ins><span class="cx"> 
</span><span class="cx">     StorageManager* storageManager() { return m_storageManager.get(); }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1146,6 +1146,10 @@
</span><span class="cx">                 6501BD1A12F1243400E9F248 /* WKBundleInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65B86F1712F11D7B00B7DD8A /* WKBundleInspector.cpp */; };
</span><span class="cx">                 659C551E130006410025C0C2 /* InjectedBundlePageResourceLoadClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6546A82913000164000CEB1C /* InjectedBundlePageResourceLoadClient.cpp */; };
</span><span class="cx">                 65B86F1E12F11DE300B7DD8A /* WKBundleInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B86F1812F11D7B00B7DD8A /* WKBundleInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                6BE9699C1E43B3FF008B7483 /* WKResourceLoadStatisticsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BE9699B1E43B3FF008B7483 /* WKResourceLoadStatisticsManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                6BE9699E1E43B41D008B7483 /* WKResourceLoadStatisticsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BE9699D1E43B41D008B7483 /* WKResourceLoadStatisticsManager.cpp */; };
+                6BE969A01E43B86E008B7483 /* WebResourceLoadStatisticsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BE9699F1E43B86E008B7483 /* WebResourceLoadStatisticsManager.h */; };
+                6BE969A21E43B8A4008B7483 /* WebResourceLoadStatisticsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BE969A11E43B8A4008B7483 /* WebResourceLoadStatisticsManager.cpp */; };
</ins><span class="cx">                 6EE849C81368D9390038D481 /* WKInspectorPrivateMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE849C61368D92D0038D481 /* WKInspectorPrivateMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 728E86F11795188C0087879E /* WebColorPickerMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 728E86EF1795188C0087879E /* WebColorPickerMac.h */; };
</span><span class="cx">                 728E86F21795188C0087879E /* WebColorPickerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 728E86F01795188C0087879E /* WebColorPickerMac.mm */; };
</span><span class="lines">@@ -3329,6 +3333,10 @@
</span><span class="cx">                 6546A82A13000164000CEB1C /* InjectedBundlePageResourceLoadClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundlePageResourceLoadClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 65B86F1712F11D7B00B7DD8A /* WKBundleInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKBundleInspector.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 65B86F1812F11D7B00B7DD8A /* WKBundleInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKBundleInspector.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                6BE9699B1E43B3FF008B7483 /* WKResourceLoadStatisticsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKResourceLoadStatisticsManager.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                6BE9699D1E43B41D008B7483 /* WKResourceLoadStatisticsManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKResourceLoadStatisticsManager.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                6BE9699F1E43B86E008B7483 /* WebResourceLoadStatisticsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebResourceLoadStatisticsManager.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                6BE969A11E43B8A4008B7483 /* WebResourceLoadStatisticsManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebResourceLoadStatisticsManager.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 6D8A91A511F0EFD100DD01FE /* com.apple.WebProcess.sb.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = com.apple.WebProcess.sb.in; path = WebProcess/com.apple.WebProcess.sb.in; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 6EE849C61368D92D0038D481 /* WKInspectorPrivateMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKInspectorPrivateMac.h; path = mac/WKInspectorPrivateMac.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 728E86EF1795188C0087879E /* WebColorPickerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebColorPickerMac.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -6534,6 +6542,8 @@
</span><span class="cx">                                 BC111B0D112F5E4F00337BAB /* WebProcessProxy.cpp */,
</span><span class="cx">                                 BC032DCF10F4389F0058C15A /* WebProcessProxy.h */,
</span><span class="cx">                                 BCEE7AB312817095009827DA /* WebProcessProxy.messages.in */,
</span><ins>+                                6BE9699F1E43B86E008B7483 /* WebResourceLoadStatisticsManager.h */,
+                                6BE969A11E43B8A4008B7483 /* WebResourceLoadStatisticsManager.cpp */,
</ins><span class="cx">                                 7A9CD8C01C77984900D9F6C7 /* WebResourceLoadStatisticsStore.cpp */,
</span><span class="cx">                                 7A9CD8C11C77984900D9F6C7 /* WebResourceLoadStatisticsStore.h */,
</span><span class="cx">                                 7A9CD8C21C779AD600D9F6C7 /* WebResourceLoadStatisticsStore.messages.in */,
</span><span class="lines">@@ -6722,6 +6732,8 @@
</span><span class="cx">                                 518ACAE912AEE6BB00B04B83 /* WKProtectionSpaceTypes.h */,
</span><span class="cx">                                 33367638130C99DC006C9DE2 /* WKResourceCacheManager.cpp */,
</span><span class="cx">                                 33367639130C99DC006C9DE2 /* WKResourceCacheManager.h */,
</span><ins>+                                6BE9699D1E43B41D008B7483 /* WKResourceLoadStatisticsManager.cpp */,
+                                6BE9699B1E43B3FF008B7483 /* WKResourceLoadStatisticsManager.h */,
</ins><span class="cx">                                 1ADE46B01954EC61000F7985 /* WKSessionStateRef.cpp */,
</span><span class="cx">                                 1ADE46B11954EC61000F7985 /* WKSessionStateRef.h */,
</span><span class="cx">                                 314888FE1D91B11D00377042 /* WKTextChecker.cpp */,
</span><span class="lines">@@ -8574,6 +8586,7 @@
</span><span class="cx">                                 9321D58A1A38F196008052BE /* WKImmediateActionTypes.h in Headers */,
</span><span class="cx">                                 1C8E293912761E5B00BC7BD0 /* WKInspector.h in Headers */,
</span><span class="cx">                                 0F3C725B196F604E00AEDD0C /* WKInspectorHighlightView.h in Headers */,
</span><ins>+                                6BE969A01E43B86E008B7483 /* WebResourceLoadStatisticsManager.h in Headers */,
</ins><span class="cx">                                 A54293A4195A43DA002782C7 /* WKInspectorNodeSearchGestureRecognizer.h in Headers */,
</span><span class="cx">                                 6EE849C81368D9390038D481 /* WKInspectorPrivateMac.h in Headers */,
</span><span class="cx">                                 51A9E10B1315CD18009E7031 /* WKKeyValueStorageManager.h in Headers */,
</span><span class="lines">@@ -8758,6 +8771,7 @@
</span><span class="cx">                                 1A3CC16718906ACF001E6ED8 /* WKWebView.h in Headers */,
</span><span class="cx">                                 1ADF591B1890528E0043C145 /* WKWebViewConfiguration.h in Headers */,
</span><span class="cx">                                 2D7AAFD618C956AF00A7ACD4 /* WKWebViewConfigurationInternal.h in Headers */,
</span><ins>+                                6BE9699C1E43B3FF008B7483 /* WKResourceLoadStatisticsManager.h in Headers */,
</ins><span class="cx">                                 1AC1415118AC47EE006C602C /* WKWebViewConfigurationPrivate.h in Headers */,
</span><span class="cx">                                 41DC459C1E3DBB2800B11F51 /* LibWebRTCSocketClient.h in Headers */,
</span><span class="cx">                                 2D7AAFD318C8640600A7ACD4 /* WKWebViewContentProvider.h in Headers */,
</span><span class="lines">@@ -9978,6 +9992,7 @@
</span><span class="cx">                                 3760881E150413E900FC82C7 /* WebRenderObject.cpp in Sources */,
</span><span class="cx">                                 510AFFB916542048001BA05E /* WebResourceLoader.cpp in Sources */,
</span><span class="cx">                                 51F060E11654318500F3281B /* WebResourceLoaderMessageReceiver.cpp in Sources */,
</span><ins>+                                6BE969A21E43B8A4008B7483 /* WebResourceLoadStatisticsManager.cpp in Sources */,
</ins><span class="cx">                                 51F060E11654318500F3281C /* WebRTCSocketMessageReceiver.cpp in Sources */,
</span><span class="cx">                                 51F060E11654318500F3282C /* WebRTCResolverMessageReceiver.cpp in Sources */,
</span><span class="cx">                                 51F060E11654318500F3281D /* NetworkRTCSocketMessageReceiver.cpp in Sources */,
</span><span class="lines">@@ -10168,6 +10183,7 @@
</span><span class="cx">                                 37948408150C4B9700E52CE9 /* WKRenderLayer.cpp in Sources */,
</span><span class="cx">                                 37608822150414F700FC82C7 /* WKRenderObject.cpp in Sources */,
</span><span class="cx">                                 3336763A130C99DC006C9DE2 /* WKResourceCacheManager.cpp in Sources */,
</span><ins>+                                6BE9699E1E43B41D008B7483 /* WKResourceLoadStatisticsManager.cpp in Sources */,
</ins><span class="cx">                                 1A7E377818E4A4FE003D0FFF /* WKScriptMessage.mm in Sources */,
</span><span class="cx">                                 0FCB4E5518BBE044000FCFC9 /* WKScrollView.mm in Sources */,
</span><span class="cx">                                 51CD1C661B34B9DC00142CA5 /* WKSecurityOrigin.mm in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -168,7 +168,7 @@
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     , m_webSQLiteDatabaseTracker(*this)
</span><span class="cx"> #endif
</span><del>-    , m_resourceLoadStatisticsStorage(WebCore::ResourceLoadStatisticsStore::create())
</del><ins>+    , m_resourceLoadStatisticsStore(WebCore::ResourceLoadStatisticsStore::create())
</ins><span class="cx"> {
</span><span class="cx">     // Initialize our platform strategies.
</span><span class="cx">     WebPlatformStrategies::initialize();
</span><span class="lines">@@ -190,8 +190,8 @@
</span><span class="cx"> 
</span><span class="cx">     m_plugInAutoStartOriginHashes.add(SessionID::defaultSessionID(), HashMap&lt;unsigned, double&gt;());
</span><span class="cx"> 
</span><del>-    ResourceLoadObserver::sharedObserver().setStatisticsStore(m_resourceLoadStatisticsStorage.copyRef());
-    m_resourceLoadStatisticsStorage-&gt;setNotificationCallback([this] {
</del><ins>+    ResourceLoadObserver::sharedObserver().setStatisticsStore(m_resourceLoadStatisticsStore.copyRef());
+    m_resourceLoadStatisticsStore-&gt;setNotificationCallback([this] {
</ins><span class="cx">         if (m_statisticsChangedTimer.isActive())
</span><span class="cx">             return;
</span><span class="cx">         m_statisticsChangedTimer.startOneShot(std::chrono::seconds(5));
</span><span class="lines">@@ -1389,10 +1389,10 @@
</span><span class="cx"> 
</span><span class="cx"> void WebProcess::statisticsChangedTimerFired()
</span><span class="cx"> {
</span><del>-    if (m_resourceLoadStatisticsStorage-&gt;isEmpty())
</del><ins>+    if (m_resourceLoadStatisticsStore-&gt;isEmpty())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    parentProcessConnection()-&gt;send(Messages::WebResourceLoadStatisticsStore::ResourceLoadStatisticsUpdated(m_resourceLoadStatisticsStorage-&gt;takeStatistics()), 0);
</del><ins>+    parentProcessConnection()-&gt;send(Messages::WebResourceLoadStatisticsStore::ResourceLoadStatisticsUpdated(m_resourceLoadStatisticsStore-&gt;takeStatistics()), 0);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebProcess::setResourceLoadStatisticsEnabled(bool enabled)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -412,7 +412,7 @@
</span><span class="cx">     WebSQLiteDatabaseTracker m_webSQLiteDatabaseTracker;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    Ref&lt;WebCore::ResourceLoadStatisticsStore&gt; m_resourceLoadStatisticsStorage;
</del><ins>+    Ref&lt;WebCore::ResourceLoadStatisticsStore&gt; m_resourceLoadStatisticsStore;
</ins><span class="cx"> 
</span><span class="cx">     unsigned m_pagesMarkingLayersAsVolatile { 0 };
</span><span class="cx">     bool m_suppressMemoryPressureHandler { false };
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Tools/ChangeLog        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,3 +1,51 @@
</span><ins>+2017-02-10  John Wilander  &lt;wilander@apple.com&gt;
+
+        Updates to Resource Load Statistics: Get the right website data store and introduce timeout for user interaction
+        https://bugs.webkit.org/show_bug.cgi?id=167474
+        &lt;rdar://problem/24681808&gt;
+        &lt;rdar://problem/24703286&gt;
+        &lt;rdar://problem/30290270&gt;
+
+        This patch adds test infrastructure to allow testing 
+        of the various rules in place for data records removal.
+
+        Reviewed by Andy Estes.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+        (WTR::InjectedBundle::didReceiveMessageToPage):
+            Callback mechanism to tell pages that a website data store
+            scan has happened.
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setStatisticsPrevalentResource):
+        (WTR::TestRunner::isStatisticsPrevalentResource):
+        (WTR::TestRunner::setStatisticsHasHadUserInteraction):
+        (WTR::TestRunner::isStatisticsHasHadUserInteraction):
+        (WTR::TestRunner::setStatisticsTimeToLiveUserInteraction):
+        (WTR::TestRunner::installStatisticsDidModifyDataRecordsCallback):
+        (WTR::TestRunner::statisticsDidModifyDataRecordsCallback):
+        (WTR::TestRunner::statisticsFireDataModificationHandler):
+        (WTR::TestRunner::setStatisticsNotifyPagesWhenDataRecordsWereScanned):
+        (WTR::TestRunner::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval):
+        (WTR::TestRunner::setStatisticsMinimumTimeBetweeenDataRecordsRemoval):
+        (WTR::TestRunner::statisticsResetToConsistentState):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::setStatisticsPrevalentResource):
+        (WTR::TestController::isStatisticsPrevalentResource):
+        (WTR::TestController::setStatisticsHasHadUserInteraction):
+        (WTR::TestController::isStatisticsHasHadUserInteraction):
+        (WTR::TestController::setStatisticsTimeToLiveUserInteraction):
+        (WTR::TestController::statisticsFireDataModificationHandler):
+        (WTR::TestController::setStatisticsNotifyPagesWhenDataRecordsWereScanned):
+        (WTR::TestController::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval):
+        (WTR::TestController::setStatisticsMinimumTimeBetweeenDataRecordsRemoval):
+        (WTR::TestController::statisticsResetToConsistentState):
+        * WebKitTestRunner/TestController.h:
+            These are all configuration and test functions.
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
</ins><span class="cx"> 2017-02-10  Carlos Alberto Lopez Perez  &lt;clopez@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION(r182916) run-perf-tests never timeouts
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleBindingsTestRunneridl"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -246,4 +246,17 @@
</span><span class="cx">     void setMockGamepadButtonValue(unsigned long index, unsigned long buttonIndex, double value);
</span><span class="cx">     void connectMockGamepad(unsigned long index);
</span><span class="cx">     void disconnectMockGamepad(unsigned long index);
</span><ins>+
+    // Resource Load Statistics
+    void installStatisticsDidModifyDataRecordsCallback(object callback);
+    void setStatisticsPrevalentResource(DOMString hostName, boolean value);
+    boolean isStatisticsPrevalentResource(DOMString hostName);
+    void setStatisticsHasHadUserInteraction(DOMString hostName, boolean value);
+    boolean isStatisticsHasHadUserInteraction(DOMString hostName);
+    void setStatisticsTimeToLiveUserInteraction(double seconds);
+    void statisticsFireDataModificationHandler();
+    void setStatisticsNotifyPagesWhenDataRecordsWereScanned(boolean value);
+    void setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(boolean value);
+    void setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double seconds);
+    void statisticsResetToConsistentState();
</ins><span class="cx"> };
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleInjectedBundlecpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -266,6 +266,11 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (WKStringIsEqualToUTF8CString(messageName, &quot;WebsiteDataDeletionForTopPrivatelyOwnedDomainsFinished&quot;)) {
+        m_testRunner-&gt;statisticsDidModifyDataRecordsCallback();
+        return;
+    }
+
</ins><span class="cx">     WKRetainPtr&lt;WKStringRef&gt; errorMessageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;Error&quot;));
</span><span class="cx">     WKRetainPtr&lt;WKStringRef&gt; errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString(&quot;Unknown&quot;));
</span><span class="cx">     WKBundlePagePostMessage(page, errorMessageName.get(), errorMessageBody.get());
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleTestRunnercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &quot;StringFunctions.h&quot;
</span><span class="cx"> #include &quot;TestController.h&quot;
</span><span class="cx"> #include &lt;JavaScriptCore/JSCTestRunnerUtils.h&gt;
</span><ins>+#include &lt;WebCore/ResourceLoadObserver.h&gt;
</ins><span class="cx"> #include &lt;WebKit/WKBundle.h&gt;
</span><span class="cx"> #include &lt;WebKit/WKBundleBackForwardList.h&gt;
</span><span class="cx"> #include &lt;WebKit/WKBundleFrame.h&gt;
</span><span class="lines">@@ -635,6 +636,7 @@
</span><span class="cx">     WillEndSwipeCallbackID,
</span><span class="cx">     DidEndSwipeCallbackID,
</span><span class="cx">     DidRemoveSwipeSnapshotCallbackID,
</span><ins>+    StatisticsDidModifyDataRecordsCallbackID,
</ins><span class="cx">     FirstUIScriptCallbackID = 100
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -1152,6 +1154,128 @@
</span><span class="cx">     callTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestRunner::setStatisticsPrevalentResource(JSStringRef hostName, bool value)
+{
+    Vector&lt;WKRetainPtr&lt;WKStringRef&gt;&gt; keys;
+    Vector&lt;WKRetainPtr&lt;WKTypeRef&gt;&gt; values;
+
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString(&quot;HostName&quot;) });
+    values.append({ AdoptWK, WKStringCreateWithJSString(hostName) });
+    
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString(&quot;Value&quot;) });
+    values.append({ AdoptWK, WKBooleanCreate(value) });
+    
+    Vector&lt;WKStringRef&gt; rawKeys;
+    Vector&lt;WKTypeRef&gt; rawValues;
+    rawKeys.resize(keys.size());
+    rawValues.resize(values.size());
+    
+    for (size_t i = 0; i &lt; keys.size(); ++i) {
+        rawKeys[i] = keys[i].get();
+        rawValues[i] = values[i].get();
+    }
+    
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;SetStatisticsPrevalentResource&quot;));
+    WKRetainPtr&lt;WKDictionaryRef&gt; messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+bool TestRunner::isStatisticsPrevalentResource(JSStringRef hostName)
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;IsStatisticsPrevalentResource&quot;));
+    WKRetainPtr&lt;WKStringRef&gt; messageBody(AdoptWK, WKStringCreateWithJSString(hostName));
+    WKTypeRef returnData = 0;
+    WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()-&gt;page(), messageName.get(), messageBody.get(), &amp;returnData);
+    return WKBooleanGetValue(static_cast&lt;WKBooleanRef&gt;(returnData));
+}
+
+void TestRunner::setStatisticsHasHadUserInteraction(JSStringRef hostName, bool value)
+{
+    Vector&lt;WKRetainPtr&lt;WKStringRef&gt;&gt; keys;
+    Vector&lt;WKRetainPtr&lt;WKTypeRef&gt;&gt; values;
+    
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString(&quot;HostName&quot;) });
+    values.append({ AdoptWK, WKStringCreateWithJSString(hostName) });
+    
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString(&quot;Value&quot;) });
+    values.append({ AdoptWK, WKBooleanCreate(value) });
+    
+    Vector&lt;WKStringRef&gt; rawKeys;
+    Vector&lt;WKTypeRef&gt; rawValues;
+    rawKeys.resize(keys.size());
+    rawValues.resize(values.size());
+    
+    for (size_t i = 0; i &lt; keys.size(); ++i) {
+        rawKeys[i] = keys[i].get();
+        rawValues[i] = values[i].get();
+    }
+    
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;SetStatisticsHasHadUserInteraction&quot;));
+    WKRetainPtr&lt;WKDictionaryRef&gt; messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+    
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+bool TestRunner::isStatisticsHasHadUserInteraction(JSStringRef hostName)
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;IsStatisticsHasHadUserInteraction&quot;));
+    WKRetainPtr&lt;WKStringRef&gt; messageBody(AdoptWK, WKStringCreateWithJSString(hostName));
+    WKTypeRef returnData = 0;
+    WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()-&gt;page(), messageName.get(), messageBody.get(), &amp;returnData);
+    return WKBooleanGetValue(static_cast&lt;WKBooleanRef&gt;(returnData));
+}
+
+void TestRunner::setStatisticsTimeToLiveUserInteraction(double seconds)
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;SetStatisticsTimeToLiveUserInteraction&quot;));
+    WKRetainPtr&lt;WKDoubleRef&gt; messageBody(AdoptWK, WKDoubleCreate(seconds));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::installStatisticsDidModifyDataRecordsCallback(JSValueRef callback)
+{
+    cacheTestRunnerCallback(StatisticsDidModifyDataRecordsCallbackID, callback);
+}
+
+void TestRunner::statisticsDidModifyDataRecordsCallback()
+{
+    callTestRunnerCallback(StatisticsDidModifyDataRecordsCallbackID);
+}
+
+void TestRunner::statisticsFireDataModificationHandler()
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;StatisticsFireDataModificationHandler&quot;));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), 0, nullptr);
+}
+
+void TestRunner::setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool value)
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;StatisticsNotifyPagesWhenDataRecordsWereScanned&quot;));
+    WKRetainPtr&lt;WKBooleanRef&gt; messageBody(AdoptWK, WKBooleanCreate(value));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool value)
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval&quot;));
+    WKRetainPtr&lt;WKBooleanRef&gt; messageBody(AdoptWK, WKBooleanCreate(value));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
+void TestRunner::setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double seconds)
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;SetStatisticsMinimumTimeBetweeenDataRecordsRemoval&quot;));
+    WKRetainPtr&lt;WKDoubleRef&gt; messageBody(AdoptWK, WKDoubleCreate(seconds));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+    
+void TestRunner::statisticsResetToConsistentState()
+{
+    WKRetainPtr&lt;WKStringRef&gt; messageName(AdoptWK, WKStringCreateWithUTF8CString(&quot;StatisticsResetToConsistentState&quot;));
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), 0, nullptr);
+}
+
</ins><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx"> void TestRunner::connectMockGamepad(unsigned index)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleTestRunnerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -345,6 +345,20 @@
</span><span class="cx">     void setMockGamepadDetails(unsigned index, JSStringRef gamepadID, unsigned axisCount, unsigned buttonCount);
</span><span class="cx">     void setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value);
</span><span class="cx">     void setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value);
</span><ins>+    
+    // Resource Load Statistics
+    void installStatisticsDidModifyDataRecordsCallback(JSValueRef callback);
+    void statisticsDidModifyDataRecordsCallback();
+    void statisticsFireDataModificationHandler();
+    void setStatisticsPrevalentResource(JSStringRef hostName, bool value);
+    bool isStatisticsPrevalentResource(JSStringRef hostName);
+    void setStatisticsHasHadUserInteraction(JSStringRef hostName, bool value);
+    bool isStatisticsHasHadUserInteraction(JSStringRef hostName);
+    void setStatisticsTimeToLiveUserInteraction(double seconds);
+    void setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool);
+    void setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool);
+    void setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double);
+    void statisticsResetToConsistentState();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     TestRunner();
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestController.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestController.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Tools/WebKitTestRunner/TestController.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2014-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 2014-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -55,6 +55,7 @@
</span><span class="cx"> #include &lt;WebKit/WKPluginInformation.h&gt;
</span><span class="cx"> #include &lt;WebKit/WKPreferencesRefPrivate.h&gt;
</span><span class="cx"> #include &lt;WebKit/WKProtectionSpace.h&gt;
</span><ins>+#include &lt;WebKit/WKResourceLoadStatisticsManager.h&gt;
</ins><span class="cx"> #include &lt;WebKit/WKRetainPtr.h&gt;
</span><span class="cx"> #include &lt;WebKit/WKSecurityOriginRef.h&gt;
</span><span class="cx"> #include &lt;WebKit/WKTextChecker.h&gt;
</span><span class="lines">@@ -2207,6 +2208,55 @@
</span><span class="cx">     WKPageSetIgnoresViewportScaleLimits(m_mainWebView-&gt;page(), ignoresViewportScaleLimits);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void TestController::setStatisticsPrevalentResource(WKStringRef hostName, bool value)
+{
+    WKResourceLoadStatisticsManagerSetPrevalentResource(hostName, value);
+}
+
+bool TestController::isStatisticsPrevalentResource(WKStringRef hostName)
+{
+    return WKResourceLoadStatisticsManagerIsPrevalentResource(hostName);
+}
+
+void TestController::setStatisticsHasHadUserInteraction(WKStringRef hostName, bool value)
+{
+    WKResourceLoadStatisticsManagerSetHasHadUserInteraction(hostName, value);
+}
+
+bool TestController::isStatisticsHasHadUserInteraction(WKStringRef hostName)
+{
+    return WKResourceLoadStatisticsManagerIsHasHadUserInteraction(hostName);
+}
+
+void TestController::setStatisticsTimeToLiveUserInteraction(double seconds)
+{
+    WKResourceLoadStatisticsManagerSetTimeToLiveUserInteraction(seconds);
+}
+
+void TestController::statisticsFireDataModificationHandler()
+{
+    WKResourceLoadStatisticsManagerFireDataModificationHandler();
+}
+    
+void TestController::setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool value)
+{
+    WKResourceLoadStatisticsManagerSetNotifyPagesWhenDataRecordsWereScanned(value);
+}
+    
+void TestController::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool value)
+{
+    WKResourceLoadStatisticsManagerSetShouldClassifyResourcesBeforeDataRecordsRemoval(value);
+}
+
+void TestController::setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double seconds)
+{
+    WKResourceLoadStatisticsManagerSetMinimumTimeBetweeenDataRecordsRemoval(seconds);
+}
+void TestController::statisticsResetToConsistentState()
+{
+    WKResourceLoadStatisticsManagerResetToConsistentState();
+}
+    
</ins><span class="cx"> #if !PLATFORM(COCOA)
</span><span class="cx"> void TestController::platformWillRunTest(const TestInvocation&amp;)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestController.h (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestController.h        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Tools/WebKitTestRunner/TestController.h        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 2015-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -148,6 +148,17 @@
</span><span class="cx"> 
</span><span class="cx">     void setShouldDownloadUndisplayableMIMETypes(bool value) { m_shouldDownloadUndisplayableMIMETypes = value; }
</span><span class="cx"> 
</span><ins>+    void setStatisticsPrevalentResource(WKStringRef hostName, bool value);
+    bool isStatisticsPrevalentResource(WKStringRef hostName);
+    void setStatisticsHasHadUserInteraction(WKStringRef hostName, bool value);
+    bool isStatisticsHasHadUserInteraction(WKStringRef hostName);
+    void setStatisticsTimeToLiveUserInteraction(double seconds);
+    void statisticsFireDataModificationHandler();
+    void setStatisticsNotifyPagesWhenDataRecordsWereScanned(bool);
+    void setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool);
+    void setStatisticsMinimumTimeBetweeenDataRecordsRemoval(double);
+    void statisticsResetToConsistentState();
+
</ins><span class="cx"> private:
</span><span class="cx">     WKRetainPtr&lt;WKPageConfigurationRef&gt; generatePageConfiguration(WKContextConfigurationRef);
</span><span class="cx">     WKRetainPtr&lt;WKContextConfigurationRef&gt; generateContextConfiguration() const;
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestInvocationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (212182 => 212183)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp        2017-02-11 06:01:20 UTC (rev 212182)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp        2017-02-11 07:34:40 UTC (rev 212183)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2012 Intel Corporation. All rights reserved.
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -886,7 +886,90 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (WKStringIsEqualToUTF8CString(messageName, &quot;SetStatisticsPrevalentResource&quot;)) {
+        ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
</ins><span class="cx"> 
</span><ins>+        WKDictionaryRef messageBodyDictionary = static_cast&lt;WKDictionaryRef&gt;(messageBody);
+        WKRetainPtr&lt;WKStringRef&gt; hostNameKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;HostName&quot;));
+        WKRetainPtr&lt;WKStringRef&gt; valueKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;Value&quot;));
+
+        WKStringRef hostName = static_cast&lt;WKStringRef&gt;(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
+        WKBooleanRef value = static_cast&lt;WKBooleanRef&gt;(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
+
+        TestController::singleton().setStatisticsPrevalentResource(hostName, WKBooleanGetValue(value));
+        return nullptr;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;IsStatisticsPrevalentResource&quot;)) {
+        ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+
+        WKStringRef hostName = static_cast&lt;WKStringRef&gt;(messageBody);
+        bool isPrevalent = TestController::singleton().isStatisticsPrevalentResource(hostName);
+        WKRetainPtr&lt;WKTypeRef&gt; result(AdoptWK, WKBooleanCreate(isPrevalent));
+        return result;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;SetStatisticsHasHadUserInteraction&quot;)) {
+        ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+        
+        WKDictionaryRef messageBodyDictionary = static_cast&lt;WKDictionaryRef&gt;(messageBody);
+        WKRetainPtr&lt;WKStringRef&gt; hostNameKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;HostName&quot;));
+        WKRetainPtr&lt;WKStringRef&gt; valueKey(AdoptWK, WKStringCreateWithUTF8CString(&quot;Value&quot;));
+        
+        WKStringRef hostName = static_cast&lt;WKStringRef&gt;(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
+        WKBooleanRef value = static_cast&lt;WKBooleanRef&gt;(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
+        
+        TestController::singleton().setStatisticsHasHadUserInteraction(hostName, WKBooleanGetValue(value));
+        return nullptr;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;IsStatisticsHasHadUserInteraction&quot;)) {
+        ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+        
+        WKStringRef hostName = static_cast&lt;WKStringRef&gt;(messageBody);
+        bool hasHadUserInteraction = TestController::singleton().isStatisticsHasHadUserInteraction(hostName);
+        WKRetainPtr&lt;WKTypeRef&gt; result(AdoptWK, WKBooleanCreate(hasHadUserInteraction));
+        return result;
+    }
+    
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;SetStatisticsTimeToLiveUserInteraction&quot;)) {
+        ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
+        WKDoubleRef seconds = static_cast&lt;WKDoubleRef&gt;(messageBody);
+        TestController::singleton().setStatisticsTimeToLiveUserInteraction(WKDoubleGetValue(seconds));
+        return nullptr;
+    }
+    
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;StatisticsFireDataModificationHandler&quot;)) {
+        TestController::singleton().statisticsFireDataModificationHandler();
+        return nullptr;
+    }
+    
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;StatisticsNotifyPagesWhenDataRecordsWereScanned&quot;)) {
+        ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+        WKBooleanRef value = static_cast&lt;WKBooleanRef&gt;(messageBody);
+        TestController::singleton().setStatisticsNotifyPagesWhenDataRecordsWereScanned(WKBooleanGetValue(value));
+        return nullptr;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval&quot;)) {
+        ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+        WKBooleanRef value = static_cast&lt;WKBooleanRef&gt;(messageBody);
+        TestController::singleton().setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(WKBooleanGetValue(value));
+        return nullptr;
+    }
+
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;SetStatisticsMinimumTimeBetweeenDataRecordsRemoval&quot;)) {
+        ASSERT(WKGetTypeID(messageBody) == WKDoubleGetTypeID());
+        WKDoubleRef seconds = static_cast&lt;WKDoubleRef&gt;(messageBody);
+        TestController::singleton().setStatisticsMinimumTimeBetweeenDataRecordsRemoval(WKDoubleGetValue(seconds));
+        return nullptr;
+    }
+    
+    if (WKStringIsEqualToUTF8CString(messageName, &quot;StatisticsResetToConsistentState&quot;)) {
+        TestController::singleton().statisticsResetToConsistentState();
+        return nullptr;
+    }
+
</ins><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>