https://bugs.webkit.org/show_bug.cgi?id=175090
<rdar://problem/
33685546>
Reviewed by Chris Dumez.
Source/WebCore:
Test: http/tests/loading/resourceLoadStatistics/user-interaction-only-reported-once-within-short-period-of-time.html
* loader/ResourceLoadObserver.cpp:
(WebCore::ResourceLoadObserver::ResourceLoadObserver):
(WebCore::ResourceLoadObserver::logUserInteractionWithReducedTimeResolution):
Now tells the UI process immediately but also records that it has
done so to avoid doing it when not needed.
(WebCore::ResourceLoadObserver::scheduleNotificationIfNeeded):
Conditional throttling gone, now always throttles.
(WebCore::ResourceLoadObserver::notifyObserver):
Renamed from ResourceLoadObserver::notificationTimerFired().
(WebCore::ResourceLoadObserver::clearState):
New function to allow the test runner to reset the web process'
statistics state now that we keep track of whether or not we've
reported user interaction to the UI process.
(WebCore::ResourceLoadObserver::setShouldThrottleObserverNotifications): Deleted.
(WebCore::ResourceLoadObserver::notificationTimerFired): Deleted.
* loader/ResourceLoadObserver.h:
(): Deleted.
* testing/Internals.cpp:
(WebCore::Internals::resetToConsistentState):
(WebCore::Internals::setResourceLoadStatisticsShouldThrottleObserverNotifications): Deleted.
No longer needed since user interaction is always communicated
immediately.
* testing/Internals.h:
* testing/Internals.idl:
Source/WebKit:
* WebProcess/InjectedBundle/API/c/WKBundle.cpp:
(WKBundleClearResourceLoadStatistics):
Test infrastructure. Ends up calling
WebCore::ResourceLoadObserver::clearState().
* WebProcess/InjectedBundle/API/c/WKBundlePrivate.h:
Tools:
* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::beginTesting):
Now calls WebCore::ResourceLoadObserver::clearState().
LayoutTests:
* http/tests/loading/resourceLoadStatistics/user-interaction-in-cross-origin-sub-frame.html:
Now no longer needs to disable throttling since reports of
user interaction happen immediately (when needed).
* http/tests/loading/resourceLoadStatistics/user-interaction-only-reported-once-within-short-period-of-time-expected.txt: Added.
* http/tests/loading/resourceLoadStatistics/user-interaction-only-reported-once-within-short-period-of-time.html: Added.
* platform/mac-wk2/TestExpectations:
user-interaction-only-reported-once-within-short-period-of-time.html marked as [ Pass ].
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220302
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2017-08-04 John Wilander <wilander@apple.com>
+
+ Resource Load Statistics: Report user interaction immediately, but only when needed
+ https://bugs.webkit.org/show_bug.cgi?id=175090
+ <rdar://problem/33685546>
+
+ Reviewed by Chris Dumez.
+
+ * http/tests/loading/resourceLoadStatistics/user-interaction-in-cross-origin-sub-frame.html:
+ Now no longer needs to disable throttling since reports of
+ user interaction happen immediately (when needed).
+ * http/tests/loading/resourceLoadStatistics/user-interaction-only-reported-once-within-short-period-of-time-expected.txt: Added.
+ * http/tests/loading/resourceLoadStatistics/user-interaction-only-reported-once-within-short-period-of-time.html: Added.
+ * platform/mac-wk2/TestExpectations:
+ user-interaction-only-reported-once-within-short-period-of-time.html marked as [ Pass ].
+
2017-08-04 Matt Baker <mattbaker@apple.com>
Web Inspector: capture async stack trace when workers/main context posts a message
}
onload = function() {
- if (internals) {
+ if (internals)
internals.setResourceLoadStatisticsEnabled(true);
- internals.setResourceLoadStatisticsShouldThrottleObserverNotifications(false);
- }
if (testRunner) {
testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
--- /dev/null
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+main frame - didHandleOnloadEventsForFrame
+main frame - didFinishLoadForFrame
+Tests that user interaction is not reported repeatedly within a short period of time.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.location.origin is topFrameOrigin
+PASS testRunner.isStatisticsHasHadUserInteraction(topFrameOrigin) is false
+PASS testRunner.isStatisticsHasHadUserInteraction(subFrameOrigin) is false
+PASS testRunner.isStatisticsHasHadUserInteraction(topFrameOrigin) is true
+PASS testRunner.isStatisticsHasHadUserInteraction(subFrameOrigin) is false
+PASS testRunner.isStatisticsHasHadUserInteraction(topFrameOrigin) is false
+PASS testRunner.isStatisticsHasHadUserInteraction(topFrameOrigin) is false
+PASS testRunner.isStatisticsHasHadUserInteraction(subFrameOrigin) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+This is the test element
--- /dev/null
+<!DOCTYPE html>
+<html>
+<body>
+<script src="/js-test-resources/js-test.js"></script>
+<script src="/js-test-resources/ui-helper.js"></script>
+<script>
+ description("Tests that user interaction is not reported repeatedly within a short period of time.");
+ jsTestIsAsync = true;
+
+ const topFrameOrigin = "http://127.0.0.1:8000";
+ const subFrameOrigin = "http://localhost:8000";
+
+ function activateElement(elementId, callback) {
+ var element = document.getElementById(elementId);
+ var centerX = element.offsetLeft + element.offsetWidth / 2;
+ var centerY = element.offsetTop + element.offsetHeight / 2;
+ UIHelper.activateAt(centerX, centerY).then(
+ function() {
+ callback();
+ },
+ function() {
+ testFailed("Promise rejected.");
+ finishJSTest();
+ }
+ );
+ }
+
+ function firstInteraction() {
+ shouldBeFalse("testRunner.isStatisticsHasHadUserInteraction(topFrameOrigin)");
+ shouldBeFalse("testRunner.isStatisticsHasHadUserInteraction(subFrameOrigin)");
+ activateElement("testElement", secondInteraction);
+ }
+
+ function secondInteraction() {
+ shouldBeTrue("testRunner.isStatisticsHasHadUserInteraction(topFrameOrigin)");
+ shouldBeFalse("testRunner.isStatisticsHasHadUserInteraction(subFrameOrigin)");
+
+ if (testRunner)
+ testRunner.setStatisticsHasHadUserInteraction(topFrameOrigin, false);
+
+ shouldBeFalse("testRunner.isStatisticsHasHadUserInteraction(topFrameOrigin)");
+
+ activateElement("testElement", finishTest);
+ }
+
+ function finishTest() {
+ shouldBeFalse("testRunner.isStatisticsHasHadUserInteraction(topFrameOrigin)");
+ shouldBeFalse("testRunner.isStatisticsHasHadUserInteraction(subFrameOrigin)");
+
+ finishJSTest();
+ }
+
+ onload = function() {
+ if (internals)
+ internals.setResourceLoadStatisticsEnabled(true);
+
+ shouldBe("document.location.origin", "topFrameOrigin");
+
+ firstInteraction();
+ };
+</script>
+<div id="testElement">This is the test element</div>
+</body>
+</html>
\ No newline at end of file
webkit.org/b/172397 [ Sierra Debug ] animations/needs-layout.html [ Pass ImageOnlyFailure ]
-# Currently only tests with click, not tap.
+# Move to general wk2 expectations once webkit.org/b/175170 is resolved.
http/tests/loading/resourceLoadStatistics/user-interaction-in-cross-origin-sub-frame.html [ Pass ]
+http/tests/loading/resourceLoadStatistics/user-interaction-only-reported-once-within-short-period-of-time.html [ Pass ]
webkit.org/b/173861 [ Release ] http/tests/webrtc/filtering-ice-candidate-same-origin-frame.html [ Pass Timeout ]
webkit.org/b/173861 [ Release ] http/tests/webrtc/filtering-ice-candidate-cross-origin-frame.html [ Pass Timeout ]
+2017-08-04 John Wilander <wilander@apple.com>
+
+ Resource Load Statistics: Report user interaction immediately, but only when needed
+ https://bugs.webkit.org/show_bug.cgi?id=175090
+ <rdar://problem/33685546>
+
+ Reviewed by Chris Dumez.
+
+ Test: http/tests/loading/resourceLoadStatistics/user-interaction-only-reported-once-within-short-period-of-time.html
+
+ * loader/ResourceLoadObserver.cpp:
+ (WebCore::ResourceLoadObserver::ResourceLoadObserver):
+ (WebCore::ResourceLoadObserver::logUserInteractionWithReducedTimeResolution):
+ Now tells the UI process immediately but also records that it has
+ done so to avoid doing it when not needed.
+ (WebCore::ResourceLoadObserver::scheduleNotificationIfNeeded):
+ Conditional throttling gone, now always throttles.
+ (WebCore::ResourceLoadObserver::notifyObserver):
+ Renamed from ResourceLoadObserver::notificationTimerFired().
+ (WebCore::ResourceLoadObserver::clearState):
+ New function to allow the test runner to reset the web process'
+ statistics state now that we keep track of whether or not we've
+ reported user interaction to the UI process.
+ (WebCore::ResourceLoadObserver::setShouldThrottleObserverNotifications): Deleted.
+ (WebCore::ResourceLoadObserver::notificationTimerFired): Deleted.
+ * loader/ResourceLoadObserver.h:
+ (): Deleted.
+ * testing/Internals.cpp:
+ (WebCore::Internals::resetToConsistentState):
+ (WebCore::Internals::setResourceLoadStatisticsShouldThrottleObserverNotifications): Deleted.
+ No longer needed since user interaction is always communicated
+ immediately.
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2017-08-04 Matt Baker <mattbaker@apple.com>
Web Inspector: capture async stack trace when workers/main context posts a message
return firstMetaDomainIdentifier == metaDomainIdentifiers.get().get(secondDomain);
}
-void ResourceLoadObserver::setShouldThrottleObserverNotifications(bool shouldThrottle)
-{
- m_shouldThrottleNotifications = shouldThrottle;
-
- if (!m_notificationTimer.isActive())
- return;
-
- // If we change the notification state, we need to restart any notifications
- // so they will be on the right schedule.
- m_notificationTimer.stop();
- scheduleNotificationIfNeeded();
-}
-
void ResourceLoadObserver::setNotificationCallback(WTF::Function<void (Vector<ResourceLoadStatistics>&&)>&& notificationCallback)
{
ASSERT(!m_notificationCallback);
}
ResourceLoadObserver::ResourceLoadObserver()
- : m_notificationTimer(*this, &ResourceLoadObserver::notificationTimerFired)
+ : m_notificationTimer(*this, &ResourceLoadObserver::notifyObserver)
{
}
if (url.isBlankURL() || url.isEmpty())
return;
- auto& statistics = ensureResourceStatisticsForPrimaryDomain(primaryDomain(url));
+ auto domain = primaryDomain(url);
auto newTime = reduceToHourlyTimeResolution(WallTime::now());
- if (newTime == statistics.mostRecentUserInteractionTime)
+ auto lastReportedUserInteraction = m_lastReportedUserInteractionMap.get(domain);
+ if (newTime == lastReportedUserInteraction)
return;
+ m_lastReportedUserInteractionMap.set(domain, newTime);
+
+ auto& statistics = ensureResourceStatisticsForPrimaryDomain(domain);
statistics.hadUserInteraction = true;
statistics.lastSeen = newTime;
statistics.mostRecentUserInteractionTime = newTime;
- scheduleNotificationIfNeeded();
+ m_notificationTimer.stop();
+ notifyObserver();
}
ResourceLoadStatistics& ResourceLoadObserver::ensureResourceStatisticsForPrimaryDomain(const String& primaryDomain)
}
if (!m_notificationTimer.isActive())
- m_notificationTimer.startOneShot(m_shouldThrottleNotifications ? minimumNotificationInterval : 0_s);
+ m_notificationTimer.startOneShot(minimumNotificationInterval);
}
-void ResourceLoadObserver::notificationTimerFired()
+void ResourceLoadObserver::notifyObserver()
{
ASSERT(m_notificationCallback);
+ m_notificationTimer.stop();
m_notificationCallback(takeStatistics());
}
return statistics;
}
+void ResourceLoadObserver::clearState()
+{
+ m_notificationTimer.stop();
+ m_resourceStatisticsMap.clear();
+ m_lastReportedUserInteractionMap.clear();
+}
+
} // namespace WebCore
namespace WTF {
class Lock;
class WorkQueue;
+class WallTime;
}
namespace WebCore {
WEBCORE_EXPORT void setNotificationCallback(WTF::Function<void (Vector<ResourceLoadStatistics>&&)>&&);
+ WEBCORE_EXPORT void clearState();
private:
ResourceLoadObserver();
ResourceLoadStatistics& ensureResourceStatisticsForPrimaryDomain(const String&);
void scheduleNotificationIfNeeded();
- void notificationTimerFired();
+ void notifyObserver();
Vector<ResourceLoadStatistics> takeStatistics();
HashMap<String, ResourceLoadStatistics> m_resourceStatisticsMap;
+ HashMap<String, WTF::WallTime> m_lastReportedUserInteractionMap;
WTF::Function<void (Vector<ResourceLoadStatistics>&&)> m_notificationCallback;
Timer m_notificationTimer;
- bool m_shouldThrottleNotifications { true };
};
} // namespace WebCore
#if USE(LIBWEBRTC)
WebCore::useRealRTCPeerConnectionFactory();
#endif
-
- ResourceLoadObserver::shared().setShouldThrottleObserverNotifications(true);
}
Internals::Internals(Document& document)
Settings::setResourceLoadStatisticsEnabled(enable);
}
-void Internals::setResourceLoadStatisticsShouldThrottleObserverNotifications(bool enable)
-{
- ResourceLoadObserver::shared().setShouldThrottleObserverNotifications(enable);
-}
-
String Internals::composedTreeAsText(Node& node)
{
if (!is<ContainerNode>(node))
String resourceLoadStatisticsForOrigin(const String& origin);
void setResourceLoadStatisticsEnabled(bool);
- void setResourceLoadStatisticsShouldThrottleObserverNotifications(bool);
#if ENABLE(STREAMS_API)
bool isReadableStreamDisturbed(JSC::ExecState&, JSC::JSValue);
DOMString resourceLoadStatisticsForOrigin(DOMString domain);
void setResourceLoadStatisticsEnabled(boolean enable);
- void setResourceLoadStatisticsShouldThrottleObserverNotifications(boolean enable);
[MayThrowException] void setCanShowModalDialogOverride(boolean allow);
+2017-08-04 John Wilander <wilander@apple.com>
+
+ Resource Load Statistics: Report user interaction immediately, but only when needed
+ https://bugs.webkit.org/show_bug.cgi?id=175090
+ <rdar://problem/33685546>
+
+ Reviewed by Chris Dumez.
+
+ * WebProcess/InjectedBundle/API/c/WKBundle.cpp:
+ (WKBundleClearResourceLoadStatistics):
+ Test infrastructure. Ends up calling
+ WebCore::ResourceLoadObserver::clearState().
+ * WebProcess/InjectedBundle/API/c/WKBundlePrivate.h:
+
2017-08-04 Matt Lewis <jlewis3@apple.com>
Unreviewed, rolling out r220288.
#include "WebPage.h"
#include "WebPageGroupProxy.h"
#include <WebCore/DatabaseTracker.h>
+#include <WebCore/ResourceLoadObserver.h>
using namespace WebCore;
using namespace WebKit;
{
toImpl(bundleRef)->setTabKeyCyclesThroughElements(toImpl(pageRef), enabled);
}
+
+void WKBundleClearResourceLoadStatistics(WKBundleRef)
+{
+ ResourceLoadObserver::shared().clearState();
+}
WK_EXPORT void WKBundleSetTabKeyCyclesThroughElements(WKBundleRef bundle, WKBundlePageRef page, bool enabled);
+WK_EXPORT void WKBundleClearResourceLoadStatistics(WKBundleRef);
+
#ifdef __cplusplus
}
#endif
+2017-08-04 John Wilander <wilander@apple.com>
+
+ Resource Load Statistics: Report user interaction immediately, but only when needed
+ https://bugs.webkit.org/show_bug.cgi?id=175090
+ <rdar://problem/33685546>
+
+ Reviewed by Chris Dumez.
+
+ * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+ (WTR::InjectedBundle::beginTesting):
+ Now calls WebCore::ResourceLoadObserver::clearState().
+
2017-08-04 Tim Horton <timothy_horton@apple.com>
Add an API test for r220286
WKBundleClearAllDatabases(m_bundle);
WKBundlePageClearApplicationCache(page()->page());
WKBundleResetOriginAccessWhitelists(m_bundle);
+ WKBundleClearResourceLoadStatistics(m_bundle);
// [WK2] REGRESSION(r128623): It made layout tests extremely slow
// https://bugs.webkit.org/show_bug.cgi?id=96862