Diff
Modified: trunk/LayoutTests/ChangeLog (235896 => 235897)
--- trunk/LayoutTests/ChangeLog 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/LayoutTests/ChangeLog 2018-09-11 17:14:07 UTC (rev 235897)
@@ -1,3 +1,25 @@
+2018-09-11 Woodrow Wang <[email protected]>
+
+ Add Web API Statistics Collection
+ https://bugs.webkit.org/show_bug.cgi?id=187773
+ <rdar://problem/44155162>
+
+ Reviewed by Brent Fulgham.
+
+ Added new tests and expectations for the web API statistics data collection.
+
+ * TestExpectations:
+ * http/tests/webAPIStatistics/canvas-read-and-write-data-collection-expected.txt: Added.
+ * http/tests/webAPIStatistics/canvas-read-and-write-data-collection.html: Added.
+ * http/tests/webAPIStatistics/font-load-data-collection-expected.txt: Added.
+ * http/tests/webAPIStatistics/font-load-data-collection.html: Added.
+ * http/tests/webAPIStatistics/navigator-functions-accessed-data-collection-expected.txt: Added.
+ * http/tests/webAPIStatistics/navigator-functions-accessed-data-collection.html: Added.
+ * http/tests/webAPIStatistics/screen-functions-accessed-data-collection-expected.txt: Added.
+ * http/tests/webAPIStatistics/screen-functions-accessed-data-collection.html: Added.
+ * platform/ios-wk2/TestExpectations:
+ * platform/mac-wk2/TestExpectations:
+
2018-09-11 Frederic Wang <[email protected]>
Modify more tests to use document.scrollingElement to access viewport scroll properties
Modified: trunk/LayoutTests/TestExpectations (235896 => 235897)
--- trunk/LayoutTests/TestExpectations 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/LayoutTests/TestExpectations 2018-09-11 17:14:07 UTC (rev 235897)
@@ -2245,3 +2245,5 @@
fast/gradients/conic-center-outside-box.html [ Skip ]
fast/gradients/conic-extended-stops.html [ Skip ]
fast/gradients/conic-from-angle.html [ Skip ]
+
+webkit.org/b/187773 http/tests/webAPIStatistics [ Skip ]
Added: trunk/LayoutTests/http/tests/webAPIStatistics/canvas-read-and-write-data-collection-expected.txt (0 => 235897)
--- trunk/LayoutTests/http/tests/webAPIStatistics/canvas-read-and-write-data-collection-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/webAPIStatistics/canvas-read-and-write-data-collection-expected.txt 2018-09-11 17:14:07 UTC (rev 235897)
@@ -0,0 +1,30 @@
+Tests for canvas read and write data collection in ResourceLoadStatistics plist by rendering and reading text on the canvas and dumping the entire resource load statistics map.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+Resource load statistics:
+
+High level domain: 127.0.0.1
+ lastSeen: 0
+ hadUserInteraction: No
+ mostRecentUserInteraction: -1
+ grandfathered: No
+ isPrevalentResource: No
+ isVeryPrevalentResource: No
+ dataRecordsRemoved: 0
+ isMarkedForCookieBlocking: No
+ fontsSuccessfullyLoaded:
+ Helvetica
+ Times
+ Courier
+ topFrameRegistrableDomainsWhichAccessedWebAPIs:
+ 127.0.0.1: 8
+ canvasTextWritten:
+ suspicious invisible text
+ canvasReadData: Yes
+
Added: trunk/LayoutTests/http/tests/webAPIStatistics/canvas-read-and-write-data-collection.html (0 => 235897)
--- trunk/LayoutTests/http/tests/webAPIStatistics/canvas-read-and-write-data-collection.html (rev 0)
+++ trunk/LayoutTests/http/tests/webAPIStatistics/canvas-read-and-write-data-collection.html 2018-09-11 17:14:07 UTC (rev 235897)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<head>
+ <meta charset="UTF-8">
+ <title>Test for canvas read and write data collection in resource load statistics</title>
+ <script src=""
+</head>
+<body>
+<script>
+ description("Tests for canvas read and write data collection in ResourceLoadStatistics plist by rendering and reading text on the canvas and dumping the entire resource load statistics map.");
+ const hostUnderTest = "127.0.0.1:8000";
+ const statisticsUrl = "http://" + hostUnderTest + "/temp";
+
+ function completeTest() {
+ testRunner.dumpResourceLoadStatistics();
+
+ testRunner.statisticsResetToConsistentState(function() {
+ testRunner.notifyDone();
+ });
+ }
+
+ function runTestRunnerTest() {
+ testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
+
+ testRunner.installStatisticsDidScanDataRecordsCallback(completeTest);
+
+ var canvas = document.createElement('canvas');
+ var context = canvas.getContext('2d');
+ context.fillText('suspicious invisible text', 2, 15);
+ canvas.toDataURL();
+ }
+
+ if (document.location.host === hostUnderTest && window.testRunner && window.internals) {
+ testRunner.waitUntilDone();
+ internals.setResourceLoadStatisticsEnabled(true);
+ testRunner.setWebAPIStatisticsEnabled(true);
+ runTestRunnerTest();
+ }
+</script>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/http/tests/webAPIStatistics/font-load-data-collection-expected.txt (0 => 235897)
--- trunk/LayoutTests/http/tests/webAPIStatistics/font-load-data-collection-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/webAPIStatistics/font-load-data-collection-expected.txt 2018-09-11 17:14:07 UTC (rev 235897)
@@ -0,0 +1,31 @@
+Tests for font loading data collection in ResourceLoadStatistics plist by loading fonts and dumping the entire resource load statistics map. The test tries to load various fonts through a comma separated font-family list to draw a string with many m's since they differ in width more prominently among fonts.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+mmmmmmmmmmlli
+Resource load statistics:
+
+High level domain: 127.0.0.1
+ lastSeen: 0
+ hadUserInteraction: No
+ mostRecentUserInteraction: -1
+ grandfathered: No
+ isPrevalentResource: No
+ isVeryPrevalentResource: No
+ dataRecordsRemoved: 0
+ isMarkedForCookieBlocking: No
+ fontsFailedToLoad:
+ Fransiscan
+ Andale
+ notARealFont
+ fontsSuccessfullyLoaded:
+ Times
+ Courier
+ topFrameRegistrableDomainsWhichAccessedWebAPIs:
+ 127.0.0.1: 9
+ canvasReadData: No
+
Added: trunk/LayoutTests/http/tests/webAPIStatistics/font-load-data-collection.html (0 => 235897)
--- trunk/LayoutTests/http/tests/webAPIStatistics/font-load-data-collection.html (rev 0)
+++ trunk/LayoutTests/http/tests/webAPIStatistics/font-load-data-collection.html 2018-09-11 17:14:07 UTC (rev 235897)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<head>
+ <meta charset="UTF-8">
+ <title>Test for font loading data collection in resource load statistics</title>
+ <script src=""
+</head>
+<body>
+<script>
+ description("Tests for font loading data collection in ResourceLoadStatistics plist by loading fonts and dumping the entire resource load statistics map. The test tries to load various fonts through a comma separated font-family list to draw a string with many m's since they differ in width more prominently among fonts.");
+ const hostUnderTest = "127.0.0.1:8000";
+ const statisticsUrl = "http://" + hostUnderTest + "/temp";
+
+ function completeTest() {
+ testRunner.dumpResourceLoadStatistics();
+
+ testRunner.statisticsResetToConsistentState(function() {
+ testRunner.notifyDone();
+ });
+ }
+
+ function runTestRunnerTest() {
+ testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
+
+ testRunner.installStatisticsDidScanDataRecordsCallback(completeTest);
+
+ var body = document.getElementsByTagName('body')[0]
+
+ var span = document.createElement('span');
+ var testFontString = 'mmmmmmmmmmlli';
+
+ span.innerHTML = testFontString;
+ span.style.fontFamily = 'Andale, Fransiscan, notARealFont, serif';
+ body.appendChild(span);
+ }
+
+ if (document.location.host === hostUnderTest && window.testRunner && window.internals) {
+ testRunner.waitUntilDone();
+ internals.setResourceLoadStatisticsEnabled(true);
+ testRunner.setWebAPIStatisticsEnabled(true);
+ runTestRunnerTest();
+ }
+</script>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/http/tests/webAPIStatistics/navigator-functions-accessed-data-collection-expected.txt (0 => 235897)
--- trunk/LayoutTests/http/tests/webAPIStatistics/navigator-functions-accessed-data-collection-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/webAPIStatistics/navigator-functions-accessed-data-collection-expected.txt 2018-09-11 17:14:07 UTC (rev 235897)
@@ -0,0 +1,34 @@
+Tests for navigator functions accessed data collection in ResourceLoadStatistics plist by querying for all the navigator properties and dumping the entire resource load statistics map.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+Resource load statistics:
+
+High level domain: 127.0.0.1
+ lastSeen: 0
+ hadUserInteraction: No
+ mostRecentUserInteraction: -1
+ grandfathered: No
+ isPrevalentResource: No
+ isVeryPrevalentResource: No
+ dataRecordsRemoved: 0
+ isMarkedForCookieBlocking: No
+ fontsSuccessfullyLoaded:
+ Times
+ Courier
+ topFrameRegistrableDomainsWhichAccessedWebAPIs:
+ 127.0.0.1: 12
+ navigatorFunctionsAccessed:
+ appVersion
+ userAgent
+ plugins
+ mimeTypes
+ cookieEnabled
+ javaEnabled
+ canvasReadData: No
+
Added: trunk/LayoutTests/http/tests/webAPIStatistics/navigator-functions-accessed-data-collection.html (0 => 235897)
--- trunk/LayoutTests/http/tests/webAPIStatistics/navigator-functions-accessed-data-collection.html (rev 0)
+++ trunk/LayoutTests/http/tests/webAPIStatistics/navigator-functions-accessed-data-collection.html 2018-09-11 17:14:07 UTC (rev 235897)
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<head>
+ <meta charset="UTF-8">
+ <title>Test for navigator functions accessed data collection in resource load statistics</title>
+ <script src=""
+</head>
+<body>
+<script>
+ description("Tests for navigator functions accessed data collection in ResourceLoadStatistics plist by querying for all the navigator properties and dumping the entire resource load statistics map.");
+ const hostUnderTest = "127.0.0.1:8000";
+ const statisticsUrl = "http://" + hostUnderTest + "/temp";
+
+ function completeTest() {
+ testRunner.dumpResourceLoadStatistics();
+
+ testRunner.statisticsResetToConsistentState(function() {
+ testRunner.notifyDone();
+ });
+ }
+
+ function runTestRunnerTest() {
+ testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
+
+ testRunner.installStatisticsDidScanDataRecordsCallback(completeTest);
+
+ var useragent = navigator.userAgent;
+ var javaenabled = navigator.javaEnabled();
+ var cookieEnabled = navigator.cookieEnabled;
+ var mimetypes = navigator.mimeTypes;
+ var plugins = navigator.plugins;
+ var appversion = navigator.appVersion;
+ }
+
+ if (document.location.host === hostUnderTest && window.testRunner && window.internals) {
+ testRunner.waitUntilDone();
+ internals.setResourceLoadStatisticsEnabled(true);
+ testRunner.setWebAPIStatisticsEnabled(true);
+ runTestRunnerTest();
+ }
+</script>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/http/tests/webAPIStatistics/screen-functions-accessed-data-collection-expected.txt (0 => 235897)
--- trunk/LayoutTests/http/tests/webAPIStatistics/screen-functions-accessed-data-collection-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/webAPIStatistics/screen-functions-accessed-data-collection-expected.txt 2018-09-11 17:14:07 UTC (rev 235897)
@@ -0,0 +1,36 @@
+Tests for screen functions accessed data collection in ResourceLoadStatistics plist by querying for all the screen properties and dumping the entire resource load statistics map.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+Resource load statistics:
+
+High level domain: 127.0.0.1
+ lastSeen: 0
+ hadUserInteraction: No
+ mostRecentUserInteraction: -1
+ grandfathered: No
+ isPrevalentResource: No
+ isVeryPrevalentResource: No
+ dataRecordsRemoved: 0
+ isMarkedForCookieBlocking: No
+ fontsSuccessfullyLoaded:
+ Times
+ Courier
+ topFrameRegistrableDomainsWhichAccessedWebAPIs:
+ 127.0.0.1: 13
+ screenFunctionsAccessed:
+ height
+ width
+ colorDepth
+ pixelDepth
+ availLeft
+ availTop
+ availHeight
+ availWidth
+ canvasReadData: No
+
Added: trunk/LayoutTests/http/tests/webAPIStatistics/screen-functions-accessed-data-collection.html (0 => 235897)
--- trunk/LayoutTests/http/tests/webAPIStatistics/screen-functions-accessed-data-collection.html (rev 0)
+++ trunk/LayoutTests/http/tests/webAPIStatistics/screen-functions-accessed-data-collection.html 2018-09-11 17:14:07 UTC (rev 235897)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<head>
+ <meta charset="UTF-8">
+ <title>Test for screen functions accessed data collection in resource load statistics</title>
+ <script src=""
+</head>
+<body>
+<script>
+ description("Tests for screen functions accessed data collection in ResourceLoadStatistics plist by querying for all the screen properties and dumping the entire resource load statistics map.");
+ const hostUnderTest = "127.0.0.1:8000";
+ const statisticsUrl = "http://" + hostUnderTest + "/temp";
+
+ function completeTest() {
+ testRunner.dumpResourceLoadStatistics();
+
+ testRunner.statisticsResetToConsistentState(function() {
+ testRunner.notifyDone();
+ });
+ }
+
+ function runTestRunnerTest() {
+ testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
+
+ testRunner.installStatisticsDidScanDataRecordsCallback(completeTest);
+
+ var availTop = screen.availTop;
+ var colorDepth = screen.colorDepth;
+ var pixelDepth = screen.pixelDepth;
+ var height = screen.height;
+ var width = screen.width;
+ var availLeft = screen.availLeft;
+ var availHeight = screen.availHeight;
+ var availWidth = screen.availWidth;
+ }
+
+ if (document.location.host === hostUnderTest && window.testRunner && window.internals) {
+ testRunner.waitUntilDone();
+ internals.setResourceLoadStatisticsEnabled(true);
+ testRunner.setWebAPIStatisticsEnabled(true);
+ runTestRunnerTest();
+ }
+</script>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/LayoutTests/platform/ios-wk2/TestExpectations (235896 => 235897)
--- trunk/LayoutTests/platform/ios-wk2/TestExpectations 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/LayoutTests/platform/ios-wk2/TestExpectations 2018-09-11 17:14:07 UTC (rev 235897)
@@ -50,6 +50,8 @@
http/tests/security/contentSecurityPolicy/manifest-src-blocked.html [ Pass ]
applicationmanifest/ [ Pass ]
+webkit.org/b/187773 http/tests/webAPIStatistics [ Pass ]
+
#//////////////////////////////////////////////////////////////////////////////////////////
# End platform-specific directories.
#//////////////////////////////////////////////////////////////////////////////////////////
Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (235896 => 235897)
--- trunk/LayoutTests/platform/mac-wk2/TestExpectations 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations 2018-09-11 17:14:07 UTC (rev 235897)
@@ -57,6 +57,8 @@
fast/misc/valid-primary-screen-displayID.html [ Pass ]
+webkit.org/b/187773 http/tests/webAPIStatistics [ Pass ]
+
#//////////////////////////////////////////////////////////////////////////////////////////
# End platform-specific directories.
#//////////////////////////////////////////////////////////////////////////////////////////
Modified: trunk/Source/WebCore/ChangeLog (235896 => 235897)
--- trunk/Source/WebCore/ChangeLog 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/ChangeLog 2018-09-11 17:14:07 UTC (rev 235897)
@@ -1,3 +1,114 @@
+2018-09-11 Woodrow Wang <[email protected]>
+
+ Add Web API Statistics Collection
+ https://bugs.webkit.org/show_bug.cgi?id=187773
+ <rdar://problem/44155162>
+
+ Reviewed by Brent Fulgham.
+
+ Added data collection for web API statistics, specifically regarding the canvas, font loads,
+ screen functions, and navigator functions. The data collection code is placed under a runtime
+ enabled feature flag. The statistics are stored in a ResourceLoadStatistics object and written
+ to a plist on disk. Added a new file CanvasActivityRecord.h and CanvasActivityRecord.cpp which
+ includes a struct to keep track of HTML5 canvas element read and writes.
+
+ Tests: http/tests/webAPIStatistics/canvas-read-and-write-data-collection.html
+ http/tests/webAPIStatistics/font-load-data-collection.html
+ http/tests/webAPIStatistics/navigator-functions-accessed-data-collection.html
+ http/tests/webAPIStatistics/screen-functions-accessed-data-collection.html
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * css/CSSFontFaceSource.cpp:
+ (WebCore::CSSFontFaceSource::load):
+ * css/CSSFontSelector.cpp:
+ (WebCore::CSSFontSelector::fontRangesForFamily):
+ (WebCore::CSSFontSelector::fallbackFontAt):
+
+ The following are the functions where we'd like to record a canvas read.
+
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::toDataURL):
+ (WebCore::HTMLCanvasElement::toBlob):
+ (WebCore::HTMLCanvasElement::getImageData):
+ (WebCore::HTMLCanvasElement::toMediaSample):
+ (WebCore::HTMLCanvasElement::captureStream):
+
+ The following are the functions where we'd like to record a canvas write.
+
+ * html/canvas/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::measureText):
+ (WebCore::CanvasRenderingContext2D::drawTextInternal):
+
+ The following files and functions handle the CanvasActivityRecord struct and
+ its respective functions.
+
+ * loader/CanvasActivityRecord.cpp: Added.
+ (WebCore::CanvasActivityRecord::recordWrittenOrMeasuredText):
+ (WebCore::CanvasActivityRecord::mergeWith):
+ * loader/CanvasActivityRecord.h: Added.
+ (WebCore::CanvasActivityRecord::encode const):
+ (WebCore::CanvasActivityRecord::decode):
+
+ * loader/DocumentThreadableLoader.cpp:
+ * loader/FrameLoader.cpp:
+ * loader/ResourceLoadObserver.cpp:
+ (WebCore::ResourceLoadObserver::logFontLoad):
+ (WebCore::ResourceLoadObserver::logCanvasRead):
+ (WebCore::ResourceLoadObserver::logCanvasWriteOrMeasure):
+ (WebCore::ResourceLoadObserver::logNavigatorAPIAccessed):
+ (WebCore::ResourceLoadObserver::logScreenAPIAccessed):
+
+ Before, entries in the ResourceLoadStatistics involving HashSets used "origin" as the key.
+ Now the encodeHashSet function has been generalized to take any key to encode the entries
+ in the HashSet. Also added functionality to encode an OptionSet by converting it to its
+ raw bitmask state.
+
+ * loader/ResourceLoadObserver.h:
+ * loader/ResourceLoadStatistics.cpp:
+ (WebCore::encodeHashSet):
+ (WebCore::encodeOriginHashSet):
+ (WebCore::encodeOptionSet):
+ (WebCore::encodeFontHashSet):
+ (WebCore::encodeCanvasActivityRecord):
+ (WebCore::ResourceLoadStatistics::encode const):
+ (WebCore::decodeHashSet):
+ (WebCore::decodeOriginHashSet):
+ (WebCore::decodeOptionSet):
+ (WebCore::decodeFontHashSet):
+ (WebCore::decodeCanvasActivityRecord):
+ (WebCore::ResourceLoadStatistics::decode):
+ (WebCore::navigatorAPIEnumToString):
+ (WebCore::screenAPIEnumToString):
+ (WebCore::appendNavigatorAPIOptionSet):
+ (WebCore::appendScreenAPIOptionSet):
+ (WebCore::ResourceLoadStatistics::toString const):
+ (WebCore::ResourceLoadStatistics::merge):
+ * loader/ResourceLoadStatistics.h:
+ * loader/ResourceTiming.cpp:
+
+ The following are the navigator functions recorded for the web API statistics.
+
+ * page/Navigator.cpp:
+ (WebCore::Navigator::appVersion const):
+ (WebCore::Navigator::userAgent const):
+ (WebCore::Navigator::plugins):
+ (WebCore::Navigator::mimeTypes):
+ (WebCore::Navigator::cookieEnabled const):
+ (WebCore::Navigator::javaEnabled const):
+
+ The following are the screen functions recorded for the web API statistics.
+
+ * page/Screen.cpp:
+ (WebCore::Screen::height const):
+ (WebCore::Screen::width const):
+ (WebCore::Screen::colorDepth const):
+ (WebCore::Screen::pixelDepth const):
+ (WebCore::Screen::availLeft const):
+ (WebCore::Screen::availTop const):
+ (WebCore::Screen::availHeight const):
+ (WebCore::Screen::availWidth const):
+
2018-09-11 Pablo Saavedra <[email protected]>
playbackControlsManagerUpdateTimerFired and
Modified: trunk/Source/WebCore/Sources.txt (235896 => 235897)
--- trunk/Source/WebCore/Sources.txt 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/Sources.txt 2018-09-11 17:14:07 UTC (rev 235897)
@@ -1247,6 +1247,7 @@
layout/layouttree/LayoutReplaced.cpp
layout/layouttree/LayoutTreeBuilder.cpp
+loader/CanvasActivityRecord.cpp
loader/ContentFilter.cpp
loader/CookieJar.cpp
loader/CrossOriginAccessControl.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (235896 => 235897)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-09-11 17:14:07 UTC (rev 235897)
@@ -4816,6 +4816,7 @@
ED2BA83C09A24B91006C0AC4 /* DocumentMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = ED2BA83B09A24B91006C0AC4 /* DocumentMarker.h */; settings = {ATTRIBUTES = (Private, ); }; };
EDE3A5000C7A430600956A37 /* ColorMac.h in Headers */ = {isa = PBXBuildFile; fileRef = EDE3A4FF0C7A430600956A37 /* ColorMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
EDEC98030AED7E170059137F /* WebCorePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = EDEC98020AED7E170059137F /* WebCorePrefix.h */; };
+ EFCC6C8F20FE914400A2321B /* CanvasActivityRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
F12171F516A8CED2000053CA /* WebVTTElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F12171F316A8BC63000053CA /* WebVTTElement.cpp */; };
F12171F616A8CF0B000053CA /* WebVTTElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F12171F416A8BC63000053CA /* WebVTTElement.h */; };
F344C7141125B82C00F26EEE /* InspectorFrontendClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F344C7121125B82C00F26EEE /* InspectorFrontendClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -14503,6 +14504,8 @@
ED501DC50B249F2900AE18D9 /* EditorMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = EditorMac.mm; sourceTree = "<group>"; };
EDE3A4FF0C7A430600956A37 /* ColorMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorMac.h; sourceTree = "<group>"; };
EDEC98020AED7E170059137F /* WebCorePrefix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebCorePrefix.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
+ EFB7287B2124C73D005C2558 /* CanvasActivityRecord.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasActivityRecord.cpp; sourceTree = "<group>"; };
+ EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasActivityRecord.h; sourceTree = "<group>"; };
F12171F316A8BC63000053CA /* WebVTTElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebVTTElement.cpp; sourceTree = "<group>"; };
F12171F416A8BC63000053CA /* WebVTTElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebVTTElement.h; sourceTree = "<group>"; };
F344C7121125B82C00F26EEE /* InspectorFrontendClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorFrontendClient.h; sourceTree = "<group>"; };
@@ -24235,6 +24238,8 @@
93A1EAA20A5634D8006960A0 /* mac */,
63152D181F9531EE007A5E4B /* ApplicationManifestLoader.cpp */,
63152D171F9531EE007A5E4B /* ApplicationManifestLoader.h */,
+ EFB7287B2124C73D005C2558 /* CanvasActivityRecord.cpp */,
+ EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */,
A149786C1ABAF33800CEF7E4 /* ContentFilter.cpp */,
A149786D1ABAF33800CEF7E4 /* ContentFilter.h */,
E1424C91164B52C800F32D40 /* CookieJar.cpp */,
@@ -27318,6 +27323,7 @@
7C1E8D011ED0C2DA00B1D983 /* CallbackResult.h in Headers */,
952076051F2675FE007D2AAB /* CallTracer.h in Headers */,
952076061F2675FE007D2AAB /* CallTracerTypes.h in Headers */,
+ EFCC6C8F20FE914400A2321B /* CanvasActivityRecord.h in Headers */,
313171561FB079E5008D91FC /* CanvasBase.h in Headers */,
415CDAF51E6B8F8B004F11EE /* CanvasCaptureMediaStreamTrack.h in Headers */,
7C193BBB1F5E0EED0088F3E6 /* CanvasDirection.h in Headers */,
Modified: trunk/Source/WebCore/css/CSSFontFaceSource.cpp (235896 => 235897)
--- trunk/Source/WebCore/css/CSSFontFaceSource.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/css/CSSFontFaceSource.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -34,6 +34,8 @@
#include "FontCache.h"
#include "FontCustomPlatformData.h"
#include "FontDescription.h"
+#include "ResourceLoadObserver.h"
+#include "RuntimeEnabledFeatures.h"
#include "SVGToOTFFontConversion.h"
#include "SharedBuffer.h"
@@ -181,6 +183,10 @@
fontDescription.setComputedSize(1);
fontDescription.setShouldAllowUserInstalledFonts(m_face.allowUserInstalledFonts());
success = FontCache::singleton().fontForFamily(fontDescription, m_familyNameOrURI, nullptr, nullptr, FontSelectionSpecifiedCapabilities(), true);
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled()) {
+ if (auto* document = fontSelector->document())
+ ResourceLoadObserver::shared().logFontLoad(*document, m_familyNameOrURI.string(), success);
+ }
}
setStatus(success ? Status::Success : Status::Failure);
}
Modified: trunk/Source/WebCore/css/CSSFontSelector.cpp (235896 => 235897)
--- trunk/Source/WebCore/css/CSSFontSelector.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/css/CSSFontSelector.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -46,6 +46,8 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "Logging.h"
+#include "ResourceLoadObserver.h"
+#include "RuntimeEnabledFeatures.h"
#include "Settings.h"
#include "StyleProperties.h"
#include "StyleResolver.h"
@@ -308,13 +310,21 @@
AtomicString familyForLookup = resolveGenericFamilyFirst ? resolveGenericFamily(m_document, fontDescription, familyName) : familyName;
auto* face = m_cssFontFaceSet->fontFace(fontDescription.fontSelectionRequest(), familyForLookup);
- if (!face) {
- if (!resolveGenericFamilyFirst)
- familyForLookup = resolveGenericFamily(m_document, fontDescription, familyName);
- return FontRanges(FontCache::singleton().fontForFamily(fontDescription, familyForLookup));
+ if (face) {
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled()) {
+ if (m_document)
+ ResourceLoadObserver::shared().logFontLoad(*m_document, familyForLookup.string(), true);
+ }
+ return face->fontRanges(fontDescription);
}
-
- return face->fontRanges(fontDescription);
+ if (!resolveGenericFamilyFirst)
+ familyForLookup = resolveGenericFamily(m_document, fontDescription, familyName);
+ auto font = FontCache::singleton().fontForFamily(fontDescription, familyForLookup);
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled()) {
+ if (m_document)
+ ResourceLoadObserver::shared().logFontLoad(*m_document, familyForLookup.string(), !!font);
+ }
+ return FontRanges { WTFMove(font) };
}
void CSSFontSelector::clearDocument()
@@ -394,8 +404,12 @@
if (!m_document->settings().fontFallbackPrefersPictographs())
return nullptr;
-
- return FontCache::singleton().fontForFamily(fontDescription, m_document->settings().pictographFontFamily());
+ auto& pictographFontFamily = m_document->settings().pictographFontFamily();
+ auto font = FontCache::singleton().fontForFamily(fontDescription, pictographFontFamily);
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logFontLoad(*m_document, pictographFontFamily.string(), !!font);
+
+ return font;
}
}
Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (235896 => 235897)
--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -48,6 +48,7 @@
#include "MIMETypeRegistry.h"
#include "RenderElement.h"
#include "RenderHTMLCanvas.h"
+#include "ResourceLoadObserver.h"
#include "RuntimeEnabledFeatures.h"
#include "ScriptController.h"
#include "Settings.h"
@@ -698,6 +699,8 @@
if (m_size.isEmpty() || !buffer())
return UncachedString { "data:,"_s };
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logCanvasRead(document());
auto encodingMIMEType = toEncodingMimeType(mimeType);
auto quality = qualityFromJSValue(qualityValue);
@@ -727,6 +730,8 @@
callback->scheduleCallback(context, nullptr);
return { };
}
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logCanvasRead(document());
auto encodingMIMEType = toEncodingMimeType(mimeType);
auto quality = qualityFromJSValue(qualityValue);
@@ -755,8 +760,11 @@
RefPtr<ImageData> HTMLCanvasElement::getImageData()
{
#if ENABLE(WEBGL)
- if (is<WebGLRenderingContextBase>(m_context.get()))
+ if (is<WebGLRenderingContextBase>(m_context.get())) {
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logCanvasRead(document());
return downcast<WebGLRenderingContextBase>(*m_context).paintRenderingResultsToImageData();
+ }
#endif
return nullptr;
}
@@ -768,6 +776,8 @@
auto* imageBuffer = buffer();
if (!imageBuffer)
return nullptr;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logCanvasRead(document());
#if PLATFORM(COCOA)
makeRenderingResultsAvailable();
@@ -781,6 +791,8 @@
{
if (!originClean())
return Exception(SecurityError, "Canvas is tainted"_s);
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logCanvasRead(document());
if (frameRequestRate && frameRequestRate.value() < 0)
return Exception(NotSupportedError, "frameRequestRate is negative"_s);
Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (235896 => 235897)
--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -41,6 +41,8 @@
#include "InspectorInstrumentation.h"
#include "Path2D.h"
#include "RenderTheme.h"
+#include "ResourceLoadObserver.h"
+#include "RuntimeEnabledFeatures.h"
#include "StyleProperties.h"
#include "StyleResolver.h"
#include "TextMetrics.h"
@@ -363,6 +365,12 @@
Ref<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
{
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled()) {
+ auto& canvas = this->canvas();
+ ResourceLoadObserver::shared().logCanvasWriteOrMeasure(canvas.document(), text);
+ ResourceLoadObserver::shared().logCanvasRead(canvas.document());
+ }
+
Ref<TextMetrics> metrics = TextMetrics::create();
String normalizedText = text;
@@ -451,6 +459,9 @@
void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, std::optional<float> maxWidth)
{
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logCanvasWriteOrMeasure(this->canvas().document(), text);
+
auto& fontProxy = this->fontProxy();
const auto& fontMetrics = fontProxy.fontMetrics();
Added: trunk/Source/WebCore/loader/CanvasActivityRecord.cpp (0 => 235897)
--- trunk/Source/WebCore/loader/CanvasActivityRecord.cpp (rev 0)
+++ trunk/Source/WebCore/loader/CanvasActivityRecord.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CanvasActivityRecord.h"
+
+const unsigned maximumNumberOfStringsToRecord = 10;
+namespace WebCore {
+bool CanvasActivityRecord::recordWrittenOrMeasuredText(const String& text)
+{
+ // We limit the size of the textWritten HashSet to save memory and prevent bloating
+ // the plist with the resourceLoadStatistics entries. A few strings is often enough
+ // to provide sufficient information about the state of canvas activity.
+ if (textWritten.size() >= maximumNumberOfStringsToRecord)
+ return false;
+ return textWritten.add(text).isNewEntry;
+}
+
+void CanvasActivityRecord::mergeWith(const CanvasActivityRecord& otherCanvasActivityRecord)
+{
+ textWritten.add(otherCanvasActivityRecord.textWritten.begin(), otherCanvasActivityRecord.textWritten.end());
+ wasDataRead |= otherCanvasActivityRecord.wasDataRead;
+}
+} // namespace WebCore
Added: trunk/Source/WebCore/loader/CanvasActivityRecord.h (0 => 235897)
--- trunk/Source/WebCore/loader/CanvasActivityRecord.h (rev 0)
+++ trunk/Source/WebCore/loader/CanvasActivityRecord.h 2018-09-11 17:14:07 UTC (rev 235897)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+#include <wtf/HashSet.h>
+#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+struct CanvasActivityRecord {
+ HashSet<String> textWritten;
+ bool wasDataRead { false };
+
+ bool recordWrittenOrMeasuredText(const String&);
+ void mergeWith(const CanvasActivityRecord&);
+
+ template <class Encoder> void encode(Encoder&) const;
+ template <class Decoder> static bool decode(Decoder&, CanvasActivityRecord&);
+};
+
+template <class Encoder>
+void CanvasActivityRecord::encode(Encoder& encoder) const
+{
+ encoder << textWritten;
+ encoder << wasDataRead;
+}
+
+template <class Decoder>
+bool CanvasActivityRecord::decode(Decoder& decoder, CanvasActivityRecord& canvasActivityRecord)
+{
+ if (!decoder.decode(canvasActivityRecord.textWritten))
+ return false;
+ if (!decoder.decode(canvasActivityRecord.wasDataRead))
+ return false;
+ return true;
+}
+} // namespace WebCore
Modified: trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp (235896 => 235897)
--- trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -46,6 +46,7 @@
#include "LoadTiming.h"
#include "LoaderStrategy.h"
#include "Performance.h"
+#include "PlatformStrategies.h"
#include "ProgressTracker.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (235896 => 235897)
--- trunk/Source/WebCore/loader/FrameLoader.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -122,6 +122,7 @@
#include "UserGestureIndicator.h"
#include "WindowFeatures.h"
#include "XMLDocumentParser.h"
+#include <dom/ScriptDisallowedScope.h>
#include <wtf/CompletionHandler.h>
#include <wtf/Ref.h>
#include <wtf/SetForScope.h>
Modified: trunk/Source/WebCore/loader/ResourceLoadObserver.cpp (235896 => 235897)
--- trunk/Source/WebCore/loader/ResourceLoadObserver.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/loader/ResourceLoadObserver.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -36,6 +36,7 @@
#include "ResourceLoadStatistics.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
+#include "RuntimeEnabledFeatures.h"
#include "ScriptExecutionContext.h"
#include "SecurityOrigin.h"
#include "Settings.h"
@@ -242,6 +243,91 @@
}
#endif
+void ResourceLoadObserver::logFontLoad(const Document& document, const String& familyName, bool loadStatus)
+{
+ if (!shouldLog(document.sessionID().isEphemeral()))
+ return;
+ auto registrableDomain = primaryDomain(document.url());
+ auto& statistics = ensureResourceStatisticsForPrimaryDomain(registrableDomain);
+ bool shouldCallNotificationCallback = false;
+ if (!loadStatus) {
+ if (statistics.fontsFailedToLoad.add(familyName).isNewEntry)
+ shouldCallNotificationCallback = true;
+ } else {
+ if (statistics.fontsSuccessfullyLoaded.add(familyName).isNewEntry)
+ shouldCallNotificationCallback = true;
+ }
+ auto mainFrameRegistrableDomain = primaryDomain(document.topDocument().url());
+ if (statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs.add(mainFrameRegistrableDomain).isNewEntry)
+ shouldCallNotificationCallback = true;
+ if (shouldCallNotificationCallback)
+ scheduleNotificationIfNeeded();
+}
+
+void ResourceLoadObserver::logCanvasRead(const Document& document)
+{
+ if (!shouldLog(document.sessionID().isEphemeral()))
+ return;
+ auto registrableDomain = primaryDomain(document.url());
+ auto& statistics = ensureResourceStatisticsForPrimaryDomain(registrableDomain);
+ auto mainFrameRegistrableDomain = primaryDomain(document.topDocument().url());
+ statistics.canvasActivityRecord.wasDataRead = true;
+ if (statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs.add(mainFrameRegistrableDomain).isNewEntry)
+ scheduleNotificationIfNeeded();
+}
+
+void ResourceLoadObserver::logCanvasWriteOrMeasure(const Document& document, const String& textWritten)
+{
+ if (!shouldLog(document.sessionID().isEphemeral()))
+ return;
+ auto registrableDomain = primaryDomain(document.url());
+ auto& statistics = ensureResourceStatisticsForPrimaryDomain(registrableDomain);
+ bool shouldCallNotificationCallback = false;
+ auto mainFrameRegistrableDomain = primaryDomain(document.topDocument().url());
+ if (statistics.canvasActivityRecord.recordWrittenOrMeasuredText(textWritten))
+ shouldCallNotificationCallback = true;
+ if (statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs.add(mainFrameRegistrableDomain).isNewEntry)
+ shouldCallNotificationCallback = true;
+ if (shouldCallNotificationCallback)
+ scheduleNotificationIfNeeded();
+}
+
+void ResourceLoadObserver::logNavigatorAPIAccessed(const Document& document, const ResourceLoadStatistics::NavigatorAPI functionName)
+{
+ if (!shouldLog(document.sessionID().isEphemeral()))
+ return;
+ auto registrableDomain = primaryDomain(document.url());
+ auto& statistics = ensureResourceStatisticsForPrimaryDomain(registrableDomain);
+ bool shouldCallNotificationCallback = false;
+ if (!statistics.navigatorFunctionsAccessed.contains(functionName)) {
+ statistics.navigatorFunctionsAccessed.add(functionName);
+ shouldCallNotificationCallback = true;
+ }
+ auto mainFrameRegistrableDomain = primaryDomain(document.topDocument().url());
+ if (statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs.add(mainFrameRegistrableDomain).isNewEntry)
+ shouldCallNotificationCallback = true;
+ if (shouldCallNotificationCallback)
+ scheduleNotificationIfNeeded();
+}
+
+void ResourceLoadObserver::logScreenAPIAccessed(const Document& document, const ResourceLoadStatistics::ScreenAPI functionName)
+{
+ if (!shouldLog(document.sessionID().isEphemeral()))
+ return;
+ auto registrableDomain = primaryDomain(document.url());
+ auto& statistics = ensureResourceStatisticsForPrimaryDomain(registrableDomain);
+ bool shouldCallNotificationCallback = false;
+ if (!statistics.screenFunctionsAccessed.contains(functionName)) {
+ statistics.screenFunctionsAccessed.add(functionName);
+ shouldCallNotificationCallback = true;
+ }
+ auto mainFrameRegistrableDomain = primaryDomain(document.topDocument().url());
+ if (statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs.add(mainFrameRegistrableDomain).isNewEntry)
+ shouldCallNotificationCallback = true;
+ if (shouldCallNotificationCallback)
+ scheduleNotificationIfNeeded();
+}
+
ResourceLoadStatistics& ResourceLoadObserver::ensureResourceStatisticsForPrimaryDomain(const String& primaryDomain)
{
auto addResult = m_resourceStatisticsMap.ensure(primaryDomain, [&primaryDomain] {
Modified: trunk/Source/WebCore/loader/ResourceLoadObserver.h (235896 => 235897)
--- trunk/Source/WebCore/loader/ResourceLoadObserver.h 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/loader/ResourceLoadObserver.h 2018-09-11 17:14:07 UTC (rev 235897)
@@ -25,6 +25,8 @@
#pragma once
+#include "CanvasActivityRecord.h"
+#include "ResourceLoadStatistics.h"
#include "Timer.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
@@ -58,6 +60,12 @@
void logWebSocketLoading(const URL& targetURL, const URL& mainFrameURL, bool usesEphemeralSession);
void logUserInteractionWithReducedTimeResolution(const Document&);
void logWindowCreation(const URL& popupUrl, uint64_t openerPageID, Document& openerDocument);
+
+ void logFontLoad(const Document&, const String& familyName, bool loadStatus);
+ void logCanvasRead(const Document&);
+ void logCanvasWriteOrMeasure(const Document&, const String& textWritten);
+ void logNavigatorAPIAccessed(const Document&, const ResourceLoadStatistics::NavigatorAPI);
+ void logScreenAPIAccessed(const Document&, const ResourceLoadStatistics::ScreenAPI);
WEBCORE_EXPORT String statisticsForOrigin(const String&);
Modified: trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp (235896 => 235897)
--- trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -29,6 +29,7 @@
#include "KeyedCoding.h"
#include "PublicSuffix.h"
#include <wtf/MainThread.h>
+#include <wtf/text/ASCIILiteral.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringHash.h>
@@ -49,16 +50,46 @@
});
}
-static void encodeHashSet(KeyedEncoder& encoder, const String& label, const HashSet<String>& hashSet)
+static void encodeHashSet(KeyedEncoder& encoder, const String& label, const String& key, const HashSet<String>& hashSet)
{
if (hashSet.isEmpty())
return;
- encoder.encodeObjects(label, hashSet.begin(), hashSet.end(), [](KeyedEncoder& encoderInner, const String& origin) {
- encoderInner.encodeString("origin", origin);
+ encoder.encodeObjects(label, hashSet.begin(), hashSet.end(), [&key](KeyedEncoder& encoderInner, const String& origin) {
+ encoderInner.encodeString(key, origin);
});
}
+static void encodeOriginHashSet(KeyedEncoder& encoder, const String& label, const HashSet<String>& hashSet)
+{
+ encodeHashSet(encoder, label, "origin", hashSet);
+}
+
+template<typename T>
+static void encodeOptionSet(KeyedEncoder& encoder, const String& label, const OptionSet<T>& optionSet)
+{
+ if (optionSet.isEmpty())
+ return;
+
+ uint64_t optionSetBitMask = optionSet.toRaw();
+ encoder.encodeUInt64(label, optionSetBitMask);
+}
+
+static void encodeFontHashSet(KeyedEncoder& encoder, const String& label, const HashSet<String>& hashSet)
+{
+ encodeHashSet(encoder, label, "font", hashSet);
+}
+
+static void encodeCanvasActivityRecord(KeyedEncoder& encoder, const String& label, const CanvasActivityRecord& canvasActivityRecord)
+{
+ encoder.encodeObject(label, canvasActivityRecord, [] (KeyedEncoder& encoderInner, const CanvasActivityRecord& canvasActivityRecord) {
+ encoderInner.encodeBool("wasDataRead", canvasActivityRecord.wasDataRead);
+ encoderInner.encodeObjects("textWritten", canvasActivityRecord.textWritten.begin(), canvasActivityRecord.textWritten.end(), [] (KeyedEncoder& encoderInner2, const String& text) {
+ encoderInner2.encodeString("text", text);
+ });
+ });
+}
+
void ResourceLoadStatistics::encode(KeyedEncoder& encoder) const
{
encoder.encodeString("PrevalentResourceOrigin", highLevelDomain);
@@ -71,7 +102,7 @@
encoder.encodeBool("grandfathered", grandfathered);
// Storage access
- encodeHashSet(encoder, "storageAccessUnderTopFrameOrigins", storageAccessUnderTopFrameOrigins);
+ encodeOriginHashSet(encoder, "storageAccessUnderTopFrameOrigins", storageAccessUnderTopFrameOrigins);
// Top frame stats
encodeHashCountedSet(encoder, "topFrameUniqueRedirectsTo", topFrameUniqueRedirectsTo);
@@ -92,6 +123,13 @@
encoder.encodeUInt32("timesAccessedAsFirstPartyDueToUserInteraction", timesAccessedAsFirstPartyDueToUserInteraction);
encoder.encodeUInt32("timesAccessedAsFirstPartyDueToStorageAccessAPI", timesAccessedAsFirstPartyDueToStorageAccessAPI);
+
+ encodeFontHashSet(encoder, "fontsFailedToLoad", fontsFailedToLoad);
+ encodeFontHashSet(encoder, "fontsSuccessfullyLoaded", fontsSuccessfullyLoaded);
+ encodeHashCountedSet(encoder, "topFrameRegistrableDomainsWhichAccessedWebAPIs", topFrameRegistrableDomainsWhichAccessedWebAPIs);
+ encodeCanvasActivityRecord(encoder, "canvasActivityRecord", canvasActivityRecord);
+ encodeOptionSet(encoder, "navigatorFunctionsAccessedBitMask", navigatorFunctionsAccessed);
+ encodeOptionSet(encoder, "screenFunctionsAccessedBitMask", screenFunctionsAccessed);
}
static void decodeHashCountedSet(KeyedDecoder& decoder, const String& label, HashCountedSet<String>& hashCountedSet)
@@ -110,11 +148,11 @@
});
}
-static void decodeHashSet(KeyedDecoder& decoder, const String& label, HashSet<String>& hashSet)
+static void decodeHashSet(KeyedDecoder& decoder, const String& label, const String& key, HashSet<String>& hashSet)
{
Vector<String> ignore;
- decoder.decodeObjects(label, ignore, [&hashSet](KeyedDecoder& decoderInner, String& origin) {
- if (!decoderInner.decodeString("origin", origin))
+ decoder.decodeObjects(label, ignore, [&hashSet, &key](KeyedDecoder& decoderInner, String& origin) {
+ if (!decoderInner.decodeString(key, origin))
return false;
hashSet.add(origin);
@@ -122,6 +160,40 @@
});
}
+static void decodeOriginHashSet(KeyedDecoder& decoder, const String& label, HashSet<String>& hashSet)
+{
+ decodeHashSet(decoder, label, "origin", hashSet);
+}
+
+template<typename T>
+static void decodeOptionSet(KeyedDecoder& decoder, const String& label, OptionSet<T>& optionSet)
+{
+ uint64_t optionSetBitMask = 0;
+ decoder.decodeUInt64(label, optionSetBitMask);
+ optionSet = OptionSet<T>::fromRaw(optionSetBitMask);
+}
+
+static void decodeFontHashSet(KeyedDecoder& decoder, const String& label, HashSet<String>& hashSet)
+{
+ decodeHashSet(decoder, label, "font", hashSet);
+}
+
+static void decodeCanvasActivityRecord(KeyedDecoder& decoder, const String& label, CanvasActivityRecord& canvasActivityRecord)
+{
+ decoder.decodeObject(label, canvasActivityRecord, [] (KeyedDecoder& decoderInner, CanvasActivityRecord& canvasActivityRecord) {
+ if (!decoderInner.decodeBool("wasDataRead", canvasActivityRecord.wasDataRead))
+ return false;
+ Vector<String> ignore;
+ decoderInner.decodeObjects("textWritten", ignore, [&canvasActivityRecord] (KeyedDecoder& decoderInner2, String& text) {
+ if (!decoderInner2.decodeString("text", text))
+ return false;
+ canvasActivityRecord.textWritten.add(text);
+ return true;
+ });
+ return true;
+ });
+}
+
bool ResourceLoadStatistics::decode(KeyedDecoder& decoder, unsigned modelVersion)
{
if (!decoder.decodeString("PrevalentResourceOrigin", highLevelDomain))
@@ -132,7 +204,7 @@
return false;
// Storage access
- decodeHashSet(decoder, "storageAccessUnderTopFrameOrigins", storageAccessUnderTopFrameOrigins);
+ decodeOriginHashSet(decoder, "storageAccessUnderTopFrameOrigins", storageAccessUnderTopFrameOrigins);
// Top frame stats
if (modelVersion >= 11) {
@@ -180,6 +252,16 @@
if (!decoder.decodeUInt32("timesAccessedAsFirstPartyDueToStorageAccessAPI", timesAccessedAsFirstPartyDueToStorageAccessAPI))
timesAccessedAsFirstPartyDueToStorageAccessAPI = 0;
}
+
+ if (modelVersion >= 13) {
+ decodeFontHashSet(decoder, "fontsFailedToLoad", fontsFailedToLoad);
+ decodeFontHashSet(decoder, "fontsSuccessfullyLoaded", fontsSuccessfullyLoaded);
+ decodeHashCountedSet(decoder, "topFrameRegistrableDomainsWhichAccessedWebAPIs", topFrameRegistrableDomainsWhichAccessedWebAPIs);
+ decodeCanvasActivityRecord(decoder, "canvasActivityRecord", canvasActivityRecord);
+ decodeOptionSet(decoder, "navigatorFunctionsAccessedBitMask", navigatorFunctionsAccessed);
+ decodeOptionSet(decoder, "screenFunctionsAccessedBitMask", screenFunctionsAccessed);
+ }
+
return true;
}
@@ -225,11 +307,81 @@
}
}
+static ASCIILiteral navigatorAPIEnumToString(ResourceLoadStatistics::NavigatorAPI navigatorEnum)
+{
+ switch (navigatorEnum) {
+ case ResourceLoadStatistics::NavigatorAPI::JavaEnabled:
+ return "javaEnabled"_s;
+ case ResourceLoadStatistics::NavigatorAPI::MimeTypes:
+ return "mimeTypes"_s;
+ case ResourceLoadStatistics::NavigatorAPI::CookieEnabled:
+ return "cookieEnabled"_s;
+ case ResourceLoadStatistics::NavigatorAPI::Plugins:
+ return "plugins"_s;
+ case ResourceLoadStatistics::NavigatorAPI::UserAgent:
+ return "userAgent"_s;
+ case ResourceLoadStatistics::NavigatorAPI::AppVersion:
+ return "appVersion"_s;
+ }
+ ASSERT_NOT_REACHED();
+ return "Invalid navigator API"_s;
+}
+
+static ASCIILiteral screenAPIEnumToString(ResourceLoadStatistics::ScreenAPI screenEnum)
+{
+ switch (screenEnum) {
+ case ResourceLoadStatistics::ScreenAPI::Height:
+ return "height"_s;
+ case ResourceLoadStatistics::ScreenAPI::Width:
+ return "width"_s;
+ case ResourceLoadStatistics::ScreenAPI::ColorDepth:
+ return "colorDepth"_s;
+ case ResourceLoadStatistics::ScreenAPI::PixelDepth:
+ return "pixelDepth"_s;
+ case ResourceLoadStatistics::ScreenAPI::AvailLeft:
+ return "availLeft"_s;
+ case ResourceLoadStatistics::ScreenAPI::AvailTop:
+ return "availTop"_s;
+ case ResourceLoadStatistics::ScreenAPI::AvailHeight:
+ return "availHeight"_s;
+ case ResourceLoadStatistics::ScreenAPI::AvailWidth:
+ return "availWidth"_s;
+ }
+ ASSERT_NOT_REACHED();
+ return "Invalid screen API"_s;
+}
+
+static void appendNavigatorAPIOptionSet(StringBuilder& builder, const OptionSet<ResourceLoadStatistics::NavigatorAPI>& optionSet)
+{
+ if (optionSet.isEmpty())
+ return;
+ builder.appendLiteral(" navigatorFunctionsAccessed:\n");
+ for (auto navigatorAPI : optionSet) {
+ builder.appendLiteral(" ");
+ builder.append(navigatorAPIEnumToString(navigatorAPI).characters());
+ builder.append('\n');
+ }
+}
+
+static void appendScreenAPIOptionSet(StringBuilder& builder, const OptionSet<ResourceLoadStatistics::ScreenAPI>& optionSet)
+{
+ if (optionSet.isEmpty())
+ return;
+ builder.appendLiteral(" screenFunctionsAccessed:\n");
+ for (auto screenAPI : optionSet) {
+ builder.appendLiteral(" ");
+ builder.append(screenAPIEnumToString(screenAPI).characters());
+ builder.append('\n');
+ }
+}
+
String ResourceLoadStatistics::toString() const
{
StringBuilder builder;
-
- builder.appendLiteral("lastSeen");
+ builder.appendLiteral("High level domain: ");
+ builder.append(highLevelDomain);
+ builder.append('\n');
+ builder.appendLiteral(" lastSeen: ");
builder.appendNumber(lastSeen.secondsSinceEpoch().value());
builder.append('\n');
@@ -239,7 +391,7 @@
builder.appendLiteral(" mostRecentUserInteraction: ");
builder.appendNumber(mostRecentUserInteractionTime.secondsSinceEpoch().value());
builder.append('\n');
- appendBoolean(builder, " grandfathered", grandfathered);
+ appendBoolean(builder, "grandfathered", grandfathered);
builder.append('\n');
// Storage access
@@ -259,7 +411,9 @@
// Prevalent Resource
appendBoolean(builder, "isPrevalentResource", isPrevalentResource);
- appendBoolean(builder, " isVeryPrevalentResource", isVeryPrevalentResource);
+ builder.append('\n');
+ appendBoolean(builder, "isVeryPrevalentResource", isVeryPrevalentResource);
+ builder.append('\n');
builder.appendLiteral(" dataRecordsRemoved: ");
builder.appendNumber(dataRecordsRemoved);
builder.append('\n');
@@ -268,7 +422,15 @@
appendBoolean(builder, "isMarkedForCookieBlocking", isMarkedForCookieBlocking);
builder.append('\n');
+ appendHashSet(builder, "fontsFailedToLoad", fontsFailedToLoad);
+ appendHashSet(builder, "fontsSuccessfullyLoaded", fontsSuccessfullyLoaded);
+ appendHashCountedSet(builder, "topFrameRegistrableDomainsWhichAccessedWebAPIs", topFrameRegistrableDomainsWhichAccessedWebAPIs);
+ appendNavigatorAPIOptionSet(builder, navigatorFunctionsAccessed);
+ appendScreenAPIOptionSet(builder, screenFunctionsAccessed);
+ appendHashSet(builder, "canvasTextWritten", canvasActivityRecord.textWritten);
+ appendBoolean(builder, "canvasReadData", canvasActivityRecord.wasDataRead);
builder.append('\n');
+ builder.append('\n');
return builder.toString();
}
@@ -330,6 +492,13 @@
// In-memory only
isMarkedForCookieBlocking |= other.isMarkedForCookieBlocking;
+
+ mergeHashSet(fontsFailedToLoad, other.fontsFailedToLoad);
+ mergeHashSet(fontsSuccessfullyLoaded, other.fontsSuccessfullyLoaded);
+ mergeHashCountedSet(topFrameRegistrableDomainsWhichAccessedWebAPIs, other.topFrameRegistrableDomainsWhichAccessedWebAPIs);
+ canvasActivityRecord.mergeWith(other.canvasActivityRecord);
+ navigatorFunctionsAccessed.add(other.navigatorFunctionsAccessed);
+ screenFunctionsAccessed.add(other.screenFunctionsAccessed);
}
String ResourceLoadStatistics::primaryDomain(const URL& url)
Modified: trunk/Source/WebCore/loader/ResourceLoadStatistics.h (235896 => 235897)
--- trunk/Source/WebCore/loader/ResourceLoadStatistics.h 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/loader/ResourceLoadStatistics.h 2018-09-11 17:14:07 UTC (rev 235897)
@@ -25,9 +25,11 @@
#pragma once
+#include "CanvasActivityRecord.h"
#include "URL.h"
#include <wtf/HashCountedSet.h>
#include <wtf/HashSet.h>
+#include <wtf/OptionSet.h>
#include <wtf/WallTime.h>
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
@@ -96,6 +98,33 @@
// In-memory only
bool isMarkedForCookieBlocking { false };
+
+ // This set represents the registrable domain of the top frame where web API
+ // were used in the top frame or one of its subframes.
+ HashCountedSet<String> topFrameRegistrableDomainsWhichAccessedWebAPIs;
+ HashSet<String> fontsFailedToLoad;
+ HashSet<String> fontsSuccessfullyLoaded;
+ CanvasActivityRecord canvasActivityRecord;
+ enum class NavigatorAPI : uint64_t {
+ AppVersion = 1 << 0,
+ UserAgent = 1 << 1,
+ Plugins = 1 << 2,
+ MimeTypes = 1 << 3,
+ CookieEnabled = 1 << 4,
+ JavaEnabled = 1 << 5,
+ };
+ enum class ScreenAPI : uint64_t {
+ Height = 1 << 0,
+ Width = 1 << 1,
+ ColorDepth = 1 << 2,
+ PixelDepth = 1 << 3,
+ AvailLeft = 1 << 4,
+ AvailTop = 1 << 5,
+ AvailHeight = 1 << 6,
+ AvailWidth = 1 << 7,
+ };
+ OptionSet<NavigatorAPI> navigatorFunctionsAccessed;
+ OptionSet<ScreenAPI> screenFunctionsAccessed;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/loader/ResourceTiming.cpp (235896 => 235897)
--- trunk/Source/WebCore/loader/ResourceTiming.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/loader/ResourceTiming.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -28,8 +28,10 @@
#include "CachedResource.h"
#include "PerformanceServerTiming.h"
+#include "RuntimeEnabledFeatures.h"
#include "SecurityOrigin.h"
#include "ServerTimingParser.h"
+#include <wtf/CrossThreadCopier.h>
namespace WebCore {
Modified: trunk/Source/WebCore/page/Navigator.cpp (235896 => 235897)
--- trunk/Source/WebCore/page/Navigator.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/page/Navigator.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -37,6 +37,8 @@
#include "Page.h"
#include "PlatformStrategies.h"
#include "PluginData.h"
+#include "ResourceLoadObserver.h"
+#include "RuntimeEnabledFeatures.h"
#include "ScriptController.h"
#include "SecurityOrigin.h"
#include "Settings.h"
@@ -44,7 +46,6 @@
#include <wtf/StdLibExtras.h>
#include <wtf/WeakPtr.h>
-
namespace WebCore {
using namespace WTF;
@@ -74,6 +75,8 @@
{
if (!m_frame)
return String();
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logNavigatorAPIAccessed(*m_frame->document(), ResourceLoadStatistics::NavigatorAPI::AppVersion);
String appVersion = NavigatorBase::appVersion();
if (shouldHideFourDot(*m_frame))
appVersion.replace("4.", "4_");
@@ -82,7 +85,11 @@
const String& Navigator::userAgent() const
{
- if (m_userAgent.isNull() && m_frame && m_frame->page())
+ if (!m_frame || !m_frame->page())
+ return m_userAgent;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logNavigatorAPIAccessed(*m_frame->document(), ResourceLoadStatistics::NavigatorAPI::UserAgent);
+ if (m_userAgent.isNull())
m_userAgent = m_frame->loader().userAgent(m_frame->document()->url());
return m_userAgent;
}
@@ -136,6 +143,10 @@
DOMPluginArray& Navigator::plugins()
{
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled()) {
+ if (m_frame)
+ ResourceLoadObserver::shared().logNavigatorAPIAccessed(*m_frame->document(), ResourceLoadStatistics::NavigatorAPI::Plugins);
+ }
if (!m_plugins)
m_plugins = DOMPluginArray::create(m_frame);
return *m_plugins;
@@ -143,6 +154,10 @@
DOMMimeTypeArray& Navigator::mimeTypes()
{
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled()) {
+ if (m_frame)
+ ResourceLoadObserver::shared().logNavigatorAPIAccessed(*m_frame->document(), ResourceLoadStatistics::NavigatorAPI::MimeTypes);
+ }
if (!m_mimeTypes)
m_mimeTypes = DOMMimeTypeArray::create(m_frame);
return *m_mimeTypes;
@@ -153,6 +168,9 @@
if (!m_frame)
return false;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logNavigatorAPIAccessed(*m_frame->document(), ResourceLoadStatistics::NavigatorAPI::CookieEnabled);
+
if (m_frame->page() && !m_frame->page()->settings().cookieEnabled())
return false;
@@ -168,6 +186,9 @@
if (!m_frame)
return false;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logNavigatorAPIAccessed(*m_frame->document(), ResourceLoadStatistics::NavigatorAPI::JavaEnabled);
+
if (!m_frame->settings().isJavaEnabled())
return false;
if (m_frame->document()->securityOrigin().isLocal() && !m_frame->settings().isJavaEnabledForLocalFiles())
Modified: trunk/Source/WebCore/page/Screen.cpp (235896 => 235897)
--- trunk/Source/WebCore/page/Screen.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebCore/page/Screen.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -33,6 +33,8 @@
#include "Frame.h"
#include "FrameView.h"
#include "PlatformScreen.h"
+#include "ResourceLoadObserver.h"
+#include "RuntimeEnabledFeatures.h"
namespace WebCore {
@@ -45,6 +47,8 @@
{
if (!m_frame)
return 0;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logScreenAPIAccessed(*m_frame->document(), ResourceLoadStatistics::ScreenAPI::Height);
long height = static_cast<long>(screenRect(m_frame->view()).height());
return static_cast<unsigned>(height);
}
@@ -53,6 +57,8 @@
{
if (!m_frame)
return 0;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logScreenAPIAccessed(*m_frame->document(), ResourceLoadStatistics::ScreenAPI::Width);
long width = static_cast<long>(screenRect(m_frame->view()).width());
return static_cast<unsigned>(width);
}
@@ -61,6 +67,8 @@
{
if (!m_frame)
return 0;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logScreenAPIAccessed(*m_frame->document(), ResourceLoadStatistics::ScreenAPI::ColorDepth);
return static_cast<unsigned>(screenDepth(m_frame->view()));
}
@@ -68,6 +76,8 @@
{
if (!m_frame)
return 0;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logScreenAPIAccessed(*m_frame->document(), ResourceLoadStatistics::ScreenAPI::PixelDepth);
return static_cast<unsigned>(screenDepth(m_frame->view()));
}
@@ -75,6 +85,8 @@
{
if (!m_frame)
return 0;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logScreenAPIAccessed(*m_frame->document(), ResourceLoadStatistics::ScreenAPI::AvailLeft);
return static_cast<int>(screenAvailableRect(m_frame->view()).x());
}
@@ -82,6 +94,8 @@
{
if (!m_frame)
return 0;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logScreenAPIAccessed(*m_frame->document(), ResourceLoadStatistics::ScreenAPI::AvailTop);
return static_cast<int>(screenAvailableRect(m_frame->view()).y());
}
@@ -89,6 +103,8 @@
{
if (!m_frame)
return 0;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logScreenAPIAccessed(*m_frame->document(), ResourceLoadStatistics::ScreenAPI::AvailHeight);
return static_cast<unsigned>(screenAvailableRect(m_frame->view()).height());
}
@@ -96,6 +112,8 @@
{
if (!m_frame)
return 0;
+ if (RuntimeEnabledFeatures::sharedFeatures().webAPIStatisticsEnabled())
+ ResourceLoadObserver::shared().logScreenAPIAccessed(*m_frame->document(), ResourceLoadStatistics::ScreenAPI::AvailWidth);
return static_cast<unsigned>(screenAvailableRect(m_frame->view()).width());
}
Modified: trunk/Source/WebKit/ChangeLog (235896 => 235897)
--- trunk/Source/WebKit/ChangeLog 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebKit/ChangeLog 2018-09-11 17:14:07 UTC (rev 235897)
@@ -1 +1,14 @@
+2018-09-11 Woodrow Wang <[email protected]>
+
+ Add Web API Statistics Collection
+ https://bugs.webkit.org/show_bug.cgi?id=187773
+ <rdar://problem/44155162>
+
+ Reviewed by Brent Fulgham.
+
+ * Shared/WebCoreArgumentCoders.cpp:
+ (IPC::ArgumentCoder<ResourceLoadStatistics>::encode):
+ (IPC::ArgumentCoder<ResourceLoadStatistics>::decode):
+ * UIProcess/ResourceLoadStatisticsMemoryStore.cpp:
+
== Rolled over to ChangeLog-2018-09-11 ==
Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (235896 => 235897)
--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -2664,6 +2664,16 @@
encoder << statistics.isPrevalentResource;
encoder << statistics.isVeryPrevalentResource;
encoder << statistics.dataRecordsRemoved;
+
+ encoder << statistics.fontsFailedToLoad;
+ encoder << statistics.fontsSuccessfullyLoaded;
+ encoder << statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs;
+
+ encoder << statistics.canvasActivityRecord;
+
+ encoder << statistics.navigatorFunctionsAccessed;
+ encoder << statistics.screenFunctionsAccessed;
+
}
std::optional<ResourceLoadStatistics> ArgumentCoder<ResourceLoadStatistics>::decode(Decoder& decoder)
@@ -2723,7 +2733,25 @@
if (!decoder.decode(statistics.dataRecordsRemoved))
return std::nullopt;
-
+
+ if (!decoder.decode(statistics.fontsFailedToLoad))
+ return std::nullopt;
+
+ if (!decoder.decode(statistics.fontsSuccessfullyLoaded))
+ return std::nullopt;
+
+ if (!decoder.decode(statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs))
+ return std::nullopt;
+
+ if (!decoder.decode(statistics.canvasActivityRecord))
+ return std::nullopt;
+
+ if (!decoder.decode(statistics.navigatorFunctionsAccessed))
+ return std::nullopt;
+
+ if (!decoder.decode(statistics.screenFunctionsAccessed))
+ return std::nullopt;
+
return WTFMove(statistics);
}
Modified: trunk/Source/WebKit/UIProcess/ResourceLoadStatisticsMemoryStore.cpp (235896 => 235897)
--- trunk/Source/WebKit/UIProcess/ResourceLoadStatisticsMemoryStore.cpp 2018-09-11 16:24:21 UTC (rev 235896)
+++ trunk/Source/WebKit/UIProcess/ResourceLoadStatisticsMemoryStore.cpp 2018-09-11 17:14:07 UTC (rev 235897)
@@ -46,7 +46,7 @@
namespace WebKit {
using namespace WebCore;
-constexpr unsigned statisticsModelVersion { 12 };
+constexpr unsigned statisticsModelVersion { 13 };
constexpr unsigned maxNumberOfRecursiveCallsInRedirectTraceBack { 50 };
constexpr Seconds minimumStatisticsProcessingInterval { 5_s };
constexpr unsigned operatingDatesWindow { 30 };