Changeset 250866 in webkit


Ignore:
Timestamp:
Oct 8, 2019 3:13:39 PM (5 years ago)
Author:
commit-queue@webkit.org
Message:

Implement Telemetry and Dumping Routines for SQLite backend (195088)
https://bugs.webkit.org/show_bug.cgi?id=195088
<rdar://problem/54213407>

Patch by Kate Cheney <Kate Cheney> on 2019-10-08
Reviewed by John Wilander.

Source/WebKit:

Implemented database telemetry calculating for ITP. Mimicked
ResourceLoadStatisticsMemoryStore telemetry logging behavior using
SQLite Queries as opposed to vector sorting/manipulation. Once fully
integrated, this will simplify analysis of ITP data by transitioning
ITP data storage from a plist to a SQLite database.

  • NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:

(WebKit::ResourceLoadStatisticsDatabaseStore::ResourceLoadStatisticsDatabaseStore):
Added SQL queries to be initialized in the constructor. These queries
are needed to mimic the telemetry calculations done in
ResourceLoadStatisticsMemoryStore.

(WebKit::resetStatement):
To reduce code duplication, this function holds common code to reset
a SQL query.

(WebKit::ResourceLoadStatisticsDatabaseStore::prepareStatements):
Added SQL queries needed for telemetry calculations to be prepared.

(WebKit::joinSubStatisticsForSorting):
This function returns the query string for sorting resources that is
shared by many queries.

(WebKit::ResourceLoadStatisticsDatabaseStore::getMedianOfPrevalentResourcesWithUserInteraction const):
Implemented a function to take the median days since user interaction
from all prevalent resources in the database with user interaction
(sorted by max count of subframes, subresources and unique redirects under
the top frame domain).

(WebKit::ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResources const):
Executes a SQL query to get the number of prevalent resources to log as
telemetry.

(WebKit::ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResourcesWithUI const):
Executes a SQL query to get the number of prevalent resources with user
interaction to log as telemetry.

(WebKit::ResourceLoadStatisticsDatabaseStore::getTopPrevelentResourceDaysSinceUI const):
Prepares and executes a SQL query to get the days since user
interaction from the top prevalent resource to be recorded as
telemetry data.

(WebKit::ResourceLoadStatisticsDatabaseStore::getMedianStatisticOfPrevalentResourceWithoutUserInteraction const):
Implemented a function which takes a statistic and returns the value
of that statistic for the median prevalent resource without user
interaction to be recorded as telemetry data.

(WebKit::ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResourcesInTopResources const):
Returns the count of prevalent resources in the top x resources
sorted by sum of substatistics again to be logged as telemetry.

(WebKit::ResourceLoadStatisticsDatabaseStore::calculateTelemetryData const):
Function which executes all functions which populate the struct with
telemetry data. This struct will then be passed to
WebResourceLoadStatisticsTelemetry to be logged.

(WebKit::ResourceLoadStatisticsDatabaseStore::calculateAndSubmitTelemetry const):
Initializes the telemetry struct and calls the function to populate
it, then passes it to the WebResourceLoadStatisticsTelemetry object
to be recorded.

  • NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:

Describe PrevalentResourceDatabaseTelemetry Struct to be passed and
logged as telemetry data.

  • NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.cpp:

(WebKit::databaseSubmitTopLists):
Logging telemetry data by looping through 2D array of statistics for
the top 1, 3, 10, 50, and 100 prevalent resources sorted by the sum
of substatistics under the top frame domain. This matches the logging
already done in ResourceLoadStatisticsMemoryStore.

(WebKit::WebResourceLoadStatisticsTelemetry::submitTelemetry):
Submits data to the webPageProxy logs and plists.

  • NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.h:

Added new submitTopList function to accomodate database telemetry
logging.

  • NetworkProcess/NetworkSession.cpp:

(WebKit::NetworkSession::notifyPageStatisticsTelemetryFinished):

  • NetworkProcess/NetworkSession.h:
  • UIProcess/Network/NetworkProcessProxy.cpp:

(WebKit::NetworkProcessProxy::notifyResourceLoadStatisticsTelemetryFinished):

  • UIProcess/Network/NetworkProcessProxy.h:
  • UIProcess/Network/NetworkProcessProxy.messages.in:

Updated the current testing for telemetry which only tested 3
statistics. With this patch it now tests 10 statistics.

Tools:

Updated the current testing for telemetry which only tested 3
statistics. With this patch it now tests 10 statistics.

  • WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:

(WTR::InjectedBundle::didReceiveMessageToPage):

  • WebKitTestRunner/InjectedBundle/TestRunner.cpp:

(WTR::TestRunner::statisticsDidRunTelemetryCallback):

  • WebKitTestRunner/InjectedBundle/TestRunner.h:

LayoutTests:

Updated the current testing for telemetry which only tested 3
statistics. With this patch it now tests 10 statistics.

  • http/tests/resourceLoadStatistics/telemetry-generation-advanced-functionality-database-expected.txt: Added.
  • http/tests/resourceLoadStatistics/telemetry-generation-advanced-functionality-database.html: Added.
  • http/tests/resourceLoadStatistics/telemetry-generation-basic-functionality-database-expected.txt: Added.
  • http/tests/resourceLoadStatistics/telemetry-generation-basic-functionality-database.html: Added.
Location:
trunk
Files:
4 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r250862 r250866  
     12019-10-08  Kate Cheney  <katherine_cheney@apple.com>
     2
     3        Implement Telemetry and Dumping Routines for SQLite backend (195088)
     4        https://bugs.webkit.org/show_bug.cgi?id=195088
     5        <rdar://problem/54213407>
     6
     7        Reviewed by John Wilander.
     8
     9        Updated the current testing for telemetry which only tested 3
     10        statistics. With this patch it now tests 10 statistics.
     11        * http/tests/resourceLoadStatistics/telemetry-generation-advanced-functionality-database-expected.txt: Added.
     12        * http/tests/resourceLoadStatistics/telemetry-generation-advanced-functionality-database.html: Added.
     13        * http/tests/resourceLoadStatistics/telemetry-generation-basic-functionality-database-expected.txt: Added.
     14        * http/tests/resourceLoadStatistics/telemetry-generation-basic-functionality-database.html: Added.
     15
    1162019-10-08  Antti Koivisto  <antti@apple.com>
    217
  • trunk/Source/WebKit/ChangeLog

    r250857 r250866  
     12019-10-08  Kate Cheney  <katherine_cheney@apple.com>
     2
     3        Implement Telemetry and Dumping Routines for SQLite backend (195088)
     4        https://bugs.webkit.org/show_bug.cgi?id=195088
     5        <rdar://problem/54213407>
     6
     7        Reviewed by John Wilander.
     8
     9        Implemented database telemetry calculating for ITP. Mimicked
     10        ResourceLoadStatisticsMemoryStore telemetry logging behavior using
     11        SQLite Queries as opposed to vector sorting/manipulation. Once fully
     12        integrated, this will simplify analysis of ITP data by transitioning
     13        ITP data storage from a plist to a SQLite database.
     14
     15        * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
     16        (WebKit::ResourceLoadStatisticsDatabaseStore::ResourceLoadStatisticsDatabaseStore):
     17        Added SQL queries to be initialized in the constructor. These queries
     18        are needed to mimic the telemetry calculations done in
     19        ResourceLoadStatisticsMemoryStore.
     20       
     21        (WebKit::resetStatement):
     22        To reduce code duplication, this function holds common code to reset
     23        a SQL query.
     24
     25        (WebKit::ResourceLoadStatisticsDatabaseStore::prepareStatements):
     26        Added SQL queries needed for telemetry calculations to be prepared.
     27       
     28        (WebKit::joinSubStatisticsForSorting):
     29        This function returns the query string for sorting resources that is
     30        shared by many queries.
     31
     32        (WebKit::ResourceLoadStatisticsDatabaseStore::getMedianOfPrevalentResourcesWithUserInteraction const):
     33        Implemented a function to take the median days since user interaction
     34        from all prevalent resources in the database with user interaction
     35        (sorted by max count of subframes, subresources and unique redirects under
     36        the top frame domain).
     37
     38        (WebKit::ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResources const):
     39        Executes a SQL query to get the number of prevalent resources to log as
     40        telemetry.
     41
     42        (WebKit::ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResourcesWithUI const):
     43        Executes a SQL query to get the number of prevalent resources with user
     44        interaction to log as telemetry.
     45
     46        (WebKit::ResourceLoadStatisticsDatabaseStore::getTopPrevelentResourceDaysSinceUI const):
     47        Prepares and executes a SQL query to get the days since user
     48        interaction from the top prevalent resource to be recorded as
     49        telemetry data.
     50
     51        (WebKit::ResourceLoadStatisticsDatabaseStore::getMedianStatisticOfPrevalentResourceWithoutUserInteraction const):
     52        Implemented a function which takes a statistic and returns the value
     53        of that statistic for the median prevalent resource without user
     54        interaction to be recorded as telemetry data.
     55
     56        (WebKit::ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResourcesInTopResources const):
     57        Returns the count of prevalent resources in the top x resources
     58        sorted by sum of substatistics again to be logged as telemetry.
     59
     60        (WebKit::ResourceLoadStatisticsDatabaseStore::calculateTelemetryData const):
     61        Function which executes all functions which populate the struct with
     62        telemetry data. This struct will then be passed to
     63        WebResourceLoadStatisticsTelemetry to be logged.
     64
     65        (WebKit::ResourceLoadStatisticsDatabaseStore::calculateAndSubmitTelemetry const):
     66        Initializes the telemetry struct and calls the function to populate
     67        it, then passes it to the WebResourceLoadStatisticsTelemetry object
     68        to be recorded.
     69
     70        * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h:
     71        Describe PrevalentResourceDatabaseTelemetry Struct to be passed and
     72        logged as telemetry data.
     73
     74        * NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.cpp:
     75        (WebKit::databaseSubmitTopLists):
     76        Logging telemetry data by looping through 2D array of statistics for
     77        the top 1, 3, 10, 50, and 100 prevalent resources sorted by the sum
     78        of substatistics under the top frame domain. This matches the logging
     79        already done in ResourceLoadStatisticsMemoryStore.
     80
     81        (WebKit::WebResourceLoadStatisticsTelemetry::submitTelemetry):
     82        Submits data to the webPageProxy logs and plists.
     83
     84        * NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.h:
     85        Added new submitTopList function to accomodate database telemetry
     86        logging.
     87       
     88        * NetworkProcess/NetworkSession.cpp:
     89        (WebKit::NetworkSession::notifyPageStatisticsTelemetryFinished):
     90        * NetworkProcess/NetworkSession.h:
     91        * UIProcess/Network/NetworkProcessProxy.cpp:
     92        (WebKit::NetworkProcessProxy::notifyResourceLoadStatisticsTelemetryFinished):
     93        * UIProcess/Network/NetworkProcessProxy.h:
     94        * UIProcess/Network/NetworkProcessProxy.messages.in:
     95        Updated the current testing for telemetry which only tested 3
     96        statistics. With this patch it now tests 10 statistics.
     97
    1982019-10-08  Adrian Perez de Castro  <aperez@igalia.com>
    299
  • trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp

    r250804 r250866  
    6868constexpr auto countSubresourceUnderTopFrameQuery = "SELECT COUNT(*) FROM SubresourceUnderTopFrameDomains WHERE subresourceDomainID = ? AND topFrameDomainID = ?;"_s;
    6969constexpr auto countSubresourceUniqueRedirectsToQuery = "SELECT COUNT(*) FROM SubresourceUniqueRedirectsTo WHERE subresourceDomainID = ? AND toDomainID = ?;"_s;
     70constexpr auto countPrevalentResourcesQuery = "SELECT COUNT(DISTINCT registrableDomain) FROM ObservedDomains WHERE isPrevalent = 1;"_s;
     71constexpr auto countPrevalentResourcesWithUserInteractionQuery = "SELECT COUNT(DISTINCT registrableDomain) FROM ObservedDomains WHERE isPrevalent = 1 AND hadUserInteraction = 1;"_s;
     72
     73constexpr auto countPrevalentResourcesWithoutUserInteractionQuery = "SELECT COUNT(DISTINCT registrableDomain) FROM ObservedDomains WHERE isPrevalent = 1 AND hadUserInteraction = 0;"_s;
    7074
    7175// INSERT Queries
     
    187191constexpr auto createUniqueIndexSubresourceUniqueRedirectsFrom = "CREATE UNIQUE INDEX IF NOT EXISTS SubresourceUniqueRedirectsFrom_subresourceDomainID_fromDomainID on SubresourceUnderTopFrameDomains ( subresourceDomainID, fromDomainID );"_s;
    188192
    189    
     193const unsigned minimumPrevalentResourcesForTelemetry = 3;
     194
    190195ResourceLoadStatisticsDatabaseStore::ResourceLoadStatisticsDatabaseStore(WebResourceLoadStatisticsStore& store, WorkQueue& workQueue, ShouldIncludeLocalhost shouldIncludeLocalhost, const String& storageDirectoryPath, PAL::SessionID sessionID)
    191196    : ResourceLoadStatisticsStore(store, workQueue, shouldIncludeLocalhost)
     
    211216    , m_isGrandfatheredStatement(m_database, isGrandfatheredQuery)
    212217    , m_findExpiredUserInteractionStatement(m_database, findExpiredUserInteractionQuery)
     218    , m_countPrevalentResourcesStatement(m_database, countPrevalentResourcesQuery)
     219    , m_countPrevalentResourcesWithUserInteractionStatement(m_database, countPrevalentResourcesWithUserInteractionQuery)
     220    , m_countPrevalentResourcesWithoutUserInteractionStatement(m_database, countPrevalentResourcesWithoutUserInteractionQuery)
    213221    , m_sessionID(sessionID)
    214222{
     
    245253            weakThis->calculateAndSubmitTelemetry();
    246254    });
     255}
     256
     257static void resetStatement(SQLiteStatement& statement)
     258{
     259    int resetResult = statement.reset();
     260    ASSERT_UNUSED(resetResult, resetResult == SQLITE_OK);
    247261}
    248262
     
    360374        || m_isGrandfatheredStatement.prepare() != SQLITE_OK
    361375        || m_findExpiredUserInteractionStatement.prepare() != SQLITE_OK
    362         || m_topFrameLinkDecorationsFromExists.prepare() != SQLITE_OK) {
     376        || m_topFrameLinkDecorationsFromExists.prepare() != SQLITE_OK
     377        || m_countPrevalentResourcesStatement.prepare() != SQLITE_OK
     378        || m_countPrevalentResourcesWithUserInteractionStatement.prepare() != SQLITE_OK
     379        || m_countPrevalentResourcesWithoutUserInteractionStatement.prepare() != SQLITE_OK
     380        ) {
    363381        RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::prepareStatements failed to prepare, error message: %{public}s", this, m_database.lastErrorMsg());
    364382        ASSERT_NOT_REACHED();
     
    603621}
    604622
     623static const StringView joinSubStatisticsForSorting()
     624{
     625    return R"query(
     626        domainID,
     627        (cnt1 + cnt2 + cnt3) as sum
     628        FROM (
     629        SELECT
     630            domainID,
     631            COUNT(DISTINCT f.topFrameDomainID) as cnt1,
     632            COUNT(DISTINCT r.topFrameDomainID) as cnt2,
     633            COUNT(DISTINCT toDomainID) as cnt3
     634        FROM
     635        ObservedDomains o
     636        LEFT JOIN SubframeUnderTopFrameDomains f ON o.domainID = f.subFrameDomainID
     637        LEFT JOIN SubresourceUnderTopFrameDomains r ON o.domainID = r.subresourceDomainID
     638        LEFT JOIN SubresourceUniqueRedirectsTo u ON o.domainID = u.subresourceDomainID
     639        WHERE isPrevalent = 1
     640        and hadUserInteraction LIKE ?
     641        GROUP BY domainID) ORDER BY sum DESC
     642        )query";
     643}
     644
     645static SQLiteStatement makeMedianWithUIQuery(SQLiteDatabase& database)
     646{
     647    return SQLiteStatement(database, makeString("SELECT mostRecentUserInteractionTime FROM ObservedDomains INNER JOIN (SELECT ", joinSubStatisticsForSorting(), ") as q ON ObservedDomains.domainID = q.domainID LIMIT 1 OFFSET ?"));
     648}
     649
     650static std::pair<StringView, StringView> buildQueryStartAndEnd(PrevalentResourceDatabaseTelemetry::Statistic statistic)
     651{
     652    switch (statistic) {
     653    case PrevalentResourceDatabaseTelemetry::Statistic::MedianSubFrameWithoutUI:
     654        return std::make_pair("SELECT cnt1 FROM ObservedDomains o INNER JOIN(SELECT cnt1, ", ") as q ON o.domainID = q.domainID LIMIT 1 OFFSET ?");
     655    case PrevalentResourceDatabaseTelemetry::Statistic::MedianSubResourceWithoutUI:
     656        return std::make_pair("SELECT cnt2 FROM ObservedDomains o INNER JOIN(SELECT cnt2, ", ") as q ON o.domainID = q.domainID LIMIT 1 OFFSET ?");
     657    case PrevalentResourceDatabaseTelemetry::Statistic::MedianUniqueRedirectsWithoutUI:
     658        return std::make_pair("SELECT cnt3 FROM ObservedDomains o INNER JOIN(SELECT cnt3, ", ") as q ON o.domainID = q.domainID LIMIT 1 OFFSET ?");
     659    case PrevalentResourceDatabaseTelemetry::Statistic::MedianDataRecordsRemovedWithoutUI:
     660        return std::make_pair("SELECT dataRecordsRemoved FROM (SELECT * FROM ObservedDomains o INNER JOIN(SELECT ", ") as q ON o.domainID = q.domainID) LIMIT 1 OFFSET ?");
     661    case PrevalentResourceDatabaseTelemetry::Statistic::MedianTimesAccessedDueToUserInteractionWithoutUI:
     662        return std::make_pair("SELECT timesAccessedAsFirstPartyDueToUserInteraction FROM (SELECT * FROM ObservedDomains o INNER JOIN(SELECT ", ") as q ON o.domainID = q.domainID) LIMIT 1 OFFSET ?");
     663    case PrevalentResourceDatabaseTelemetry::Statistic::MedianTimesAccessedDueToStorageAccessAPIWithoutUI:
     664        return std::make_pair("SELECT timesAccessedAsFirstPartyDueToStorageAccessAPI FROM (SELECT * FROM ObservedDomains o INNER JOIN(SELECT ", ") as q ON o.domainID = q.domainID) LIMIT 1 OFFSET ?");
     665    case PrevalentResourceDatabaseTelemetry::Statistic::NumberOfPrevalentResourcesWithUI:
     666        LOG_ERROR("ResourceLoadStatisticsDatabaseStore::makeMedianWithoutUIQuery was called for an incorrect statistic, undetermined query behavior will result.");
     667        RELEASE_ASSERT_NOT_REACHED();
     668    }
     669}
     670
     671static SQLiteStatement makeMedianWithoutUIQuery(SQLiteDatabase& database, PrevalentResourceDatabaseTelemetry::Statistic statistic)
     672{
     673    auto[queryStart, queryEnd] = buildQueryStartAndEnd(statistic);
     674
     675    return SQLiteStatement(database, makeString(queryStart, joinSubStatisticsForSorting(), queryEnd));
     676}
     677
     678static unsigned getMedianOfPrevalentResourcesWithUserInteraction(SQLiteDatabase& database, unsigned prevalentResourcesWithUserInteractionCount)
     679{
     680    SQLiteStatement medianDaysSinceUIStatement = makeMedianWithUIQuery(database);
     681
     682    // Prepare
     683    if (medianDaysSinceUIStatement.prepare() != SQLITE_OK) {
     684        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::getMedianOfPrevalentResourcesWithUserInteraction, error message: %{public}s", database.lastErrorMsg());
     685        ASSERT_NOT_REACHED();
     686        return 0;
     687    }
     688
     689    // Bind
     690    if (medianDaysSinceUIStatement.bindInt(1, 1) != SQLITE_OK || medianDaysSinceUIStatement.bindInt(2, (prevalentResourcesWithUserInteractionCount / 2) != SQLITE_OK)) {
     691        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::getMedianOfPrevalentResourcesWithUserInteraction, error message: %{public}s", database.lastErrorMsg());
     692        ASSERT_NOT_REACHED();
     693        return 0;
     694    }
     695
     696    // Step
     697    if (medianDaysSinceUIStatement.step() != SQLITE_ROW) {
     698        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::getMedianOfPrevalentResourcesWithUserInteraction, error message: %{public}s", database.lastErrorMsg());
     699        return 0;
     700    }
     701
     702    double rawSeconds = medianDaysSinceUIStatement.getColumnDouble(0);
     703    WallTime wallTime = WallTime::fromRawSeconds(rawSeconds);
     704    unsigned median = wallTime <= WallTime() ? 0 : std::floor((WallTime::now() - wallTime) / 24_h);
     705
     706    if (prevalentResourcesWithUserInteractionCount & 1)
     707        return median;
     708
     709    SQLiteStatement lowerMedianDaysSinceUIStatement = makeMedianWithUIQuery(database);
     710
     711    // Prepare
     712    if (lowerMedianDaysSinceUIStatement.prepare() != SQLITE_OK) {
     713        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::getMedianOfPrevalentResourcesWithUserInteraction, error message: %{public}s", database.lastErrorMsg());
     714        ASSERT_NOT_REACHED();
     715        return 0;
     716    }
     717
     718    // Bind
     719    if (lowerMedianDaysSinceUIStatement.bindInt(1, 1) != SQLITE_OK || lowerMedianDaysSinceUIStatement.bindInt(2, ((prevalentResourcesWithUserInteractionCount - 1) / 2)) != SQLITE_OK) {
     720        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::getMedianOfPrevalentResourcesWithUserInteraction, error message: %{public}s", database.lastErrorMsg());
     721        ASSERT_NOT_REACHED();
     722        return 0;
     723    }
     724
     725    // Step
     726    if (lowerMedianDaysSinceUIStatement.step() != SQLITE_ROW) {
     727        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::getMedianOfPrevalentResourcesWithUserInteraction, error message: %{public}s", database.lastErrorMsg());
     728        return 0;
     729    }
     730
     731    double rawSecondsLower = lowerMedianDaysSinceUIStatement.getColumnDouble(0);
     732    WallTime wallTimeLower = WallTime::fromRawSeconds(rawSecondsLower);
     733    return ((wallTimeLower <= WallTime() ? 0 : std::floor((WallTime::now() - wallTimeLower) / 24_h)) + median) / 2;
     734}
     735
     736unsigned ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResources() const
     737{
     738    if (m_countPrevalentResourcesStatement.step() == SQLITE_ROW) {
     739        unsigned prevalentResourceCount = m_countPrevalentResourcesStatement.getColumnInt(0);
     740        if (prevalentResourceCount >= minimumPrevalentResourcesForTelemetry) {
     741            resetStatement(m_countPrevalentResourcesStatement);
     742            return prevalentResourceCount;
     743        }
     744    }
     745    resetStatement(m_countPrevalentResourcesStatement);
     746    return 0;
     747}
     748
     749unsigned ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResourcesWithUI() const
     750{
     751    if (m_countPrevalentResourcesWithUserInteractionStatement.step() == SQLITE_ROW) {
     752        int count = m_countPrevalentResourcesWithUserInteractionStatement.getColumnInt(0);
     753        resetStatement(m_countPrevalentResourcesWithUserInteractionStatement);
     754        return count;
     755    }
     756    resetStatement(m_countPrevalentResourcesWithUserInteractionStatement);
     757    return 0;
     758}
     759
     760unsigned ResourceLoadStatisticsDatabaseStore::getTopPrevelentResourceDaysSinceUI() const
     761{
     762    SQLiteStatement topPrevalentResourceWithUserInteractionDaysSinceUserInteractionStatement(m_database, makeString("SELECT mostRecentUserInteractionTime FROM ObservedDomains INNER JOIN (SELECT ", joinSubStatisticsForSorting(), " LIMIT 1) as q ON ObservedDomains.domainID = q.domainID;"));
     763   
     764    // Prepare
     765    if (topPrevalentResourceWithUserInteractionDaysSinceUserInteractionStatement.prepare() != SQLITE_OK) {
     766        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::topPrevalentResourceWithUserInteractionDaysSinceUserInteractionStatement query failed to prepare, error message: %{public}s", m_database.lastErrorMsg());
     767        ASSERT_NOT_REACHED();
     768        return 0;
     769    }
     770   
     771    // Bind
     772    if (topPrevalentResourceWithUserInteractionDaysSinceUserInteractionStatement.bindInt(1, 1) != SQLITE_OK) {
     773        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::topPrevalentResourceWithUserInteractionDaysSinceUserInteractionStatement query failed to bind, error message: %{public}s", m_database.lastErrorMsg());
     774        ASSERT_NOT_REACHED();
     775        return 0;
     776    }
     777   
     778    // Step
     779    if (topPrevalentResourceWithUserInteractionDaysSinceUserInteractionStatement.step() != SQLITE_ROW) {
     780        RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::topPrevalentResourceWithUserInteractionDaysSinceUserInteractionStatement query failed to step, error message: %{public}s", m_database.lastErrorMsg());
     781        return 0;
     782    }
     783   
     784    double rawSeconds = topPrevalentResourceWithUserInteractionDaysSinceUserInteractionStatement.getColumnDouble(0);
     785    WallTime wallTime = WallTime::fromRawSeconds(rawSeconds);
     786   
     787    return wallTime <= WallTime() ? 0 : std::floor((WallTime::now() - wallTime) / 24_h);
     788}
     789
     790static unsigned getMedianOfPrevalentResourceWithoutUserInteraction(SQLiteDatabase& database, unsigned bucketSize, PrevalentResourceDatabaseTelemetry::Statistic statistic, unsigned numberOfPrevalentResourcesWithoutUI)
     791{
     792    if (numberOfPrevalentResourcesWithoutUI < bucketSize)
     793        return 0;
     794
     795    unsigned median;
     796    SQLiteStatement getMedianStatistic = makeMedianWithoutUIQuery(database, statistic);
     797
     798    if (getMedianStatistic.prepare() == SQLITE_OK) {
     799        if (getMedianStatistic.bindInt(1, 0) != SQLITE_OK
     800            || getMedianStatistic.bindInt(2, (bucketSize / 2)) != SQLITE_OK) {
     801            RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::makeMedianWithoutUIQuery, error message: %{public}s", database.lastErrorMsg());
     802            ASSERT_NOT_REACHED();
     803            return 0;
     804        }
     805        if (getMedianStatistic.step() == SQLITE_ROW)
     806            median = getMedianStatistic.getColumnDouble(0);
     807    }
     808
     809    if (bucketSize & 1)
     810        return median;
     811
     812    SQLiteStatement getLowerMedianStatistic = makeMedianWithoutUIQuery(database, statistic);
     813
     814    if (getLowerMedianStatistic.prepare() == SQLITE_OK) {
     815        if (getLowerMedianStatistic.bindInt(1, 0) != SQLITE_OK
     816            || getLowerMedianStatistic.bindInt(2, ((bucketSize-1) / 2)) != SQLITE_OK) {
     817            RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::makeMedianWithoutUIQuery, error message: %{public}s", database.lastErrorMsg());
     818            ASSERT_NOT_REACHED();
     819            return 0;
     820        }
     821        if (getLowerMedianStatistic.step() == SQLITE_ROW)
     822            return (getLowerMedianStatistic.getColumnDouble(0) + median) / 2;
     823    }
     824
     825    return 0;
     826}
     827
     828static unsigned getNumberOfPrevalentResourcesInTopResources(SQLiteDatabase& database, unsigned bucketSize)
     829{
     830    SQLiteStatement prevalentResourceCountInTop(database, makeString("SELECT COUNT(*) FROM (SELECT * FROM ObservedDomains o INNER JOIN(SELECT ", joinSubStatisticsForSorting(), ") as q on q.domainID = o.domainID LIMIT ?) as p WHERE p.hadUserInteraction = 1;"));
     831
     832    if (prevalentResourceCountInTop.prepare() == SQLITE_OK) {
     833        if (prevalentResourceCountInTop.bindText(1, "%") != SQLITE_OK
     834            || prevalentResourceCountInTop.bindInt(2, bucketSize) != SQLITE_OK) {
     835            RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResourcesInTopResources, error message: %{public}s", database.lastErrorMsg());
     836            ASSERT_NOT_REACHED();
     837            return 0;
     838        }
     839
     840        if (prevalentResourceCountInTop.step() == SQLITE_ROW)
     841            return prevalentResourceCountInTop.getColumnInt(0);
     842    }
     843
     844    return 0;
     845}
     846
     847static unsigned makeStatisticQuery(SQLiteDatabase& database, PrevalentResourceDatabaseTelemetry::Statistic statistic, int bucketSize, unsigned totalWithUI, unsigned totalWithoutUI)
     848{
     849    switch (statistic) {
     850    case PrevalentResourceDatabaseTelemetry::Statistic::NumberOfPrevalentResourcesWithUI:
     851        return getNumberOfPrevalentResourcesInTopResources(database, bucketSize);
     852    case PrevalentResourceDatabaseTelemetry::Statistic::MedianSubFrameWithoutUI:
     853    case PrevalentResourceDatabaseTelemetry::Statistic::MedianSubResourceWithoutUI:
     854    case PrevalentResourceDatabaseTelemetry::Statistic::MedianUniqueRedirectsWithoutUI:
     855    case PrevalentResourceDatabaseTelemetry::Statistic::MedianDataRecordsRemovedWithoutUI:
     856    case PrevalentResourceDatabaseTelemetry::Statistic::MedianTimesAccessedDueToUserInteractionWithoutUI:
     857    case PrevalentResourceDatabaseTelemetry::Statistic::MedianTimesAccessedDueToStorageAccessAPIWithoutUI:
     858        return getMedianOfPrevalentResourceWithoutUserInteraction(database, bucketSize, statistic, totalWithoutUI);
     859    }
     860}
     861
     862unsigned ResourceLoadStatisticsDatabaseStore::getNumberOfPrevalentResourcesWithoutUI() const
     863{
     864    if (m_countPrevalentResourcesWithoutUserInteractionStatement.step() == SQLITE_ROW) {
     865        int count = m_countPrevalentResourcesWithoutUserInteractionStatement.getColumnInt(0);
     866        resetStatement(m_countPrevalentResourcesWithoutUserInteractionStatement);
     867        return count;
     868    }
     869    resetStatement(m_countPrevalentResourcesWithoutUserInteractionStatement);
     870    return 0;
     871}
     872
     873void ResourceLoadStatisticsDatabaseStore::calculateTelemetryData(PrevalentResourceDatabaseTelemetry& data) const
     874{
     875    data.numberOfPrevalentResources = getNumberOfPrevalentResources();
     876    data.numberOfPrevalentResourcesWithUserInteraction = getNumberOfPrevalentResourcesWithUI();
     877    data.numberOfPrevalentResourcesWithoutUserInteraction = getNumberOfPrevalentResourcesWithoutUI();
     878    data.topPrevalentResourceWithUserInteractionDaysSinceUserInteraction = getTopPrevelentResourceDaysSinceUI();
     879    data.medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction = getMedianOfPrevalentResourcesWithUserInteraction(m_database, data.numberOfPrevalentResourcesWithUserInteraction);
     880
     881    for (unsigned bucketIndex = 0; bucketIndex < bucketSizes.size(); bucketIndex++) {
     882        unsigned bucketSize = bucketSizes[bucketIndex];
     883
     884        if (data.numberOfPrevalentResourcesWithoutUserInteraction < bucketSize)
     885            return;
     886
     887        for (unsigned statisticIndex = 0; statisticIndex < numberOfStatistics; statisticIndex++) {
     888            auto statistic = static_cast<PrevalentResourceDatabaseTelemetry::Statistic>(statisticIndex);
     889            data.statistics[statisticIndex][bucketIndex] = makeStatisticQuery(m_database, statistic, bucketSize, data.numberOfPrevalentResourcesWithUserInteraction, data.numberOfPrevalentResourcesWithoutUserInteraction);
     890        }
     891    }
     892}
     893
    605894void ResourceLoadStatisticsDatabaseStore::calculateAndSubmitTelemetry() const
    606895{
    607896    ASSERT(!RunLoop::isMain());
    608897
    609     // FIXME(195088): Implement for Database version.
     898    if (parameters().shouldSubmitTelemetry) {
     899        PrevalentResourceDatabaseTelemetry prevalentResourceDatabaseTelemetry;
     900        calculateTelemetryData(prevalentResourceDatabaseTelemetry);
     901        WebResourceLoadStatisticsTelemetry::submitTelemetry(*this, prevalentResourceDatabaseTelemetry);
     902    }
    610903}
    611904
  • trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h

    r250839 r250866  
    4848namespace WebKit {
    4949
     50static constexpr size_t numberOfBucketsPerStatistic = 5;
     51static constexpr size_t numberOfStatistics = 7;
     52static constexpr std::array<unsigned, numberOfBucketsPerStatistic> bucketSizes {{ 1, 3, 10, 50, 100 }};
     53
     54struct PrevalentResourceDatabaseTelemetry {
     55    using Buckets = std::array<unsigned, numberOfBucketsPerStatistic>;
     56
     57    enum class Statistic {
     58        NumberOfPrevalentResourcesWithUI,
     59        MedianSubFrameWithoutUI,
     60        MedianSubResourceWithoutUI,
     61        MedianUniqueRedirectsWithoutUI,
     62        MedianDataRecordsRemovedWithoutUI,
     63        MedianTimesAccessedDueToUserInteractionWithoutUI,
     64        MedianTimesAccessedDueToStorageAccessAPIWithoutUI
     65    };
     66
     67    unsigned numberOfPrevalentResources;
     68    unsigned numberOfPrevalentResourcesWithUserInteraction;
     69    unsigned numberOfPrevalentResourcesWithoutUserInteraction;
     70    unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction;
     71    unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction;
     72
     73    std::array<Buckets, numberOfStatistics> statistics;
     74};
     75
    5076class ResourceLoadStatisticsMemoryStore;
    5177
     
    111137    void merge(WebCore::SQLiteStatement&, const ResourceLoadStatistics&);
    112138    void clearDatabaseContents();
     139    unsigned getNumberOfPrevalentResources() const;
     140    unsigned getNumberOfPrevalentResourcesWithUI() const;
     141    unsigned getNumberOfPrevalentResourcesWithoutUI() const;
     142    unsigned getTopPrevelentResourceDaysSinceUI() const;
     143    void resetTelemetryPreparedStatements() const;
     144    void resetTelemetryStatements() const;
     145    void calculateTelemetryData(PrevalentResourceDatabaseTelemetry&) const;
    113146    bool insertObservedDomain(const ResourceLoadStatistics&);
    114147    void insertDomainRelationships(const ResourceLoadStatistics&);
     
    198231    mutable WebCore::SQLiteStatement m_isGrandfatheredStatement;
    199232    mutable WebCore::SQLiteStatement m_findExpiredUserInteractionStatement;
     233    mutable WebCore::SQLiteStatement m_countPrevalentResourcesStatement;
     234    mutable WebCore::SQLiteStatement m_countPrevalentResourcesWithUserInteractionStatement;
     235    mutable WebCore::SQLiteStatement m_countPrevalentResourcesWithoutUserInteractionStatement;
    200236    PAL::SessionID m_sessionID;
    201237};
  • trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp

    r250804 r250866  
    493493
    494494    postTask([this, completionHandler = WTFMove(completionHandler)]() mutable  {
    495         if (m_statisticsStore && is<ResourceLoadStatisticsMemoryStore>(*m_statisticsStore))
     495        if (!m_statisticsStore)
     496            return;
     497       
     498        if (is<ResourceLoadStatisticsMemoryStore>(*m_statisticsStore))
    496499            WebResourceLoadStatisticsTelemetry::calculateAndSubmit(downcast<ResourceLoadStatisticsMemoryStore>(*m_statisticsStore));
    497 
     500        else
     501            m_statisticsStore->calculateAndSubmitTelemetry();
    498502        postTaskReply(WTFMove(completionHandler));
    499503    });
     
    10781082}
    10791083
    1080 void WebResourceLoadStatisticsStore::notifyPageStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins) const
     1084void WebResourceLoadStatisticsStore::notifyPageStatisticsTelemetryFinished(unsigned numberOfPrevalentResources, unsigned numberOfPrevalentResourcesWithUserInteraction, unsigned numberOfPrevalentResourcesWithoutUserInteraction, unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, unsigned top3NumberOfPrevalentResourcesWithUI, unsigned top3MedianSubFrameWithoutUI, unsigned top3MedianSubResourceWithoutUI, unsigned top3MedianUniqueRedirectsWithoutUI, unsigned top3MedianDataRecordsRemovedWithoutUI) const
    10811085{
    10821086    ASSERT(RunLoop::isMain());
    10831087    if (m_networkSession)
    1084         const_cast<WebResourceLoadStatisticsStore*>(this)->networkSession()->notifyPageStatisticsTelemetryFinished(totalPrevalentResources, totalPrevalentResourcesWithUserInteraction, top3SubframeUnderTopFrameOrigins);
     1088        const_cast<WebResourceLoadStatisticsStore*>(this)->networkSession()->notifyPageStatisticsTelemetryFinished(numberOfPrevalentResources, numberOfPrevalentResourcesWithUserInteraction, numberOfPrevalentResourcesWithoutUserInteraction, topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, top3NumberOfPrevalentResourcesWithUI, top3MedianSubFrameWithoutUI, top3MedianSubResourceWithoutUI, top3MedianUniqueRedirectsWithoutUI, top3MedianDataRecordsRemovedWithoutUI);
    10851089}
    10861090
  • trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h

    r250804 r250866  
    189189
    190190    void sendDiagnosticMessageWithValue(const String& message, const String& description, unsigned value, unsigned sigDigits, WebCore::ShouldSample) const;
    191     void notifyPageStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins) const;
     191    void notifyPageStatisticsTelemetryFinished(unsigned numberOfPrevalentResources, unsigned numberOfPrevalentResourcesWithUserInteraction, unsigned numberOfPrevalentResourcesWithoutUserInteraction, unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, unsigned top3NumberOfPrevalentResourcesWithUI, unsigned top3MedianSubFrameWithoutUI, unsigned top3MedianSubResourceWithoutUI, unsigned top3MedianUniqueRedirectsWithoutUI, unsigned top3MedianDataRecordsRemovedWithoutUI) const;
    192192
    193193    void resourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics>&&);
  • trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.cpp

    r247190 r250866  
    2929#if ENABLE(RESOURCE_LOAD_STATISTICS)
    3030
     31#include "ResourceLoadStatisticsDatabaseStore.h"
    3132#include "ResourceLoadStatisticsMemoryStore.h"
    3233#include "WebPageProxy.h"
     
    200201   
    201202// This function is for testing purposes.
    202 void static notifyPages(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins, const WebResourceLoadStatisticsStore& store)
    203 {
    204     RunLoop::main().dispatch([totalPrevalentResources, totalPrevalentResourcesWithUserInteraction, top3SubframeUnderTopFrameOrigins, store = makeRef(store)] {
    205         store->notifyPageStatisticsTelemetryFinished(totalPrevalentResources, totalPrevalentResourcesWithUserInteraction, top3SubframeUnderTopFrameOrigins);
     203void static notifyPages(unsigned numberOfPrevalentResources, unsigned numberOfPrevalentResourcesWithUserInteraction, unsigned numberOfPrevalentResourcesWithoutUserInteraction, unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, unsigned top3NumberOfPrevalentResourcesWithUI, unsigned top3MedianSubFrameWithoutUI, unsigned top3MedianSubResourceWithoutUI, unsigned top3MedianUniqueRedirectsWithoutUI, unsigned top3MedianDataRecordsRemovedWithoutUI, const WebResourceLoadStatisticsStore& store)
     204{
     205    RunLoop::main().dispatch([numberOfPrevalentResources, numberOfPrevalentResourcesWithUserInteraction, numberOfPrevalentResourcesWithoutUserInteraction, topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, top3NumberOfPrevalentResourcesWithUI, top3MedianSubFrameWithoutUI, top3MedianSubResourceWithoutUI, top3MedianUniqueRedirectsWithoutUI, top3MedianDataRecordsRemovedWithoutUI, store = makeRef(store)] {
     206        store->notifyPageStatisticsTelemetryFinished(numberOfPrevalentResources, numberOfPrevalentResourcesWithUserInteraction, numberOfPrevalentResourcesWithoutUserInteraction, topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, top3NumberOfPrevalentResourcesWithUI, top3MedianSubFrameWithoutUI, top3MedianSubResourceWithoutUI, top3MedianUniqueRedirectsWithoutUI, top3MedianDataRecordsRemovedWithoutUI);
    206207    });
    207208}
     
    213214        return t.subframeUnderTopFrameOrigins;
    214215    };
    215    
    216     notifyPages(sortedPrevalentResources.size(), totalNumberOfPrevalentResourcesWithUserInteraction, median(sortedPrevalentResourcesWithoutUserInteraction, 0, 2, subframeUnderTopFrameOriginsGetter), store);
     216    notifyPages(sortedPrevalentResources.size(), totalNumberOfPrevalentResourcesWithUserInteraction, 0, 0, 0, 0, median(sortedPrevalentResourcesWithoutUserInteraction, 0, 2, subframeUnderTopFrameOriginsGetter), 0, 0, 0,  store);
    217217}
    218218   
     
    223223    auto sortedPrevalentResources = sortedPrevalentResourceTelemetry(resourceLoadStatisticsStore);
    224224    if (notifyPagesWhenTelemetryWasCaptured && sortedPrevalentResources.isEmpty()) {
    225         notifyPages(0, 0, 0, resourceLoadStatisticsStore.store());
     225        notifyPages(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, resourceLoadStatisticsStore.store());
    226226        return;
    227227    }
     
    243243        if (!webPageProxy) {
    244244            if (notifyPagesWhenTelemetryWasCaptured)
    245                 notifyPages(0, 0, 0, store);
     245                notifyPages(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, store);
    246246            return;
    247247        }
     
    264264    });
    265265}
     266
     267static StringView makeDescription(PrevalentResourceDatabaseTelemetry::Statistic statistic)
     268{
     269    switch (statistic) {
     270    case PrevalentResourceDatabaseTelemetry::Statistic::NumberOfPrevalentResourcesWithUI:
     271        return "PrevalentResourcesWithUserInteraction";
     272    case PrevalentResourceDatabaseTelemetry::Statistic::MedianSubFrameWithoutUI:
     273        return "SubframeUnderTopFrameOrigins";
     274    case PrevalentResourceDatabaseTelemetry::Statistic::MedianSubResourceWithoutUI:
     275        return "SubresourceUnderTopFrameOrigins";
     276    case PrevalentResourceDatabaseTelemetry::Statistic::MedianUniqueRedirectsWithoutUI:
     277        return "SubresourceUniqueRedirectsTo";
     278    case PrevalentResourceDatabaseTelemetry::Statistic::MedianDataRecordsRemovedWithoutUI:
     279        return "NumberOfTimesDataRecordsRemoved";
     280    case PrevalentResourceDatabaseTelemetry::Statistic::MedianTimesAccessedDueToUserInteractionWithoutUI:
     281        return "NumberOfTimesAccessedAsFirstPartyDueToUserInteraction";
     282    case PrevalentResourceDatabaseTelemetry::Statistic::MedianTimesAccessedDueToStorageAccessAPIWithoutUI:
     283        return "NumberOfTimesAccessedAsFirstPartyDueToStorageAccessAPI";
     284    }
     285}
     286
     287static void databaseSubmitTopLists(const PrevalentResourceDatabaseTelemetry& telemetry, const WebResourceLoadStatisticsStore& store)
     288{
     289    for (unsigned bucketIndex = 0; bucketIndex < bucketSizes.size(); bucketIndex++) {
     290
     291        if (telemetry.numberOfPrevalentResourcesWithoutUserInteraction < bucketSizes[bucketIndex])
     292            return;
     293
     294        String descriptionPreamble = makeString("top", bucketSizes[bucketIndex]);
     295
     296        for (unsigned statisticIndex = 0; statisticIndex < numberOfStatistics; statisticIndex++) {
     297            auto statistic = static_cast<PrevalentResourceDatabaseTelemetry::Statistic>(statisticIndex);
     298
     299            store.sendDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceLoadStatisticsTelemetryKey(), descriptionPreamble + makeDescription(statistic), telemetry.statistics[statisticIndex][bucketIndex], significantFiguresForLoggedValues, ShouldSample::No);
     300        }
     301    }
     302}
     303
     304void WebResourceLoadStatisticsTelemetry::submitTelemetry(const ResourceLoadStatisticsDatabaseStore& resourceLoadStatisticsStore, PrevalentResourceDatabaseTelemetry& prevalentResourceDatabaseTelemetry)
     305{
     306    ASSERT(!RunLoop::isMain());
     307
     308    if (notifyPagesWhenTelemetryWasCaptured && !prevalentResourceDatabaseTelemetry.numberOfPrevalentResources) {
     309        notifyPages(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, resourceLoadStatisticsStore.store());
     310        return;
     311    }
     312
     313    // Dispatch on the main thread to make sure the WebPageProxy we're using doesn't go away.
     314    RunLoop::main().dispatch([telemetry = WTFMove(prevalentResourceDatabaseTelemetry), store = makeRef(resourceLoadStatisticsStore.store())] () {
     315
     316        // The notify pages function is for testing so we don't need to do an actual submission.
     317        if (notifyPagesWhenTelemetryWasCaptured) {
     318            if (telemetry.numberOfPrevalentResourcesWithoutUserInteraction < 3) {
     319                notifyPages(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, store);
     320                return;
     321            }
     322            notifyPages(telemetry.numberOfPrevalentResources,
     323                telemetry.numberOfPrevalentResourcesWithUserInteraction,
     324                telemetry.numberOfPrevalentResourcesWithoutUserInteraction,
     325                telemetry.topPrevalentResourceWithUserInteractionDaysSinceUserInteraction,
     326                telemetry.medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction,
     327                telemetry.statistics[0][1], // bucket 1 -> top3.
     328                telemetry.statistics[1][1],
     329                telemetry.statistics[2][1],
     330                telemetry.statistics[3][1],
     331                telemetry.statistics[4][1],
     332                store);
     333            return;
     334        }
     335       
     336        auto webPageProxy = WebPageProxy::nonEphemeralWebPageProxy();
     337        if (!webPageProxy)
     338            return;
     339
     340        webPageProxy->logDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceLoadStatisticsTelemetryKey(), "totalNumberOfPrevalentResources"_s, telemetry.numberOfPrevalentResources, significantFiguresForLoggedValues, ShouldSample::No);
     341        webPageProxy->logDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceLoadStatisticsTelemetryKey(), "totalNumberOfPrevalentResourcesWithUserInteraction"_s, telemetry.numberOfPrevalentResourcesWithUserInteraction, significantFiguresForLoggedValues, ShouldSample::No);
     342        if (telemetry.numberOfPrevalentResourcesWithUserInteraction > 0)
     343            webPageProxy->logDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceLoadStatisticsTelemetryKey(), "topPrevalentResourceWithUserInteractionDaysSinceUserInteraction"_s, telemetry.topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, significantFiguresForLoggedValues, ShouldSample::No);
     344        if (telemetry.numberOfPrevalentResourcesWithUserInteraction > 1)
     345            webPageProxy->logDiagnosticMessageWithValue(DiagnosticLoggingKeys::resourceLoadStatisticsTelemetryKey(), "medianPrevalentResourcesWithUserInteractionDaysSinceUserInteraction"_s, telemetry.medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, significantFiguresForLoggedValues, ShouldSample::No);
     346
     347        databaseSubmitTopLists(telemetry, store);
     348    });
     349}
    266350   
    267351void WebResourceLoadStatisticsTelemetry::setNotifyPagesWhenTelemetryWasCaptured(bool always)
  • trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsTelemetry.h

    r240243 r250866  
    3333
    3434class ResourceLoadStatisticsMemoryStore;
     35class ResourceLoadStatisticsDatabaseStore;
     36struct PrevalentResourceDatabaseTelemetry;
    3537
    3638namespace WebResourceLoadStatisticsTelemetry {
    3739   
    3840void calculateAndSubmit(const ResourceLoadStatisticsMemoryStore&);
     41void submitTelemetry(const ResourceLoadStatisticsDatabaseStore&, PrevalentResourceDatabaseTelemetry&);
    3942void setNotifyPagesWhenTelemetryWasCaptured(bool);
    4043   
  • trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp

    r250521 r250866  
    194194}
    195195
    196 void NetworkSession::notifyPageStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins)
    197 {
    198     m_networkProcess->parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyResourceLoadStatisticsTelemetryFinished(totalPrevalentResources, totalPrevalentResourcesWithUserInteraction, top3SubframeUnderTopFrameOrigins), 0);
     196void NetworkSession::notifyPageStatisticsTelemetryFinished(unsigned numberOfPrevalentResources, unsigned numberOfPrevalentResourcesWithUserInteraction, unsigned numberOfPrevalentResourcesWithoutUserInteraction, unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, unsigned top3NumberOfPrevalentResourcesWithUI, unsigned top3MedianSubFrameWithoutUI, unsigned top3MedianSubResourceWithoutUI, unsigned top3MedianUniqueRedirectsWithoutUI, unsigned top3MedianDataRecordsRemovedWithoutUI)
     197{
     198    m_networkProcess->parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyResourceLoadStatisticsTelemetryFinished(numberOfPrevalentResources, numberOfPrevalentResourcesWithUserInteraction, numberOfPrevalentResourcesWithoutUserInteraction, topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, top3NumberOfPrevalentResourcesWithUI, top3MedianSubFrameWithoutUI, top3MedianSubResourceWithoutUI, top3MedianUniqueRedirectsWithoutUI, top3MedianDataRecordsRemovedWithoutUI), 0);
    199199}
    200200
  • trunk/Source/WebKit/NetworkProcess/NetworkSession.h

    r250521 r250866  
    9191    void registrableDomainsWithWebsiteData(OptionSet<WebsiteDataType>, bool shouldNotifyPage, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&&);
    9292    void logDiagnosticMessageWithValue(const String& message, const String& description, unsigned value, unsigned significantFigures, WebCore::ShouldSample);
    93     void notifyPageStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins);
     93    void notifyPageStatisticsTelemetryFinished(unsigned numberOfPrevalentResources, unsigned numberOfPrevalentResourcesWithUserInteraction, unsigned numberOfPrevalentResourcesWithoutUserInteraction, unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, unsigned top3NumberOfPrevalentResourcesWithUI, unsigned top3MedianSubFrameWithoutUI, unsigned top3MedianSubResourceWithoutUI, unsigned top3MedianUniqueRedirectsWithoutUI, unsigned top3MedianDataRecordsRemovedWithoutUI);
    9494    bool enableResourceLoadStatisticsLogTestingEvent() const { return m_enableResourceLoadStatisticsLogTestingEvent; }
    9595    void setResourceLoadStatisticsLogTestingEvent(bool log) { m_enableResourceLoadStatisticsLogTestingEvent = log; }
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp

    r250804 r250866  
    957957}
    958958
    959 void NetworkProcessProxy::notifyResourceLoadStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins)
     959void NetworkProcessProxy::notifyResourceLoadStatisticsTelemetryFinished(unsigned numberOfPrevalentResources, unsigned numberOfPrevalentResourcesWithUserInteraction, unsigned numberOfPrevalentResourcesWithoutUserInteraction, unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, unsigned top3NumberOfPrevalentResourcesWithUI, unsigned top3MedianSubFrameWithoutUI, unsigned top3MedianSubResourceWithoutUI, unsigned top3MedianUniqueRedirectsWithoutUI, unsigned top3MedianDataRecordsRemovedWithoutUI)
    960960{
    961961    API::Dictionary::MapType messageBody;
    962     messageBody.set("TotalPrevalentResources"_s, API::UInt64::create(totalPrevalentResources));
    963     messageBody.set("TotalPrevalentResourcesWithUserInteraction"_s, API::UInt64::create(totalPrevalentResourcesWithUserInteraction));
    964     messageBody.set("Top3SubframeUnderTopFrameOrigins"_s, API::UInt64::create(top3SubframeUnderTopFrameOrigins));
     962    messageBody.set("NumberOfPrevalentResources"_s, API::UInt64::create(numberOfPrevalentResources));
     963    messageBody.set("NumberOfPrevalentResourcesWithUserInteraction"_s, API::UInt64::create(numberOfPrevalentResourcesWithUserInteraction));
     964    messageBody.set("NumberOfPrevalentResourcesWithoutUserInteraction"_s, API::UInt64::create(numberOfPrevalentResourcesWithoutUserInteraction));
     965    messageBody.set("TopPrevalentResourceWithUserInteractionDaysSinceUserInteraction"_s, API::UInt64::create(topPrevalentResourceWithUserInteractionDaysSinceUserInteraction));
     966    messageBody.set("MedianDaysSinceUserInteractionPrevalentResourceWithUserInteraction"_s, API::UInt64::create(medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction));
     967    messageBody.set("Top3NumberOfPrevalentResourcesWithUI"_s, API::UInt64::create(top3NumberOfPrevalentResourcesWithUI));
     968    messageBody.set("Top3MedianSubFrameWithoutUI"_s, API::UInt64::create(top3MedianSubFrameWithoutUI));
     969    messageBody.set("Top3MedianSubResourceWithoutUI"_s, API::UInt64::create(top3MedianSubResourceWithoutUI));
     970    messageBody.set("Top3MedianUniqueRedirectsWithoutUI"_s, API::UInt64::create(top3MedianUniqueRedirectsWithoutUI));
     971    messageBody.set("Top3MedianDataRecordsRemovedWithoutUI"_s, API::UInt64::create(top3MedianDataRecordsRemovedWithoutUI));
    965972
    966973    WebProcessProxy::notifyPageStatisticsTelemetryFinished(API::Dictionary::create(messageBody).ptr());
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h

    r250804 r250866  
    233233    void notifyWebsiteDataDeletionForRegistrableDomainsFinished();
    234234    void notifyWebsiteDataScanForRegistrableDomainsFinished();
    235     void notifyResourceLoadStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins);
     235    void notifyResourceLoadStatisticsTelemetryFinished(unsigned numberOfPrevalentResources, unsigned numberOfPrevalentResourcesWithUserInteraction, unsigned numberOfPrevalentResourcesWithoutUserInteraction, unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, unsigned top3NumberOfPrevalentResourcesWithUI, unsigned top3MedianSubFrameWithoutUI, unsigned top3MedianSubResourceWithoutUI, unsigned top3MedianUniqueRedirectsWithoutUI, unsigned top3MedianDataRecordsRemovedWithoutUI);
    236236#endif
    237237    void retrieveCacheStorageParameters(PAL::SessionID);
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in

    r249832 r250866  
    4646    NotifyWebsiteDataDeletionForRegistrableDomainsFinished()
    4747    NotifyWebsiteDataScanForRegistrableDomainsFinished()
    48     NotifyResourceLoadStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins)
     48    NotifyResourceLoadStatisticsTelemetryFinished(unsigned numberOfPrevalentResources, unsigned numberOfPrevalentResourcesWithUserInteraction, unsigned numberOfPrevalentResourcesWithoutUserInteraction, unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, unsigned top3NumberOfPrevalentResourcesWithUI, unsigned top3MedianSubFrameWithoutUI, unsigned top3MedianSubResourceWithoutUI, unsigned top3MedianUniqueRedirectsWithoutUI, unsigned top3MedianDataRecordsRemovedWithoutUI)
    4949    RequestStorageAccessConfirm(WebKit::WebPageProxyIdentifier pageID, WebCore::FrameIdentifier frameID, WebCore::RegistrableDomain subFrameDomain, WebCore::RegistrableDomain topFrameDomain) -> (bool userDidGrantAccess) Async
    5050    DeleteWebsiteDataInUIProcessForRegistrableDomains(PAL::SessionID sessionID, OptionSet<WebKit::WebsiteDataType> dataTypes, OptionSet<WebKit::WebsiteDataFetchOption> fetchOptions, Vector<WebCore::RegistrableDomain> domains) -> (HashSet<WebCore::RegistrableDomain> domainsWithMatchingDataRecords) Async
  • trunk/Tools/ChangeLog

    r250863 r250866  
     12019-10-08  Kate Cheney  <katherine_cheney@apple.com>
     2
     3        Implement Telemetry and Dumping Routines for SQLite backend (195088)
     4        https://bugs.webkit.org/show_bug.cgi?id=195088
     5        <rdar://problem/54213407>
     6
     7        Reviewed by John Wilander.
     8
     9        Updated the current testing for telemetry which only tested 3
     10        statistics. With this patch it now tests 10 statistics.
     11        * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
     12        (WTR::InjectedBundle::didReceiveMessageToPage):
     13        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
     14        (WTR::TestRunner::statisticsDidRunTelemetryCallback):
     15        * WebKitTestRunner/InjectedBundle/TestRunner.h:
     16
    1172019-10-08  Timothy Hatcher  <timothy@apple.com>
    218
  • trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp

    r250621 r250866  
    441441        WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
    442442
    443         WKRetainPtr<WKStringRef> totalPrevalentResourcesKey = adoptWK(WKStringCreateWithUTF8CString("TotalPrevalentResources"));
    444         WKRetainPtr<WKStringRef> totalPrevalentResourcesWithUserInteractionKey = adoptWK(WKStringCreateWithUTF8CString("TotalPrevalentResourcesWithUserInteraction"));
    445         WKRetainPtr<WKStringRef> top3SubframeUnderTopFrameOriginsKey = adoptWK(WKStringCreateWithUTF8CString("Top3SubframeUnderTopFrameOrigins"));
    446 
    447         unsigned totalPrevalentResources = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, totalPrevalentResourcesKey.get())));
    448         unsigned totalPrevalentResourcesWithUserInteraction = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, totalPrevalentResourcesWithUserInteractionKey.get())));
    449         unsigned top3SubframeUnderTopFrameOrigins = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, top3SubframeUnderTopFrameOriginsKey.get())));
    450 
    451         m_testRunner->statisticsDidRunTelemetryCallback(totalPrevalentResources, totalPrevalentResourcesWithUserInteraction, top3SubframeUnderTopFrameOrigins);
     443        WKRetainPtr<WKStringRef> numberOfPrevalentResourcesKey = adoptWK(WKStringCreateWithUTF8CString("NumberOfPrevalentResources"));
     444        WKRetainPtr<WKStringRef> numberOfPrevalentResourcesWithUserInteractionKey = adoptWK(WKStringCreateWithUTF8CString("NumberOfPrevalentResourcesWithUserInteraction"));
     445        WKRetainPtr<WKStringRef> numberOfPrevalentResourcesWithoutUserInteractionKey = adoptWK(WKStringCreateWithUTF8CString("NumberOfPrevalentResourcesWithoutUserInteraction"));
     446        WKRetainPtr<WKStringRef> topPrevalentResourceWithUserInteractionDaysSinceUserInteractionKey = adoptWK(WKStringCreateWithUTF8CString("TopPrevalentResourceWithUserInteractionDaysSinceUserInteraction"));
     447        WKRetainPtr<WKStringRef> medianDaysSinceUserInteractionPrevalentResourceWithUserInteractionKey = adoptWK(WKStringCreateWithUTF8CString("MedianDaysSinceUserInteractionPrevalentResourceWithUserInteraction"));
     448        WKRetainPtr<WKStringRef> top3NumberOfPrevalentResourcesWithUIKey = adoptWK(WKStringCreateWithUTF8CString("Top3NumberOfPrevalentResourcesWithUI"));
     449        WKRetainPtr<WKStringRef> top3MedianSubFrameWithoutUIKey = adoptWK(WKStringCreateWithUTF8CString("Top3MedianSubFrameWithoutUI"));
     450        WKRetainPtr<WKStringRef> top3MedianSubResourceWithoutUIKey = adoptWK(WKStringCreateWithUTF8CString("Top3MedianSubResourceWithoutUI"));
     451        WKRetainPtr<WKStringRef> top3MedianUniqueRedirectsWithoutUIKey = adoptWK(WKStringCreateWithUTF8CString("Top3MedianUniqueRedirectsWithoutUI"));
     452        WKRetainPtr<WKStringRef> top3MedianDataRecordsRemovedWithoutUIKey = adoptWK(WKStringCreateWithUTF8CString("Top3MedianDataRecordsRemovedWithoutUI"));
     453       
     454        unsigned numberOfPrevalentResources = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, numberOfPrevalentResourcesKey.get())));
     455        unsigned numberOfPrevalentResourcesWithUserInteraction = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, numberOfPrevalentResourcesWithUserInteractionKey.get())));
     456        unsigned numberOfPrevalentResourcesWithoutUserInteraction = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, numberOfPrevalentResourcesWithoutUserInteractionKey.get())));
     457        unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, topPrevalentResourceWithUserInteractionDaysSinceUserInteractionKey.get())));
     458        unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, medianDaysSinceUserInteractionPrevalentResourceWithUserInteractionKey.get())));
     459        unsigned top3NumberOfPrevalentResourcesWithUI = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, top3NumberOfPrevalentResourcesWithUIKey.get())));
     460        unsigned top3MedianSubFrameWithoutUI = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, top3MedianSubFrameWithoutUIKey.get())));
     461        unsigned top3MedianSubResourceWithoutUI = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, top3MedianSubResourceWithoutUIKey.get())));
     462        unsigned top3MedianUniqueRedirectsWithoutUI = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, top3MedianUniqueRedirectsWithoutUIKey.get())));
     463        unsigned top3MedianDataRecordsRemovedWithoutUI = (unsigned)WKUInt64GetValue(static_cast<WKUInt64Ref>(WKDictionaryGetItemForKey(messageBodyDictionary, top3MedianDataRecordsRemovedWithoutUIKey.get())));
     464
     465        m_testRunner->statisticsDidRunTelemetryCallback(numberOfPrevalentResources, numberOfPrevalentResourcesWithUserInteraction, numberOfPrevalentResourcesWithoutUserInteraction, topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, top3NumberOfPrevalentResourcesWithUI, top3MedianSubFrameWithoutUI, top3MedianSubResourceWithoutUI, top3MedianUniqueRedirectsWithoutUI, top3MedianDataRecordsRemovedWithoutUI);
    452466        return;
    453467    }
  • trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp

    r250852 r250866  
    20092009}
    20102010   
    2011 void TestRunner::statisticsDidRunTelemetryCallback(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins)
     2011void TestRunner::statisticsDidRunTelemetryCallback(unsigned numberOfPrevalentResources, unsigned numberOfPrevalentResourcesWithUserInteraction, unsigned numberOfPrevalentResourcesWithoutUserInteraction, unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, unsigned top3NumberOfPrevalentResourcesWithUI, unsigned top3MedianSubFrameWithoutUI, unsigned top3MedianSubResourceWithoutUI, unsigned top3MedianUniqueRedirectsWithoutUI, unsigned top3MedianDataRecordsRemovedWithoutUI)
    20122012{
    20132013    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::singleton().page()->page());
    20142014    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
    20152015   
    2016     String string = makeString("{ \"totalPrevalentResources\" : ", totalPrevalentResources, ", \"totalPrevalentResourcesWithUserInteraction\" : ", totalPrevalentResourcesWithUserInteraction, ", \"top3SubframeUnderTopFrameOrigins\" : ", top3SubframeUnderTopFrameOrigins, " }");
     2016    String string = makeString("{ \"numberOfPrevalentResources\" : ", numberOfPrevalentResources, ", \"numberOfPrevalentResourcesWithUserInteraction\" : ", numberOfPrevalentResourcesWithUserInteraction, ", \"numberOfPrevalentResourcesWithoutUserInteraction\" : ", numberOfPrevalentResourcesWithoutUserInteraction, ", \"topPrevalentResourceWithUserInteractionDaysSinceUserInteraction\" : ", topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, ", \"medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction\" : ", medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, ", \"top3NumberOfPrevalentResourcesWithUI\" : ", top3NumberOfPrevalentResourcesWithUI, ", \"top3MedianSubFrameWithoutUI\" : ", top3MedianSubFrameWithoutUI, ", \"top3MedianSubResourceWithoutUI\" : ", top3MedianSubResourceWithoutUI, ", \"top3MedianUniqueRedirectsWithoutUI\" : ", top3MedianUniqueRedirectsWithoutUI, ", \"top3MedianDataRecordsRemovedWithoutUI\" : ", top3MedianDataRecordsRemovedWithoutUI, " }");
    20172017   
    20182018    JSValueRef result = JSValueMakeFromJSONString(context, adopt(JSStringCreateWithUTF8CString(string.utf8().data())).get());
  • trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h

    r250852 r250866  
    385385    void statisticsDidModifyDataRecordsCallback();
    386386    void statisticsDidScanDataRecordsCallback();
    387     void statisticsDidRunTelemetryCallback(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins);
     387    void statisticsDidRunTelemetryCallback(unsigned numberOfPrevalentResources, unsigned numberOfPrevalentResourcesWithUserInteraction, unsigned numberOfPrevalentResourcesWithoutUserInteraction, unsigned topPrevalentResourceWithUserInteractionDaysSinceUserInteraction, unsigned medianDaysSinceUserInteractionPrevalentResourceWithUserInteraction, unsigned top3NumberOfPrevalentResourcesWithUI, unsigned top3MedianSubFrameWithoutUI, unsigned top3MedianSubResourceWithoutUI, unsigned top3MedianUniqueRedirectsWithoutUI, unsigned top3MedianDataRecordsRemovedWithoutUI);
    388388    bool statisticsNotifyObserver();
    389389    void statisticsProcessStatisticsAndDataRecords();
Note: See TracChangeset for help on using the changeset viewer.