Changeset 252014 in webkit


Ignore:
Timestamp:
Nov 4, 2019 2:13:40 PM (4 years ago)
Author:
wilander@apple.com
Message:

Resource Load Statistics: Flush the shared ResourceLoadObserver when the webpage is closed by JavaScript
https://bugs.webkit.org/show_bug.cgi?id=203623
<rdar://problem/56756427>

Reviewed by Alex Christensen.

Source/WebCore:

New API test added.

  • loader/ResourceLoadObserver.cpp:

(WebCore::ResourceLoadObserver::shared):

Now returns its own empty observer if no shared one has been set.

  • loader/ResourceLoadObserver.h:

(WebCore::ResourceLoadObserver::logSubresourceLoadingForTesting):

Test function to seed the web process' observer.

  • page/DOMWindow.cpp:

(WebCore::DOMWindow::close):

Now flushes the shared observer.

Source/WebKit:

This patch adds flushing of pending statistics when a window is closed by JavaScript,
when a webpage is removed from the web process, and when the web process prepares to
suspend.

New API test added.

  • NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:

(WebKit::WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated):

Now calls logTestingEvent() so that the test infrastructure can wait for updates.

  • UIProcess/API/Cocoa/WKProcessPool.mm:

(-[WKProcessPool _seedResourceLoadStatisticsForTestingWithFirstParty:thirdParty:shouldScheduleNotification:completionHandler:]):

Test infrastructure to seed every web process' WebCore::ResourceLoadObserver with test data.

  • UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
  • UIProcess/API/Cocoa/WKWebsiteDataStore.mm:

(-[WKWebsiteDataStore _clearResourceLoadStatistics:]):
(-[WKWebsiteDataStore _isRegisteredAsSubresourceUnderFirstParty:thirdParty:completionHandler:]):

Test infrastructure.

  • UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
  • UIProcess/WebProcessPool.cpp:

(WebKit::WebProcessPool::seedResourceLoadStatisticsForTesting):

Test infrastructure.

  • UIProcess/WebProcessPool.h:
  • UIProcess/WebsiteData/WebsiteDataStore.cpp:

(WebKit::WebsiteDataStore::isRegisteredAsSubresourceUnder):

Made sure the completion handler is called even if there is no network process.

(WebKit::WebsiteDataStore::setResourceLoadStatisticsEnabled):

Now tells all web processes to turn ITP on or off.

  • WebProcess/WebCoreSupport/WebResourceLoadObserver.cpp:

(WebKit::WebResourceLoadObserver::~WebResourceLoadObserver):
(WebKit::WebResourceLoadObserver::logSubresourceLoadingForTesting):

Test infrastructure to seed the observer with test data.

  • WebProcess/WebCoreSupport/WebResourceLoadObserver.h:
  • WebProcess/WebProcess.cpp:

(WebKit::WebProcess::setWebsiteDataStoreParameters):

Now checks whether a shared observer already exists before setting one.

(WebKit::WebProcess::removeWebPage):
(WebKit::WebProcess::prepareToSuspend):

These two functions now call WebProcess::flushResourceLoadStatistics().

(WebKit::WebProcess::setResourceLoadStatisticsEnabled):

This function now sets the process' shared WebCore::ResourceLoadObserver if none exists.

(WebKit::WebProcess::flushResourceLoadStatistics):

This function tells the shared WebCore::ResourceLoadObserver to send any pending
statistics to the central ITP store.

(WebKit::WebProcess::seedResourceLoadStatisticsForTesting):

Test infrastructure to seed the shared observer with test data.

  • WebProcess/WebProcess.h:
  • WebProcess/WebProcess.messages.in:

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm:

(TEST):

Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r252013 r252014  
     12019-11-04  John Wilander  <wilander@apple.com>
     2
     3        Resource Load Statistics: Flush the shared ResourceLoadObserver when the webpage is closed by JavaScript
     4        https://bugs.webkit.org/show_bug.cgi?id=203623
     5        <rdar://problem/56756427>
     6
     7        Reviewed by Alex Christensen.
     8
     9        New API test added.
     10
     11        * loader/ResourceLoadObserver.cpp:
     12        (WebCore::ResourceLoadObserver::shared):
     13            Now returns its own empty observer if no shared one has been set.
     14        * loader/ResourceLoadObserver.h:
     15        (WebCore::ResourceLoadObserver::logSubresourceLoadingForTesting):
     16            Test function to seed the web process' observer.
     17        * page/DOMWindow.cpp:
     18        (WebCore::DOMWindow::close):
     19            Now flushes the shared observer.
     20
    1212019-11-04  Alex Christensen  <achristensen@webkit.org>
    222
  • trunk/Source/WebCore/loader/ResourceLoadObserver.cpp

    r249920 r252014  
    2626#include "config.h"
    2727#include "ResourceLoadObserver.h"
     28#include <wtf/NeverDestroyed.h>
    2829
    2930namespace WebCore {
     
    4344ResourceLoadObserver& ResourceLoadObserver::shared()
    4445{
     46    static NeverDestroyed<ResourceLoadObserver> emptyObserver;
    4547    if (!sharedObserver())
    46         sharedObserver() = new ResourceLoadObserver;
     48        return emptyObserver;
    4749    return *sharedObserver();
    4850}
  • trunk/Source/WebCore/loader/ResourceLoadObserver.h

    r249920 r252014  
    5353    virtual void logNavigatorAPIAccessed(const Document&, const ResourceLoadStatistics::NavigatorAPI) { }
    5454    virtual void logScreenAPIAccessed(const Document&, const ResourceLoadStatistics::ScreenAPI) { }
     55    virtual void logSubresourceLoadingForTesting(const RegistrableDomain& /* firstPartyDomain */, const RegistrableDomain& /* thirdPartyDomain */, bool /* shouldScheduleNotification */) { }
    5556
    5657    virtual String statisticsForURL(const URL&) { return { }; }
  • trunk/Source/WebCore/page/DOMWindow.cpp

    r251425 r252014  
    10591059        return;
    10601060
     1061    ResourceLoadObserver::shared().updateCentralStatisticsStore();
     1062
    10611063    page->setIsClosing();
    10621064    page->chrome().closeWindowSoon();
  • trunk/Source/WebKit/ChangeLog

    r252011 r252014  
     12019-11-04  John Wilander  <wilander@apple.com>
     2
     3        Resource Load Statistics: Flush the shared ResourceLoadObserver when the webpage is closed by JavaScript
     4        https://bugs.webkit.org/show_bug.cgi?id=203623
     5        <rdar://problem/56756427>
     6
     7        Reviewed by Alex Christensen.
     8
     9        This patch adds flushing of pending statistics when a window is closed by JavaScript,
     10        when a webpage is removed from the web process, and when the web process prepares to
     11        suspend.
     12
     13        New API test added.
     14
     15        * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
     16        (WebKit::WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated):
     17            Now calls logTestingEvent() so that the test infrastructure can wait for updates.
     18        * UIProcess/API/Cocoa/WKProcessPool.mm:
     19        (-[WKProcessPool _seedResourceLoadStatisticsForTestingWithFirstParty:thirdParty:shouldScheduleNotification:completionHandler:]):
     20            Test infrastructure to seed every web process' WebCore::ResourceLoadObserver with test data.
     21        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
     22        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
     23        (-[WKWebsiteDataStore _clearResourceLoadStatistics:]):
     24        (-[WKWebsiteDataStore _isRegisteredAsSubresourceUnderFirstParty:thirdParty:completionHandler:]):
     25            Test infrastructure.
     26        * UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
     27        * UIProcess/WebProcessPool.cpp:
     28        (WebKit::WebProcessPool::seedResourceLoadStatisticsForTesting):
     29            Test infrastructure.
     30        * UIProcess/WebProcessPool.h:
     31        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
     32        (WebKit::WebsiteDataStore::isRegisteredAsSubresourceUnder):
     33            Made sure the completion handler is called even if there is no network process.
     34        (WebKit::WebsiteDataStore::setResourceLoadStatisticsEnabled):
     35            Now tells all web processes to turn ITP on or off.
     36        * WebProcess/WebCoreSupport/WebResourceLoadObserver.cpp:
     37        (WebKit::WebResourceLoadObserver::~WebResourceLoadObserver):
     38        (WebKit::WebResourceLoadObserver::logSubresourceLoadingForTesting):
     39            Test infrastructure to seed the observer with test data.
     40        * WebProcess/WebCoreSupport/WebResourceLoadObserver.h:
     41        * WebProcess/WebProcess.cpp:
     42        (WebKit::WebProcess::setWebsiteDataStoreParameters):
     43            Now checks whether a shared observer already exists before setting one.
     44        (WebKit::WebProcess::removeWebPage):
     45        (WebKit::WebProcess::prepareToSuspend):
     46            These two functions now call WebProcess::flushResourceLoadStatistics().
     47        (WebKit::WebProcess::setResourceLoadStatisticsEnabled):
     48            This function now sets the process' shared WebCore::ResourceLoadObserver if none exists.
     49        (WebKit::WebProcess::flushResourceLoadStatistics):
     50            This function tells the shared WebCore::ResourceLoadObserver to send any pending
     51            statistics to the central ITP store.
     52        (WebKit::WebProcess::seedResourceLoadStatisticsForTesting):
     53            Test infrastructure to seed the shared observer with test data.
     54        * WebProcess/WebProcess.h:
     55        * WebProcess/WebProcess.messages.in:
     56
    1572019-11-04  Chris Dumez  <cdumez@apple.com>
    258
  • trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp

    r251672 r252014  
    274274    // coming from IPC. ResourceLoadStatistics only contains strings which are safe to move to other threads as long
    275275    // as nobody on this thread holds a reference to those strings.
    276     postTask([this, statistics = WTFMove(statistics)]() mutable {
     276    postTask([this, protectedThis = makeRef(*this), statistics = WTFMove(statistics)]() mutable {
    277277        if (!m_statisticsStore)
    278278            return;
     
    284284
    285285        // Fire before processing statistics to propagate user interaction as fast as possible to the network process.
    286         m_statisticsStore->updateCookieBlocking([]() { });
     286        m_statisticsStore->updateCookieBlocking([this, protectedThis = protectedThis.copyRef()]() {
     287            postTaskReply([this, protectedThis = protectedThis.copyRef()]() {
     288                logTestingEvent("Statistics Updated"_s);
     289            });
     290        });
    287291        m_statisticsStore->processStatisticsAndDataRecords();
    288292    });
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm

    r251067 r252014  
    5050#import <WebCore/CertificateInfo.h>
    5151#import <WebCore/PluginData.h>
     52#import <WebCore/RegistrableDomain.h>
    5253#import <pal/spi/cf/CFNetworkSPI.h>
    5354#import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
     
    654655}
    655656
     657- (void)_seedResourceLoadStatisticsForTestingWithFirstParty:(NSURL *)firstPartyURL thirdParty:(NSURL *)thirdPartyURL shouldScheduleNotification:(BOOL)shouldScheduleNotification completionHandler:(void(^)(void))completionHandler
     658{
     659#if ENABLE(RESOURCE_LOAD_STATISTICS)
     660    _processPool->seedResourceLoadStatisticsForTesting(WebCore::RegistrableDomain { firstPartyURL }, WebCore::RegistrableDomain { thirdPartyURL }, shouldScheduleNotification, [completionHandler = makeBlockPtr(completionHandler)] () {
     661        completionHandler();
     662    });
     663#else
     664    UNUSED_PARAM(firstPartyURL);
     665    UNUSED_PARAM(thirdPartyURL);
     666    UNUSED_PARAM(shouldScheduleNotification);
     667    UNUSED_PARAM(completionHandler);
     668#endif
     669}
     670
    656671@end
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h

    r251067 r252014  
    133133- (void)_synthesizeAppIsBackground:(BOOL)background WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    134134
     135// Test only.
     136- (void)_seedResourceLoadStatisticsForTestingWithFirstParty:(NSURL *)firstPartyURL thirdParty:(NSURL *)thirdPartyURL shouldScheduleNotification:(BOOL)shouldScheduleNotification completionHandler:(void(^)(void))completionHandler  WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     137
    135138@end
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm

    r251687 r252014  
    3030#import "AuthenticationChallengeDispositionCocoa.h"
    3131#import "CompletionHandlerCallChecker.h"
     32#import "ShouldGrandfatherStatistics.h"
    3233#import "WKHTTPCookieStoreInternal.h"
    3334#import "WKNSArray.h"
     
    496497}
    497498
     499- (void)_clearResourceLoadStatistics:(void (^)(void))completionHandler
     500{
     501#if ENABLE(RESOURCE_LOAD_STATISTICS)
     502    _websiteDataStore->scheduleClearInMemoryAndPersistent(WebKit::ShouldGrandfatherStatistics::No, [completionHandler = makeBlockPtr(completionHandler)]() {
     503        completionHandler();
     504    });
     505#else
     506    completionHandler();
     507#endif
     508}
     509
     510- (void)_isRegisteredAsSubresourceUnderFirstParty:(NSURL *)firstPartyURL thirdParty:(NSURL *)thirdPartyURL completionHandler:(void (^)(BOOL))completionHandler
     511{
     512#if ENABLE(RESOURCE_LOAD_STATISTICS)
     513    _websiteDataStore->isRegisteredAsSubresourceUnder(thirdPartyURL, firstPartyURL, [completionHandler = makeBlockPtr(completionHandler)](bool enabled) {
     514        completionHandler(enabled);
     515    });
     516#else
     517    completionHandler(NO);
     518#endif
     519}
     520
    498521- (void)_processStatisticsAndDataRecords:(void (^)(void))completionHandler
    499522{
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h

    r251687 r252014  
    7171- (void)_setPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    7272- (void)_getIsPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(BOOL))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    73 - (void)_clearPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(void))completionHandler;
     73- (void)_clearPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     74- (void)_clearResourceLoadStatistics:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     75- (void)_isRegisteredAsSubresourceUnderFirstParty:(NSURL *)firstPartyURL thirdParty:(NSURL *)thirdPartyURL completionHandler:(void (^)(BOOL))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    7476- (void)_processStatisticsAndDataRecords:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    7577
  • trunk/Source/WebKit/UIProcess/WebProcessPool.cpp

    r252011 r252014  
    9090#include <WebCore/ProcessIdentifier.h>
    9191#include <WebCore/ProcessWarming.h>
     92#include <WebCore/RegistrableDomain.h>
    9293#include <WebCore/RegistrationDatabase.h>
    9394#include <WebCore/ResourceRequest.h>
    9495#include <WebCore/RuntimeApplicationChecks.h>
    9596#include <pal/SessionID.h>
     97#include <wtf/CallbackAggregator.h>
    9698#include <wtf/Language.h>
    9799#include <wtf/MainThread.h>
     
    22772279    m_networkProcess->didCommitCrossSiteLoadWithDataTransfer(sessionID, fromDomain, toDomain, navigationDataTransfer, webPageProxyID, webPageID);
    22782280}
     2281
     2282void WebProcessPool::seedResourceLoadStatisticsForTesting(const RegistrableDomain& firstPartyDomain, const RegistrableDomain& thirdPartyDomain, bool shouldScheduleNotification, CompletionHandler<void()>&& completionHandler)
     2283{
     2284    auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
     2285
     2286    for (auto& process : processes())
     2287        process->sendWithAsyncReply(Messages::WebProcess::SeedResourceLoadStatisticsForTesting(firstPartyDomain, thirdPartyDomain, shouldScheduleNotification), [callbackAggregator = callbackAggregator.copyRef()] { });
     2288}
    22792289#endif
    22802290
  • trunk/Source/WebKit/UIProcess/WebProcessPool.h

    r252011 r252014  
    4646#include <WebCore/CrossSiteNavigationDataTransfer.h>
    4747#include <WebCore/ProcessIdentifier.h>
    48 #include <WebCore/RegistrableDomain.h>
    4948#include <WebCore/SecurityOriginHash.h>
    5049#include <WebCore/SharedStringHash.h>
     
    9190
    9291namespace WebCore {
     92class RegistrableDomain;
    9393struct MockMediaDevice;
    9494}
     
    496496#if ENABLE(RESOURCE_LOAD_STATISTICS)
    497497    void didCommitCrossSiteLoadWithDataTransfer(PAL::SessionID, const WebCore::RegistrableDomain& fromDomain, const WebCore::RegistrableDomain& toDomain, OptionSet<WebCore::CrossSiteNavigationDataTransfer::Flag>, WebPageProxyIdentifier, WebCore::PageIdentifier);
     498    void seedResourceLoadStatisticsForTesting(const WebCore::RegistrableDomain& firstPartyDomain, const WebCore::RegistrableDomain& thirdPartyDomain, bool shouldScheduleNotification, CompletionHandler<void()>&&);
    498499#endif
    499500
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp

    r251222 r252014  
    13701370            ASSERT(processPools().size() == 1);
    13711371            break;
     1372        } else {
     1373            ASSERT_NOT_REACHED();
     1374            completionHandler(false);
     1375            break;
    13721376        }
    13731377    }
     
    19621966        resolveDirectoriesIfNecessary();
    19631967       
    1964         for (auto& processPool : processPools(std::numeric_limits<size_t>::max(), false))
     1968        for (auto& processPool : processPools(std::numeric_limits<size_t>::max(), false)) {
    19651969            processPool->sendToNetworkingProcess(Messages::NetworkProcess::SetResourceLoadStatisticsEnabled(m_sessionID, true));
    1966         return;
    1967     }
    1968 
    1969     for (auto& processPool : processPools(std::numeric_limits<size_t>::max(), false))
     1970            processPool->sendToAllProcesses(Messages::WebProcess::SetResourceLoadStatisticsEnabled(true));
     1971        }
     1972        return;
     1973    }
     1974
     1975    for (auto& processPool : processPools(std::numeric_limits<size_t>::max(), false)) {
    19701976        processPool->sendToNetworkingProcess(Messages::NetworkProcess::SetResourceLoadStatisticsEnabled(m_sessionID, false));
     1977        processPool->sendToAllProcesses(Messages::WebProcess::SetResourceLoadStatisticsEnabled(false));
     1978    }
    19711979
    19721980    m_resourceLoadStatisticsEnabled = false;
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebResourceLoadObserver.cpp

    r250579 r252014  
    6666}
    6767
     68WebResourceLoadObserver::~WebResourceLoadObserver()
     69{
     70    if (hasStatistics())
     71        updateCentralStatisticsStore();
     72}
     73
    6874void WebResourceLoadObserver::requestStorageAccessUnderOpener(const RegistrableDomain& domainInNeedOfStorageAccess, PageIdentifier openerPageID, Document& openerDocument)
    6975{
     
    357363}
    358364
     365void WebResourceLoadObserver::logSubresourceLoadingForTesting(const RegistrableDomain& firstPartyDomain, const RegistrableDomain& thirdPartyDomain, bool shouldScheduleNotification)
     366{
     367    auto& targetStatistics = ensureResourceStatisticsForRegistrableDomain(thirdPartyDomain);
     368    auto lastSeen = ResourceLoadStatistics::reduceTimeResolution(WallTime::now());
     369    targetStatistics.lastSeen = lastSeen;
     370    targetStatistics.subresourceUnderTopFrameDomains.add(firstPartyDomain);
     371
     372    if (shouldScheduleNotification)
     373        scheduleNotificationIfNeeded();
     374    else
     375        m_notificationTimer.stop();
     376}
     377
    359378} // namespace WebKit
    360379
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebResourceLoadObserver.h

    r249920 r252014  
    3838public:
    3939    WebResourceLoadObserver();
    40    
     40    ~WebResourceLoadObserver();
     41
    4142    void logSubresourceLoading(const WebCore::Frame*, const WebCore::ResourceRequest& newRequest, const WebCore::ResourceResponse& redirectResponse) final;
    4243    void logWebSocketLoading(const URL& targetURL, const URL& mainFrameURL) final;
     
    4748    void logNavigatorAPIAccessed(const WebCore::Document&, const WebCore::ResourceLoadStatistics::NavigatorAPI) final;
    4849    void logScreenAPIAccessed(const WebCore::Document&, const WebCore::ResourceLoadStatistics::ScreenAPI) final;
     50    void logSubresourceLoadingForTesting(const WebCore::RegistrableDomain& firstPartyDomain, const WebCore::RegistrableDomain& thirdPartyDomain, bool shouldScheduleNotification);
    4951
    5052#if !RELEASE_LOG_DISABLED
  • trunk/Source/WebKit/WebProcess/WebProcess.cpp

    r251814 r252014  
    459459
    460460#if ENABLE(RESOURCE_LOAD_STATISTICS)
    461     if (parameters.resourceLoadStatisticsEnabled && !parameters.sessionID.isEphemeral())
     461    if (parameters.resourceLoadStatisticsEnabled && !parameters.sessionID.isEphemeral() && !ResourceLoadObserver::sharedIfExists())
    462462        ResourceLoadObserver::setShared(*new WebResourceLoadObserver);
    463463#endif
     
    671671{
    672672    ASSERT(m_pageMap.contains(pageID));
     673
     674    flushResourceLoadStatistics();
    673675
    674676    pageWillLeaveWindow(pageID);
     
    13841386    m_processIsSuspended = true;
    13851387
     1388    flushResourceLoadStatistics();
     1389
    13861390#if PLATFORM(COCOA)
    13871391    if (m_processType == ProcessType::PrewarmedWebContent) {
     
    15531557void WebProcess::setResourceLoadStatisticsEnabled(bool enabled)
    15541558{
     1559    if (WebCore::DeprecatedGlobalSettings::resourceLoadStatisticsEnabled() == enabled || m_sessionID->isEphemeral())
     1560        return;
    15551561    WebCore::DeprecatedGlobalSettings::setResourceLoadStatisticsEnabled(enabled);
     1562#if ENABLE(RESOURCE_LOAD_STATISTICS)
     1563    if (enabled && !ResourceLoadObserver::sharedIfExists())
     1564        WebCore::ResourceLoadObserver::setShared(*new WebResourceLoadObserver);
     1565#endif
    15561566}
    15571567
     
    15621572        observer->clearState();
    15631573#endif
     1574}
     1575
     1576void WebProcess::flushResourceLoadStatistics()
     1577{
     1578#if ENABLE(RESOURCE_LOAD_STATISTICS)
     1579    if (auto* observer = ResourceLoadObserver::sharedIfExists())
     1580        observer->updateCentralStatisticsStore();
     1581#endif
     1582}
     1583
     1584void WebProcess::seedResourceLoadStatisticsForTesting(const RegistrableDomain& firstPartyDomain, const RegistrableDomain& thirdPartyDomain, bool shouldScheduleNotification, CompletionHandler<void()>&& completionHandler)
     1585{
     1586#if ENABLE(RESOURCE_LOAD_STATISTICS)
     1587    if (auto* observer = ResourceLoadObserver::sharedIfExists())
     1588        observer->logSubresourceLoadingForTesting(firstPartyDomain, thirdPartyDomain, shouldScheduleNotification);
     1589#endif
     1590    completionHandler();
    15641591}
    15651592
  • trunk/Source/WebKit/WebProcess/WebProcess.h

    r251814 r252014  
    8888class CertificateInfo;
    8989class PageGroup;
     90class RegistrableDomain;
    9091class ResourceRequest;
    9192class UserGestureToken;
     
    347348    void setResourceLoadStatisticsEnabled(bool);
    348349    void clearResourceLoadStatistics();
     350    void flushResourceLoadStatistics();
     351    void seedResourceLoadStatisticsForTesting(const WebCore::RegistrableDomain& firstPartyDomain, const WebCore::RegistrableDomain& thirdPartyDomain, bool shouldScheduleNotification, CompletionHandler<void()>&&);
    349352    void userPreferredLanguagesChanged(const Vector<String>&) const;
    350353    void fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled);
  • trunk/Source/WebKit/WebProcess/WebProcess.messages.in

    r251814 r252014  
    161161    SendMessageToWebExtension(struct WebKit::UserMessage userMessage)
    162162#endif
     163
     164#if ENABLE(RESOURCE_LOAD_STATISTICS)
     165    SeedResourceLoadStatisticsForTesting(WebCore::RegistrableDomain firstPartyDomain, WebCore::RegistrableDomain thirdPartyDomain, bool shouldScheduleNotification) -> () Async
     166#endif
    163167}
  • trunk/Tools/ChangeLog

    r252012 r252014  
     12019-11-04  John Wilander  <wilander@apple.com>
     2
     3        Resource Load Statistics: Flush the shared ResourceLoadObserver when the webpage is closed by JavaScript
     4        https://bugs.webkit.org/show_bug.cgi?id=203623
     5        <rdar://problem/56756427>
     6
     7        Reviewed by Alex Christensen.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm:
     10        (TEST):
     11
    1122019-11-04  Wenson Hsieh  <wenson_hsieh@apple.com>
    213
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm

    r248144 r252014  
    485485    EXPECT_FALSE([WKWebsiteDataStore _defaultDataStoreExists]);
    486486}
     487
     488TEST(ResourceLoadStatistics, FlushObserverWhenWebPageIsClosedByJavaScript)
     489{
     490    auto *sharedProcessPool = [WKProcessPool _sharedProcessPool];
     491    auto *dataStore = [WKWebsiteDataStore defaultDataStore];
     492
     493    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     494    [configuration setProcessPool: sharedProcessPool];
     495    configuration.get().websiteDataStore = dataStore;
     496
     497    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     498
     499    [webView loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
     500    [webView _test_waitForDidFinishNavigation];
     501
     502    [dataStore _setResourceLoadStatisticsEnabled:YES];
     503
     504    static bool doneFlag = false;
     505    [dataStore _clearResourceLoadStatistics:^(void) {
     506        doneFlag = true;
     507    }];
     508
     509    static bool statisticsUpdated = false;
     510    [dataStore _setResourceLoadStatisticsTestingCallback:^(WKWebsiteDataStore *, NSString *message) {
     511        if (![message isEqualToString:@"Statistics Updated"])
     512            return;
     513        statisticsUpdated = true;
     514    }];
     515
     516    TestWebKitAPI::Util::run(&doneFlag);
     517
     518    // Seed test data in the web process' observer.
     519    doneFlag = false;
     520    [sharedProcessPool _seedResourceLoadStatisticsForTestingWithFirstParty:[NSURL URLWithString:@"http://webkit.org"] thirdParty:[NSURL URLWithString:@"http://evil.com"] shouldScheduleNotification:NO completionHandler: ^() {
     521        doneFlag = true;
     522    }];
     523   
     524    TestWebKitAPI::Util::run(&doneFlag);
     525
     526    // Check that the third-party is not yet registered.
     527    doneFlag = false;
     528    [dataStore _isRegisteredAsSubresourceUnderFirstParty:[NSURL URLWithString:@"http://webkit.org"] thirdParty:[NSURL URLWithString:@"http://evil.com"] completionHandler: ^(BOOL isRegistered) {
     529        EXPECT_FALSE(isRegistered);
     530        doneFlag = true;
     531    }];
     532
     533    TestWebKitAPI::Util::run(&doneFlag);
     534
     535    statisticsUpdated = false;
     536    [webView loadHTMLString:@"<body><script>close();</script></body>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
     537
     538    // Wait for the statistics to be updated in the network process.
     539    TestWebKitAPI::Util::run(&statisticsUpdated);
     540
     541    // Check that the third-party is now registered.
     542    doneFlag = false;
     543    [dataStore _isRegisteredAsSubresourceUnderFirstParty:[NSURL URLWithString:@"http://webkit.org"] thirdParty:[NSURL URLWithString:@"http://evil.com"] completionHandler: ^(BOOL isRegistered) {
     544        EXPECT_TRUE(isRegistered);
     545        doneFlag = true;
     546    }];
     547
     548    TestWebKitAPI::Util::run(&doneFlag);
     549}
Note: See TracChangeset for help on using the changeset viewer.