aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2021-02-02 16:46:40 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-02-02 16:46:40 +0000
commit6f646ffc3ebcc08cc35de484cd80dc1815923aef (patch)
tree4fae679f441b84389fa75886c45a246891176bba
parent01475bd1c746c98178fdc60cb665074e0b1c5e4c (diff)
parent481ecea8372fdb116dc5eec3f4a76f3d8cb88fe9 (diff)
downloadchromium-trace-6f646ffc3ebcc08cc35de484cd80dc1815923aef.tar.gz
Merge "Update catapult to latest version (91735e2e6)" am: 481ecea837
Original change: https://android-review.googlesource.com/c/platform/external/chromium-trace/+/1567220 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I9004291607bc9b0e7f80e252ce2e9ef9271eaad1
-rw-r--r--UPSTREAM_REVISION2
-rw-r--r--catapult/common/node_runner/node_runner/node_binaries.json32
-rw-r--r--catapult/common/node_runner/node_runner/package-lock.json657
-rw-r--r--catapult/common/py_utils/py_utils/chrome_binaries.json10
-rw-r--r--catapult/common/py_utils/py_utils/cloud_storage.py31
-rw-r--r--catapult/common/py_utils/py_utils/cloud_storage_unittest.py18
-rw-r--r--catapult/common/py_utils/py_utils/ts_proxy_server.py12
-rw-r--r--catapult/common/py_utils/py_utils/webpagereplay_go_server.py84
-rw-r--r--catapult/dependency_manager/dependency_manager/__init__.py2
-rwxr-xr-xcatapult/devil/bin/generate_md_docs2
-rwxr-xr-xcatapult/devil/bin/run_py_devicetests2
-rwxr-xr-xcatapult/devil/bin/run_py_tests2
-rw-r--r--catapult/devil/build/cipd.yaml7
-rw-r--r--catapult/devil/devil/android/device_blacklist.py9
-rw-r--r--catapult/devil/devil/android/device_errors.py9
-rw-r--r--catapult/devil/devil/android/device_utils.py140
-rwxr-xr-xcatapult/devil/devil/android/device_utils_test.py248
-rw-r--r--catapult/devil/devil/android/forwarder.py13
-rw-r--r--catapult/devil/devil/android/sdk/adb_wrapper.py37
-rwxr-xr-xcatapult/devil/devil/android/sdk/adb_wrapper_test.py9
-rw-r--r--catapult/devil/devil/android/sdk/bundletool.py4
-rwxr-xr-xcatapult/devil/devil/android/tools/device_monitor.py5
-rwxr-xr-xcatapult/devil/devil/android/tools/device_recovery.py8
-rwxr-xr-xcatapult/devil/devil/android/tools/device_status.py5
-rwxr-xr-xcatapult/devil/devil/android/tools/provision_devices.py9
-rw-r--r--catapult/devil/devil/android/tools/script_common.py19
-rwxr-xr-xcatapult/devil/devil/android/tools/system_app.py5
-rwxr-xr-xcatapult/devil/devil/android/tools/webview_app.py16
-rw-r--r--catapult/devil/devil/devil_dependencies.json2
-rw-r--r--catapult/devil/devil/devil_env.py5
-rwxr-xr-xcatapult/devil/devil/utils/update_dependencies.py2
-rw-r--r--catapult/devil/devil/utils/zip_utils.py13
-rw-r--r--catapult/devil/devil/utils/zip_utils_test.py5
-rw-r--r--catapult/systrace/systrace/systrace_trace_viewer.html282
-rw-r--r--catapult/systrace/systrace/tracing_agents/atrace_agent.py3
-rw-r--r--catapult/systrace/systrace/util.py14
36 files changed, 1263 insertions, 460 deletions
diff --git a/UPSTREAM_REVISION b/UPSTREAM_REVISION
index 2997d941..ab641bd2 100644
--- a/UPSTREAM_REVISION
+++ b/UPSTREAM_REVISION
@@ -1 +1 @@
-c4d3ff474abec0ece4c42552b25aea9b54ecc047
+91735e2e6775c098eb32840a8903e5a9111fad77
diff --git a/catapult/common/node_runner/node_runner/node_binaries.json b/catapult/common/node_runner/node_runner/node_binaries.json
index d5e1cc5d..89a73eeb 100644
--- a/catapult/common/node_runner/node_runner/node_binaries.json
+++ b/catapult/common/node_runner/node_runner/node_binaries.json
@@ -9,19 +9,19 @@
"cloud_storage_hash": "27ad092b0ce59d2da32090a00f717f0c31e65240",
"download_path": "bin/node/node-linux64.zip",
"path_within_archive": "node-v10.14.1-linux-x64/bin/node",
- "version_in_cs": "6.7.0"
+ "version_in_cs": "10.14.1"
},
"mac_x86_64": {
- "cloud_storage_hash": "1af7c221e530165af8a6ab8ff7ccb1f2dd54036d",
+ "cloud_storage_hash": "1bd87abe88492d52b366e97ae9404f082b34fd15",
"download_path": "bin/node/node-mac64.zip",
- "path_within_archive": "node-v6.7.0-darwin-x64/bin/node",
- "version_in_cs": "6.7.0"
+ "path_within_archive": "node-v10.14.1-darwin-x64/bin/node",
+ "version_in_cs": "10.14.1"
},
"win_AMD64": {
- "cloud_storage_hash": "23f21bfb2edf874a8b6bdb6c1acb408bc7edeced",
+ "cloud_storage_hash": "f1162c6343dc6a3a1acecf76966d4c2acd17fc46",
"download_path": "bin/node/node-win64.zip",
- "path_within_archive": "node-v6.7.0-win-x64/node.exe",
- "version_in_cs": "6.7.0"
+ "path_within_archive": "node-v10.14.1-win-x64/node.exe",
+ "version_in_cs": "10.14.1"
}
}
},
@@ -30,22 +30,22 @@
"cloud_storage_bucket": "chromium-telemetry",
"file_info": {
"linux_x86_64": {
- "cloud_storage_hash": "5750e968975e7f5ab8cb694f5e92a34a890e129d",
+ "cloud_storage_hash": "830b8f6761bf82a945b57facfb49925b579c471c",
"download_path": "bin/node/npm-linux64.zip",
- "path_within_archive": "node-v6.7.0-linux-x64/lib/node_modules/npm/bin/npm-cli.js",
- "version_in_cs": "6.7.0"
+ "path_within_archive": "node-v10.14.1-linux-x64/lib/node_modules/npm/bin/npm-cli.js",
+ "version_in_cs": "10.14.1"
},
"mac_x86_64": {
- "cloud_storage_hash": "1af7c221e530165af8a6ab8ff7ccb1f2dd54036d",
+ "cloud_storage_hash": "1bd87abe88492d52b366e97ae9404f082b34fd15",
"download_path": "bin/node/npm-mac64.zip",
- "path_within_archive": "node-v6.7.0-darwin-x64/lib/node_modules/npm/bin/npm-cli.js",
- "version_in_cs": "6.7.0"
+ "path_within_archive": "node-v10.14.1-darwin-x64/lib/node_modules/npm/bin/npm-cli.js",
+ "version_in_cs": "10.14.1"
},
"win_AMD64": {
- "cloud_storage_hash": "23f21bfb2edf874a8b6bdb6c1acb408bc7edeced",
+ "cloud_storage_hash": "f1162c6343dc6a3a1acecf76966d4c2acd17fc46",
"download_path": "bin/node/npm-win64.zip",
- "path_within_archive": "node-v6.7.0-win-x64\\node_modules\\npm\\bin\\npm-cli.js",
- "version_in_cs": "6.7.0"
+ "path_within_archive": "node-v10.14.1-win-x64\\node_modules\\npm\\bin\\npm-cli.js",
+ "version_in_cs": "10.14.1"
}
}
}
diff --git a/catapult/common/node_runner/node_runner/package-lock.json b/catapult/common/node_runner/node_runner/package-lock.json
index 683cae9e..2e8ef2a2 100644
--- a/catapult/common/node_runner/node_runner/package-lock.json
+++ b/catapult/common/node_runner/node_runner/package-lock.json
@@ -4,6 +4,157 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@babel/code-frame": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+ "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+ "requires": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.11.4",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz",
+ "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==",
+ "requires": {
+ "@babel/types": "^7.11.0",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+ "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helper-get-function-arity": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+ "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
+ "requires": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+ "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
+ "requires": {
+ "@babel/types": "^7.11.0"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw=="
+ },
+ "@babel/highlight": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+ "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "dependencies": {
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ }
+ }
+ },
+ "@babel/parser": {
+ "version": "7.11.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz",
+ "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA=="
+ },
+ "@babel/template": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+ "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/parser": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz",
+ "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==",
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.11.0",
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-split-export-declaration": "^7.11.0",
+ "@babel/parser": "^7.11.0",
+ "@babel/types": "^7.11.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.19"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "@babel/types": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz",
+ "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==",
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
+ }
+ }
+ },
"@chopsui/batch-iterator": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@chopsui/batch-iterator/-/batch-iterator-0.1.0.tgz",
@@ -232,11 +383,83 @@
"resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
"integrity": "sha1-jaXGUwkVZT86Hzj9XxAdjD+AecU="
},
+ "@types/babel-generator": {
+ "version": "6.25.3",
+ "resolved": "https://registry.npmjs.org/@types/babel-generator/-/babel-generator-6.25.3.tgz",
+ "integrity": "sha512-pGgnuxVddKcYIc+VJkRDop7gxLhqclNKBdlsm/5Vp8d+37pQkkDK7fef8d9YYImRzw9xcojEPc18pUYnbxmjqA==",
+ "requires": {
+ "@types/babel-types": "*"
+ }
+ },
+ "@types/babel-traverse": {
+ "version": "6.25.5",
+ "resolved": "https://registry.npmjs.org/@types/babel-traverse/-/babel-traverse-6.25.5.tgz",
+ "integrity": "sha512-WrMbwmu+MWf8FiUMbmVOGkc7bHPzndUafn1CivMaBHthBBoo0VNIcYk1KV71UovYguhsNOwf3UF5oRmkkGOU3w==",
+ "requires": {
+ "@types/babel-types": "*"
+ }
+ },
+ "@types/babel-types": {
+ "version": "7.0.8",
+ "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.8.tgz",
+ "integrity": "sha512-jvu8g4LR7+p6ao30RhTREnEhHxmP4/R9D9/rOR/Kq14FztORty9SKgtOZUNZNMB9CXLxZ54EWu4dArUE8WdTsw=="
+ },
+ "@types/babylon": {
+ "version": "6.16.5",
+ "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz",
+ "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==",
+ "requires": {
+ "@types/babel-types": "*"
+ }
+ },
+ "@types/chai": {
+ "version": "4.2.12",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.12.tgz",
+ "integrity": "sha512-aN5IAC8QNtSUdQzxu7lGBgYAOuU1tmRU4c9dIq5OKGf/SBVjXo+ffM2wEjudAWbgpOhy60nLoAGH1xm8fpCKFQ=="
+ },
+ "@types/chai-subset": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz",
+ "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==",
+ "requires": {
+ "@types/chai": "*"
+ }
+ },
+ "@types/chalk": {
+ "version": "0.4.31",
+ "resolved": "https://registry.npmjs.org/@types/chalk/-/chalk-0.4.31.tgz",
+ "integrity": "sha1-ox10JBprHtu5c8822XooloNKUfk="
+ },
"@types/clone": {
"version": "0.1.30",
"resolved": "https://registry.npmjs.org/@types/clone/-/clone-0.1.30.tgz",
"integrity": "sha1-5zZWSMG0ITalnH1QQGN7O1yDthQ="
},
+ "@types/cssbeautify": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@types/cssbeautify/-/cssbeautify-0.3.1.tgz",
+ "integrity": "sha1-jgvuj33suVIlDaDK6+BeMFkcF+8="
+ },
+ "@types/doctrine": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.1.tgz",
+ "integrity": "sha1-uZny2fe0PKvgoaLzm8IDvH3K2p0="
+ },
+ "@types/estree": {
+ "version": "0.0.45",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz",
+ "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g=="
+ },
+ "@types/is-windows": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@types/is-windows/-/is-windows-0.2.0.tgz",
+ "integrity": "sha1-byTuSHMdMRaOpRBhDW3RXl/Jxv8="
+ },
+ "@types/minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
+ },
"@types/node": {
"version": "4.2.23",
"resolved": "https://registry.npmjs.org/@types/node/-/node-4.2.23.tgz",
@@ -257,6 +480,27 @@
}
}
},
+ "@types/path-is-inside": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@types/path-is-inside/-/path-is-inside-1.0.0.tgz",
+ "integrity": "sha512-hfnXRGugz+McgX2jxyy5qz9sB21LRzlGn24zlwN2KEgoPtEvjzNRrLtUkOOebPDPZl3Rq7ywKxYvylVcEZDnEw=="
+ },
+ "@types/resolve": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.6.tgz",
+ "integrity": "sha512-g+Rg8uMWY76oYTyaL+m7ZcblqF/oj7pE6uEUyACluJx4zcop1Lk14qQiocdEkEVMDFm6DmKpxJhsER+ZuTwG3g==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/whatwg-url": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-6.4.0.tgz",
+ "integrity": "sha512-tonhlcbQ2eho09am6RHnHOgvtDfDYINd5rgxD+2YSkKENooVCFsWizJz139MQW/PV8FfClyKrNe9ZbdHrSCxGg==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@webassemblyjs/ast": {
"version": "1.7.10",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.10.tgz",
@@ -632,6 +876,11 @@
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
},
+ "array-back": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+ "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q=="
+ },
"array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
@@ -1317,6 +1566,14 @@
}
}
},
+ "cancel-token": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/cancel-token/-/cancel-token-0.1.1.tgz",
+ "integrity": "sha1-wYGXZ0uxyEwdaTPr8V2NWlznm08=",
+ "requires": {
+ "@types/node": "^4.0.30"
+ }
+ },
"capture-stack-trace": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
@@ -1506,6 +1763,43 @@
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
"integrity": "sha1-OeAF1Uav4B4B+cTKj6UPaGoBIF0="
},
+ "command-line-args": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz",
+ "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==",
+ "requires": {
+ "array-back": "^3.0.1",
+ "find-replace": "^3.0.0",
+ "lodash.camelcase": "^4.3.0",
+ "typical": "^4.0.0"
+ }
+ },
+ "command-line-usage": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-5.0.5.tgz",
+ "integrity": "sha512-d8NrGylA5oCXSbGoKz05FkehDAzSmIm4K03S5VDh4d5lZAtTWfc3D1RuETtuQCn8129nYfJfDdF7P/lwcz1BlA==",
+ "requires": {
+ "array-back": "^2.0.0",
+ "chalk": "^2.4.1",
+ "table-layout": "^0.4.3",
+ "typical": "^2.6.1"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "requires": {
+ "typical": "^2.6.1"
+ }
+ },
+ "typical": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+ "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0="
+ }
+ }
+ },
"commander": {
"version": "2.13.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
@@ -1725,6 +2019,11 @@
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
"integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4="
},
+ "cssbeautify": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cssbeautify/-/cssbeautify-0.3.1.tgz",
+ "integrity": "sha1-Et0fc0A1wub6ymfcvc73TkKBE5c="
+ },
"currently-unhandled": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@@ -2829,6 +3128,14 @@
"pkg-dir": "^2.0.0"
}
},
+ "find-replace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
+ "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
+ "requires": {
+ "array-back": "^3.0.1"
+ }
+ },
"find-up": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
@@ -2958,8 +3265,7 @@
},
"ansi-regex": {
"version": "2.1.1",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"aproba": {
"version": "1.2.0",
@@ -2977,13 +3283,11 @@
},
"balanced-match": {
"version": "1.0.0",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2996,18 +3300,15 @@
},
"code-point-at": {
"version": "1.1.0",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"concat-map": {
"version": "0.0.1",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"console-control-strings": {
"version": "1.1.0",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"core-util-is": {
"version": "1.0.2",
@@ -3110,8 +3411,7 @@
},
"inherits": {
"version": "2.0.3",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"ini": {
"version": "1.3.5",
@@ -3121,7 +3421,6 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -3134,20 +3433,17 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -3164,7 +3460,6 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -3237,8 +3532,7 @@
},
"number-is-nan": {
"version": "1.0.1",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"object-assign": {
"version": "4.1.1",
@@ -3248,7 +3542,6 @@
"once": {
"version": "1.4.0",
"bundled": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -3324,8 +3617,7 @@
},
"safe-buffer": {
"version": "5.1.2",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -3355,7 +3647,6 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -3373,7 +3664,6 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -3412,13 +3702,11 @@
},
"wrappy": {
"version": "1.0.2",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"yallist": {
"version": "3.0.3",
- "bundled": true,
- "optional": true
+ "bundled": true
}
}
},
@@ -3808,6 +4096,11 @@
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
},
+ "indent": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/indent/-/indent-0.0.2.tgz",
+ "integrity": "sha1-jHnwgBkFWbaHA0uEx676l9WpEdk="
+ },
"indent-string": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
@@ -4342,6 +4635,11 @@
"graceful-fs": "^4.1.6"
}
},
+ "jsonschema": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.6.tgz",
+ "integrity": "sha512-SqhURKZG07JyKKeo/ir24QnS4/BV7a6gQy93bUSe4lUdNp0QNpIz2c9elWJQ9dpc5cQYY6cvCzgRwy0MQCLyqA=="
+ },
"just-extend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz",
@@ -4544,11 +4842,26 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40="
},
+ "lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
+ },
"lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
},
+ "lodash.padend": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
+ "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4="
+ },
+ "lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
+ },
"log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
@@ -4629,6 +4942,14 @@
"yallist": "^2.1.2"
}
},
+ "magic-string": {
+ "version": "0.22.5",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz",
+ "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==",
+ "requires": {
+ "vlq": "^0.2.2"
+ }
+ },
"make-dir": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
@@ -5458,6 +5779,169 @@
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
"integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c="
},
+ "polymer-analyzer": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/polymer-analyzer/-/polymer-analyzer-3.2.4.tgz",
+ "integrity": "sha512-JmxUhMajTuC18tLXbTtu2+aN2x9bTX+4MvCD4IZKJ0rtAL8jWi1iRLfogpHJB4Ig9Dc8EEEuEYipLuzPFl3vqA==",
+ "requires": {
+ "@babel/generator": "^7.0.0-beta.42",
+ "@babel/traverse": "^7.0.0-beta.42",
+ "@babel/types": "^7.0.0-beta.42",
+ "@types/babel-generator": "^6.25.1",
+ "@types/babel-traverse": "^6.25.2",
+ "@types/babel-types": "^6.25.1",
+ "@types/babylon": "^6.16.2",
+ "@types/chai-subset": "^1.3.0",
+ "@types/chalk": "^0.4.30",
+ "@types/clone": "^0.1.30",
+ "@types/cssbeautify": "^0.3.1",
+ "@types/doctrine": "^0.0.1",
+ "@types/is-windows": "^0.2.0",
+ "@types/minimatch": "^3.0.1",
+ "@types/parse5": "^2.2.34",
+ "@types/path-is-inside": "^1.0.0",
+ "@types/resolve": "0.0.6",
+ "@types/whatwg-url": "^6.4.0",
+ "babylon": "^7.0.0-beta.42",
+ "cancel-token": "^0.1.1",
+ "chalk": "^1.1.3",
+ "clone": "^2.0.0",
+ "cssbeautify": "^0.3.1",
+ "doctrine": "^2.0.2",
+ "dom5": "^3.0.0",
+ "indent": "0.0.2",
+ "is-windows": "^1.0.2",
+ "jsonschema": "^1.1.0",
+ "minimatch": "^3.0.4",
+ "parse5": "^4.0.0",
+ "path-is-inside": "^1.0.2",
+ "resolve": "^1.5.0",
+ "shady-css-parser": "^0.1.0",
+ "stable": "^0.1.6",
+ "strip-indent": "^2.0.0",
+ "vscode-uri": "=1.0.6",
+ "whatwg-url": "^6.4.0"
+ },
+ "dependencies": {
+ "@types/babel-types": {
+ "version": "6.25.2",
+ "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-6.25.2.tgz",
+ "integrity": "sha512-+3bMuktcY4a70a0KZc8aPJlEOArPuAKQYHU5ErjkOqGJdx8xuEEVK6nWogqigBOJ8nKPxRpyCUDTCPmZ3bUxGA=="
+ },
+ "@types/parse5": {
+ "version": "2.2.34",
+ "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-2.2.34.tgz",
+ "integrity": "sha1-44cKEOgnNacg9i1x3NGDunjvOp0=",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "babylon": {
+ "version": "7.0.0-beta.47",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.47.tgz",
+ "integrity": "sha512-+rq2cr4GDhtToEzKFD6KZZMDBXhjFAr9JjPw9pAppZACeEWqNM294j+NdBzkSHYXwzzBmVjZ3nEVJlOhbR2gOQ=="
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
+ },
+ "dom5": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dom5/-/dom5-3.0.1.tgz",
+ "integrity": "sha512-JPFiouQIr16VQ4dX6i0+Hpbg3H2bMKPmZ+WZgBOSSvOPx9QHwwY8sPzeM2baUtViESYto6wC2nuZOMC/6gulcA==",
+ "requires": {
+ "@types/parse5": "^2.2.34",
+ "clone": "^2.1.0",
+ "parse5": "^4.0.0"
+ }
+ },
+ "parse5": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
+ "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA=="
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
+ }
+ },
+ "polymer-bundler": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/polymer-bundler/-/polymer-bundler-4.0.10.tgz",
+ "integrity": "sha512-nwlN3LQlQDqbZ2sUH3394C/dHZUDHq8tpdS5HARvPDb0Q9IXWD+znOR1cr7wSjF0EZN4LiUH5hWyUoV4QSjhpQ==",
+ "requires": {
+ "@types/babel-generator": "^6.25.1",
+ "@types/babel-traverse": "^6.25.3",
+ "babel-generator": "^6.26.1",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "clone": "^2.1.0",
+ "command-line-args": "^5.0.2",
+ "command-line-usage": "^5.0.5",
+ "dom5": "^3.0.0",
+ "espree": "^3.5.2",
+ "magic-string": "^0.22.4",
+ "mkdirp": "^0.5.1",
+ "parse5": "^4.0.0",
+ "polymer-analyzer": "^3.2.2",
+ "rollup": "^1.3.0",
+ "source-map": "^0.5.6",
+ "vscode-uri": "=1.0.6"
+ },
+ "dependencies": {
+ "@types/parse5": {
+ "version": "2.2.34",
+ "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-2.2.34.tgz",
+ "integrity": "sha1-44cKEOgnNacg9i1x3NGDunjvOp0=",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
+ },
+ "dom5": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dom5/-/dom5-3.0.1.tgz",
+ "integrity": "sha512-JPFiouQIr16VQ4dX6i0+Hpbg3H2bMKPmZ+WZgBOSSvOPx9QHwwY8sPzeM2baUtViESYto6wC2nuZOMC/6gulcA==",
+ "requires": {
+ "@types/parse5": "^2.2.34",
+ "clone": "^2.1.0",
+ "parse5": "^4.0.0"
+ }
+ },
+ "parse5": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
+ "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA=="
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
+ }
+ },
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@@ -5745,6 +6229,11 @@
"strip-indent": "^2.0.0"
}
},
+ "reduce-flatten": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
+ "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc="
+ },
"redux": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.0.1.tgz",
@@ -5896,6 +6385,23 @@
"inherits": "^2.0.1"
}
},
+ "rollup": {
+ "version": "1.32.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz",
+ "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==",
+ "requires": {
+ "@types/estree": "*",
+ "@types/node": "*",
+ "acorn": "^7.1.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
+ "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w=="
+ }
+ }
+ },
"run-async": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
@@ -6033,6 +6539,11 @@
"safe-buffer": "^5.0.1"
}
},
+ "shady-css-parser": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/shady-css-parser/-/shady-css-parser-0.1.0.tgz",
+ "integrity": "sha512-irfJUUkEuDlNHKZNAp2r7zOyMlmbfVJ+kWSfjlCYYUx/7dJnANLCyTzQZsuxy5NJkvtNwSxY5Gj8MOlqXUQPyA=="
+ },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -6325,6 +6836,11 @@
"safe-buffer": "^5.1.1"
}
},
+ "stable": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w=="
+ },
"static-extend": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
@@ -6471,6 +6987,33 @@
"string-width": "^2.1.1"
}
},
+ "table-layout": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
+ "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
+ "requires": {
+ "array-back": "^2.0.0",
+ "deep-extend": "~0.6.0",
+ "lodash.padend": "^4.6.1",
+ "typical": "^2.6.1",
+ "wordwrapjs": "^3.0.0"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "requires": {
+ "typical": "^2.6.1"
+ }
+ },
+ "typical": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+ "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0="
+ }
+ }
+ },
"tapable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.0.tgz",
@@ -6587,6 +7130,14 @@
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM="
},
+ "tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
"trim-newlines": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz",
@@ -6634,6 +7185,11 @@
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
},
+ "typical": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
+ "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw=="
+ },
"uglify-es": {
"version": "3.3.9",
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
@@ -6880,6 +7436,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "vlq": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz",
+ "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow=="
+ },
"vm-browserify": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
@@ -6893,6 +7454,11 @@
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
"integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
},
+ "vscode-uri": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz",
+ "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww=="
+ },
"vulcanize": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/vulcanize/-/vulcanize-1.16.0.tgz",
@@ -6923,6 +7489,11 @@
"defaults": "^1.0.3"
}
},
+ "webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
+ },
"webpack": {
"version": "4.23.1",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.23.1.tgz",
@@ -7067,6 +7638,16 @@
"source-map": "~0.6.1"
}
},
+ "whatwg-url": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
+ "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
+ "requires": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -7088,6 +7669,22 @@
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
},
+ "wordwrapjs": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
+ "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
+ "requires": {
+ "reduce-flatten": "^1.0.1",
+ "typical": "^2.6.1"
+ },
+ "dependencies": {
+ "typical": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+ "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0="
+ }
+ }
+ },
"worker-farm": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",
diff --git a/catapult/common/py_utils/py_utils/chrome_binaries.json b/catapult/common/py_utils/py_utils/chrome_binaries.json
index badb3642..03f0afd3 100644
--- a/catapult/common/py_utils/py_utils/chrome_binaries.json
+++ b/catapult/common/py_utils/py_utils/chrome_binaries.json
@@ -12,16 +12,16 @@
"version_in_cs": "85.0.4169.0"
},
"win_AMD64": {
- "cloud_storage_hash": "c0b02f47afb6bacdd8d12eda6f03488583404b60",
+ "cloud_storage_hash": "121271e6e917886bd2e5b539dd643e74a3aae395",
"download_path": "bin\\reference_build\\chrome-win64-clang.zip",
"path_within_archive": "chrome-win64-clang\\chrome.exe",
- "version_in_cs": "85.0.4169.0"
+ "version_in_cs": "86.0.4240.111"
},
"win_x86": {
- "cloud_storage_hash": "5879958eda4edc5b0eaffeda4c7369a07937af73",
+ "cloud_storage_hash": "83e9d11b28d01c10bbcccb7b882288b192b5e756",
"download_path": "bin\\reference_build\\chrome-win32-clang.zip",
"path_within_archive": "chrome-win32-clang\\chrome.exe",
- "version_in_cs": "85.0.4169.0"
+ "version_in_cs": "86.0.4240.111"
}
}
},
@@ -169,4 +169,4 @@
}
}
}
-} \ No newline at end of file
+}
diff --git a/catapult/common/py_utils/py_utils/cloud_storage.py b/catapult/common/py_utils/py_utils/cloud_storage.py
index a359a065..919add69 100644
--- a/catapult/common/py_utils/py_utils/cloud_storage.py
+++ b/catapult/common/py_utils/py_utils/cloud_storage.py
@@ -192,10 +192,33 @@ def IsNetworkIOEnabled():
return disable_cloud_storage_env_val != '1'
-def List(bucket):
- query = 'gs://%s/' % bucket
- stdout = _RunCommand(['ls', query])
- return [url[len(query):] for url in stdout.splitlines()]
+def List(bucket, prefix=None):
+ """Returns all paths matching the given prefix in bucket.
+
+ Returned paths are relative to the bucket root.
+ If path is given, 'gsutil ls gs://<bucket>/<path>' will be executed, otherwise
+ 'gsutil ls gs://<bucket>' will be executed.
+
+ For more details, see:
+ https://cloud.google.com/storage/docs/gsutil/commands/ls#directory-by-directory,-flat,-and-recursive-listings
+
+ Args:
+ bucket: Name of cloud storage bucket to look at.
+ prefix: Path within the bucket to filter to.
+
+ Returns:
+ A list of files. All returned path are relative to the bucket root
+ directory. For example, List('my-bucket', path='foo/') will returns results
+ of the form ['/foo/123', '/foo/124', ...], as opposed to ['123', '124',
+ ...].
+ """
+ bucket_prefix = 'gs://%s' % bucket
+ if prefix is None:
+ full_path = bucket_prefix
+ else:
+ full_path = '%s/%s' % (bucket_prefix, prefix)
+ stdout = _RunCommand(['ls', full_path])
+ return [url[len(bucket_prefix):] for url in stdout.splitlines()]
def ListDirs(bucket, path=''):
diff --git a/catapult/common/py_utils/py_utils/cloud_storage_unittest.py b/catapult/common/py_utils/py_utils/cloud_storage_unittest.py
index 2e663a76..afd03945 100644
--- a/catapult/common/py_utils/py_utils/cloud_storage_unittest.py
+++ b/catapult/common/py_utils/py_utils/cloud_storage_unittest.py
@@ -171,6 +171,24 @@ class CloudStorageFakeFsUnitTest(BaseFakeFsUnitTest):
cloud_storage._RunCommand = orig_run_command
@mock.patch('py_utils.cloud_storage._RunCommand')
+ def testListNoPrefix(self, mock_run_command):
+ mock_run_command.return_value = '\n'.join(['gs://bucket/foo-file.txt',
+ 'gs://bucket/foo1/',
+ 'gs://bucket/foo2/'])
+
+ self.assertEqual(cloud_storage.List('bucket'),
+ ['/foo-file.txt', '/foo1/', '/foo2/'])
+
+ @mock.patch('py_utils.cloud_storage._RunCommand')
+ def testListWithPrefix(self, mock_run_command):
+ mock_run_command.return_value = '\n'.join(['gs://bucket/foo/foo-file.txt',
+ 'gs://bucket/foo/foo1/',
+ 'gs://bucket/foo/foo2/'])
+
+ self.assertEqual(cloud_storage.List('bucket', 'foo'),
+ ['/foo/foo-file.txt', '/foo/foo1/', '/foo/foo2/'])
+
+ @mock.patch('py_utils.cloud_storage._RunCommand')
def testListDirs(self, mock_run_command):
mock_run_command.return_value = '\n'.join(['gs://bucket/foo-file.txt',
'',
diff --git a/catapult/common/py_utils/py_utils/ts_proxy_server.py b/catapult/common/py_utils/py_utils/ts_proxy_server.py
index b71d143d..0e168a53 100644
--- a/catapult/common/py_utils/py_utils/ts_proxy_server.py
+++ b/catapult/common/py_utils/py_utils/ts_proxy_server.py
@@ -196,11 +196,13 @@ class TsProxyServer(object):
try:
py_utils.WaitFor(lambda: self._proc.poll() is not None, 10)
except py_utils.TimeoutException:
- try:
- # Use a SIGNINT so that it can do graceful cleanup
- self._proc.send_signal(signal.SIGINT)
- except ValueError:
- logging.warning('Unable to stop ts_proxy_server gracefully.\n')
+ # signal.SIGINT is not supported on Windows.
+ if not sys.platform.startswith('win'):
+ try:
+ # Use a SIGNINT so that it can do graceful cleanup
+ self._proc.send_signal(signal.SIGINT)
+ except ValueError:
+ logging.warning('Unable to stop ts_proxy_server gracefully.\n')
self._proc.terminate()
_, err = self._proc.communicate()
diff --git a/catapult/common/py_utils/py_utils/webpagereplay_go_server.py b/catapult/common/py_utils/py_utils/webpagereplay_go_server.py
index 950e8adc..95e44954 100644
--- a/catapult/common/py_utils/py_utils/webpagereplay_go_server.py
+++ b/catapult/common/py_utils/py_utils/webpagereplay_go_server.py
@@ -17,7 +17,6 @@ import py_utils
from py_utils import atexit_with_log
from py_utils import binary_manager
-
_WPR_DIR = os.path.abspath(os.path.join(
py_utils.GetCatapultDir(), 'web_page_replay_go'))
@@ -31,6 +30,8 @@ CHROME_BINARY_CONFIG = os.path.join(
RECORD = '--record'
INJECT_SCRIPTS = '--inject_scripts='
+USE_LOCAL_WPR = '--use-local-wpr'
+DISABLE_FUZZY_URL_MATCHING = '--disable-fuzzy-url-matching'
class ReplayError(Exception):
"""Catch-all exception for the module."""
@@ -102,16 +103,10 @@ class ReplayServer(object):
# subprocess.
self._temp_log_file_path = None
- # Assign the downloader func and binary_manager
- downloader = None
- if binary_downloader:
- downloader = binary_downloader
- else:
- configs = [CHROME_BINARY_CONFIG, TELEMETRY_PROJECT_CONFIG]
- downloader = binary_manager.BinaryManager(configs).FetchPath
-
+ self._downloader = binary_downloader
+ self._replay_options = replay_options
self._cmd_line = self._GetCommandLine(
- self._GetGoBinaryPath(downloader=downloader), http_port, https_port,
+ self._GetGoBinaryPath(replay_options), http_port, https_port,
replay_options, archive_path)
if RECORD in replay_options or 'record' in replay_options:
@@ -122,19 +117,57 @@ class ReplayServer(object):
self.replay_process = None
- @classmethod
- def _GetGoBinaryPath(cls, downloader):
- if not cls._go_binary_path:
- cls._go_binary_path = downloader(
+ def _GetDownloader(self):
+ """Gets the downloader used to download wpr_go binary from GCS."""
+ if ReplayServer._go_binary_path:
+ # If the _go_binary_path was already set, then no need to use downloader
+ # to download via binary_manager.
+ self._downloader = None
+ elif not self._downloader:
+ configs = [CHROME_BINARY_CONFIG, TELEMETRY_PROJECT_CONFIG]
+ self._downloader = binary_manager.BinaryManager(configs).FetchPath
+ return self._downloader
+
+ def _GetGoBinaryPath(self, replay_options):
+ """Gets the _go_binary_path if it already set, or downloads it."""
+ if USE_LOCAL_WPR in replay_options:
+ # Build WPR
+ go_folder = os.path.join(_WPR_DIR, 'src')
+ cur_cwd = os.getcwd()
+ os.chdir(go_folder)
+ try:
+ print subprocess.check_output(['go', 'build', os.path.join(go_folder, 'wpr.go')])
+ except subprocess.CalledProcessError:
+ exit(1)
+ os.chdir(cur_cwd)
+
+ return os.path.join(go_folder, 'wpr')
+
+ if not ReplayServer._go_binary_path:
+ downloader = self._GetDownloader()
+ if not downloader:
+ raise RuntimeError('downloader should not be None '
+ 'while _go_binary_path is None')
+ ReplayServer._go_binary_path = downloader(
'wpr_go', py_utils.GetHostOsName(), py_utils.GetHostArchName())
- return cls._go_binary_path
+ return ReplayServer._go_binary_path
@classmethod
def SetGoBinaryPath(cls, go_binary_path):
"""Overrides the _go_binary_path.
This allows the server to use WPRGO files retrieved from somewhere
- other than GCS, such as CIPD."""
+ other than GCS via binary_manager, such as test isolation.
+
+ For chromium project to use WPR, it is encourage to use test isolation,
+ and therefore should call SetGoBinaryPath to set _go_binary_path.
+
+ For Catapult/Telemetry project, the tradition is to download wpr_go
+ binary via binary_manager. So do not call SetGoBinaryPath.
+ """
+ if not os.path.exists(go_binary_path):
+ raise ValueError('SetGoBinaryPath could not set {} as it does not exist'
+ .format(go_binary_path))
cls._go_binary_path = go_binary_path
@property
@@ -162,7 +195,8 @@ class ReplayServer(object):
"""
bad_options = []
for option in options:
- if option not in [RECORD, INJECT_SCRIPTS]:
+ if option not in [RECORD, INJECT_SCRIPTS,
+ USE_LOCAL_WPR, DISABLE_FUZZY_URL_MATCHING]:
bad_options.append(option)
if len(bad_options) > 0:
raise ValueError("Invalid replay options %s" % bad_options)
@@ -172,6 +206,8 @@ class ReplayServer(object):
cmd_line.append('record')
else:
cmd_line.append('replay')
+ if DISABLE_FUZZY_URL_MATCHING in options:
+ cmd_line.append('--disable_fuzzy_url_matching')
key_file = os.path.join(_WPR_DIR, 'wpr_key.pem')
cert_file = os.path.join(_WPR_DIR, 'wpr_cert.pem')
inject_script = os.path.join(_WPR_DIR, 'deterministic.js')
@@ -347,13 +383,17 @@ class ReplayServer(object):
def _CleanUpTempLogFilePath(self, log_level):
if not self._temp_log_file_path:
return ''
- if logging.getLogger('').isEnabledFor(log_level):
+ if logging.getLogger('').isEnabledFor(log_level) or USE_LOCAL_WPR in self._replay_options:
with open(self._temp_log_file_path, 'r') as f:
wpr_log_output = f.read()
- logging.log(log_level, '\n'.join([
- '************************** WPR LOG *****************************',
- wpr_log_output,
- '************************** END OF WPR LOG **********************']))
+ output = ('************************** WPR LOG *****************************\n' +
+ '\n'.join(wpr_log_output.split('\n')) +
+ '************************** END OF WPR LOG **********************')
+ if logging.getLogger('').isEnabledFor(log_level):
+ logging.log(log_level, output)
+ else:
+ print output
+
os.remove(self._temp_log_file_path)
self._temp_log_file_path = None
diff --git a/catapult/dependency_manager/dependency_manager/__init__.py b/catapult/dependency_manager/dependency_manager/__init__.py
index 84cca5a2..3b18f06a 100644
--- a/catapult/dependency_manager/dependency_manager/__init__.py
+++ b/catapult/dependency_manager/dependency_manager/__init__.py
@@ -15,7 +15,7 @@ DEPENDENCY_MANAGER_PATH = os.path.join(CATAPULT_PATH, 'dependency_manager')
def _AddDirToPythonPath(*path_parts):
path = os.path.abspath(os.path.join(*path_parts))
if os.path.isdir(path) and path not in sys.path:
- sys.path.append(path)
+ sys.path.insert(0, path)
_AddDirToPythonPath(CATAPULT_PATH, 'common', 'py_utils')
diff --git a/catapult/devil/bin/generate_md_docs b/catapult/devil/bin/generate_md_docs
index 1cca44c1..d1dbf06f 100755
--- a/catapult/devil/bin/generate_md_docs
+++ b/catapult/devil/bin/generate_md_docs
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env vpython
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/catapult/devil/bin/run_py_devicetests b/catapult/devil/bin/run_py_devicetests
index 6a6da188..9329f3a8 100755
--- a/catapult/devil/bin/run_py_devicetests
+++ b/catapult/devil/bin/run_py_devicetests
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env vpython
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/catapult/devil/bin/run_py_tests b/catapult/devil/bin/run_py_tests
index 112451c6..be245c6c 100755
--- a/catapult/devil/bin/run_py_tests
+++ b/catapult/devil/bin/run_py_tests
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env vpython
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/catapult/devil/build/cipd.yaml b/catapult/devil/build/cipd.yaml
index fcb4db3b..204400a9 100644
--- a/catapult/devil/build/cipd.yaml
+++ b/catapult/devil/build/cipd.yaml
@@ -1,3 +1,9 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# To create CIPD package run the following command.
+# cipd create --pkg-def cipd.yaml -ref latest
package: chromium/third_party/catapult/devil/${platform}
description: All of devil along with its dependencies in catapult.
@@ -11,4 +17,5 @@ data:
- dir: common/py_utils
- dir: dependency_manager
- dir: devil
+ - dir: third_party/gsutil
- dir: third_party/zipfile
diff --git a/catapult/devil/devil/android/device_blacklist.py b/catapult/devil/devil/android/device_blacklist.py
deleted file mode 100644
index 7112204e..00000000
--- a/catapult/devil/devil/android/device_blacklist.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from devil.android import device_denylist
-
-# TODO(crbug.com/1097306): Remove this (and this file) once existing uses
-# have switched to using device_denylist directly.
-Blacklist = device_denylist.Denylist
diff --git a/catapult/devil/devil/android/device_errors.py b/catapult/devil/devil/android/device_errors.py
index d1454683..6e710876 100644
--- a/catapult/devil/devil/android/device_errors.py
+++ b/catapult/devil/devil/android/device_errors.py
@@ -14,6 +14,7 @@ The class hierarchy for device exceptions is:
| +-- FastbootCommandFailedError
| +-- DeviceVersionError
| +-- DeviceChargingError
+ | +-- RootUserBuildError
+-- CommandTimeoutError
+-- DeviceUnreachableError
+-- NoDevicesError
@@ -228,3 +229,11 @@ class DeviceChargingError(CommandFailedError):
def __init__(self, message, device_serial=None):
super(DeviceChargingError, self).__init__(message, device_serial)
+
+
+class RootUserBuildError(CommandFailedError):
+ """Exception for being unable to root a device with "user" build."""
+
+ def __init__(self, message=None, device_serial=None):
+ super(RootUserBuildError, self).__init__(
+ message or 'Unable to root device with user build.', device_serial)
diff --git a/catapult/devil/devil/android/device_utils.py b/catapult/devil/devil/android/device_utils.py
index 0a041edb..7b7dad24 100644
--- a/catapult/devil/devil/android/device_utils.py
+++ b/catapult/devil/devil/android/device_utils.py
@@ -45,7 +45,8 @@ from devil.utils import reraiser_thread
from devil.utils import timeout_retry
from devil.utils import zip_utils
-from py_utils import tempfile_ext
+with devil_env.SysPath(devil_env.PY_UTILS_PATH):
+ from py_utils import tempfile_ext
try:
from devil.utils import reset_usb
@@ -132,6 +133,7 @@ _PERMISSIONS_DENYLIST_RE = re.compile('|'.join(
'android.permission.MANAGE_ACCOUNTS',
'android.permission.MODIFY_AUDIO_SETTINGS',
'android.permission.NFC',
+ 'android.permission.QUERY_ALL_PACKAGES',
'android.permission.READ_SYNC_SETTINGS',
'android.permission.READ_SYNC_STATS',
'android.permission.RECEIVE_BOOT_COMPLETED',
@@ -277,6 +279,15 @@ _WEBVIEW_SYSUPDATE_MIN_VERSION_CODE = re.compile(
_GOOGLE_FEATURES_RE = re.compile(r'^\s*com\.google\.')
+_EMULATOR_RE = re.compile(r'^generic_.*$')
+
+# Regular expressions for determining if a package is installed using the
+# output of `dumpsys package`.
+# Matches lines like "Package [com.google.android.youtube] (c491050):".
+# or "Package [org.chromium.trichromelibrary_425300033] (e476383):"
+_DUMPSYS_PACKAGE_RE_STR =\
+ r'^\s*Package\s*\[%s(_(?P<version_code>\d*))?\]\s*\(\w*\):$'
+
PS_COLUMNS = ('name', 'pid', 'ppid')
ProcessInfo = collections.namedtuple('ProcessInfo', PS_COLUMNS)
@@ -556,22 +567,14 @@ class DeviceUtils(object):
CommandTimeoutError on timeout.
DeviceUnreachableError on missing device.
"""
- try:
- if self.build_type == 'eng':
- # 'eng' builds have root enabled by default and the adb session cannot
- # be unrooted.
- return True
- # Devices using the system-as-root partition layout appear to not have
- # a /root directory. See http://bit.ly/37F34sx for more context.
- if (self.build_system_root_image == 'true'
- or self.build_version_sdk >= version_codes.Q
- # This may be redundant with the checks above.
- or self.product_name in _SPECIAL_ROOT_DEVICE_LIST):
- return self.GetProp('service.adb.root') == '1'
- self.RunShellCommand(['ls', '/root'], check_return=True)
+ if self.build_type == 'eng':
+ # 'eng' builds have root enabled by default and the adb session cannot
+ # be unrooted.
return True
- except device_errors.AdbCommandFailedError:
- return False
+ # Check if uid is 0. Such behavior has remained unchanged since
+ # android 2.2.3 (https://bit.ly/2QQzg67)
+ output = self.RunShellCommand(['id'], single_line=True)
+ return output.startswith('uid=0(root)')
def NeedsSU(self, timeout=DEFAULT, retries=DEFAULT):
"""Checks whether 'su' is needed to access protected resources.
@@ -638,8 +641,7 @@ class DeviceUtils(object):
self.adb.Root()
except device_errors.AdbCommandFailedError as e:
if self.IsUserBuild():
- raise device_errors.CommandFailedError(
- 'Unable to root device with user build.', str(self))
+ raise device_errors.RootUserBuildError(device_serial=str(self))
elif e.output and _WAIT_FOR_DEVICE_TIMEOUT_STR in e.output:
# adb 1.0.41 added a call to wait-for-device *inside* root
# with a timeout that can be too short in some cases.
@@ -768,21 +770,50 @@ class DeviceUtils(object):
raise device_errors.CommandFailedError('Unable to fetch IMEI.')
@decorators.WithTimeoutAndRetriesFromInstance()
- def IsApplicationInstalled(self, package, timeout=None, retries=None):
+ def IsApplicationInstalled(
+ self, package, version_code=None, timeout=None, retries=None):
"""Determines whether a particular package is installed on the device.
Args:
package: Name of the package.
+ version_code: The version of the package to check for as an int, if
+ applicable. Only used for static shared libraries, otherwise ignored.
Returns:
True if the application is installed, False otherwise.
"""
- # `pm list packages` allows matching substrings, but we want exact matches
- # only.
- matching_packages = self.RunShellCommand(
- ['pm', 'list', 'packages', package], check_return=True)
- desired_line = 'package:' + package
- return desired_line in matching_packages
+ # `pm list packages` doesn't include the version code, so if it was
+ # provided, skip this since we can't guarantee that the installed
+ # version is the requested version.
+ if version_code is None:
+ # `pm list packages` allows matching substrings, but we want exact matches
+ # only.
+ matching_packages = self.RunShellCommand(
+ ['pm', 'list', 'packages', package], check_return=True)
+ desired_line = 'package:' + package
+ found_package = desired_line in matching_packages
+ if found_package:
+ return True
+
+ # Some packages do not properly show up via `pm list packages`, so fall back
+ # to checking via `dumpsys package`.
+ matcher = re.compile(_DUMPSYS_PACKAGE_RE_STR % package)
+ dumpsys_output = self.RunShellCommand(
+ ['dumpsys', 'package'], check_return=True, large_output=True)
+ for line in dumpsys_output:
+ match = matcher.match(line)
+ # We should have one of these cases:
+ # 1. The package is a regular app, in which case it will show up without
+ # its version code in the line we're filtering for.
+ # 2. The package is a static shared library, in which case one or more
+ # entries with the version code can show up, but not one without the
+ # version code.
+ if match:
+ installed_version_code = match.groupdict().get('version_code')
+ if (installed_version_code is None
+ or installed_version_code == str(version_code)):
+ return True
+ return False
@decorators.WithTimeoutAndRetriesFromInstance()
def GetApplicationPaths(self, package, timeout=None, retries=None):
@@ -1062,6 +1093,10 @@ class DeviceUtils(object):
retries=None):
"""Reboot the device.
+ Note if the device has the root privilege, it will likely lose it after the
+ reboot. When |block| is True, it will try to restore the root status if
+ applicable.
+
Args:
block: A boolean indicating if we should wait for the reboot to complete.
wifi: A boolean indicating if we should wait for wifi to be enabled after
@@ -1081,11 +1116,15 @@ class DeviceUtils(object):
def device_offline():
return not self.IsOnline()
+ # Only check the root when block is True
+ should_restore_root = self.HasRoot() if block else False
self.adb.Reboot()
self.ClearCache()
timeout_retry.WaitFor(device_offline, wait_period=1)
if block:
self.WaitUntilFullyBooted(wifi=wifi, decrypt=decrypt)
+ if should_restore_root:
+ self.EnableRoot()
INSTALL_DEFAULT_TIMEOUT = 8 * _DEFAULT_TIMEOUT
MODULES_SRC_DIRECTORY_PATH = '/data/local/tmp/modules'
@@ -1282,6 +1321,7 @@ class DeviceUtils(object):
apks_to_install = apk_paths
if device_apk_paths and apks_to_install and not reinstall:
+ logger.info('Uninstalling package %s', package_name)
self.Uninstall(package_name)
if apks_to_install:
@@ -1292,6 +1332,8 @@ class DeviceUtils(object):
streaming = None
if self.product_name in _NO_STREAMING_DEVICE_LIST:
streaming = False
+ logger.info('Installing package %s using APKs %s',
+ package_name, apks_to_install)
if len(apks_to_install) > 1 or partial:
self.adb.InstallMultiple(
apks_to_install,
@@ -1306,10 +1348,20 @@ class DeviceUtils(object):
streaming=streaming,
allow_downgrade=allow_downgrade)
else:
+ logger.info('Skipping installation of package %s', package_name)
# Running adb install terminates running instances of the app, so to be
# consistent, we explicitly terminate it when skipping the install.
self.ForceStop(package_name)
+ # There have been cases of APKs not being detected after being explicitly
+ # installed, so perform a sanity check now and fail early if the
+ # installation somehow failed.
+ apk_version = apk.GetVersionCode()
+ if not self.IsApplicationInstalled(package_name, apk_version):
+ raise device_errors.CommandFailedError(
+ 'Package %s with version %s not installed on device after explicit '
+ 'install attempt.' % (package_name, apk_version))
+
if (permissions is None
and self.build_version_sdk >= version_codes.MARSHMALLOW):
permissions = apk.GetPermissions()
@@ -2045,9 +2097,14 @@ class DeviceUtils(object):
def _ComputeDeviceChecksumsForApks(self, package_name):
ret = self._cache['package_apk_checksums'].get(package_name)
if ret is None:
- device_paths = self._GetApplicationPathsInternal(package_name)
- file_to_checksums = md5sum.CalculateDeviceMd5Sums(device_paths, self)
- ret = set(file_to_checksums.values())
+ if self.PathExists('/data/data/' + package_name, as_root=True):
+ device_paths = self._GetApplicationPathsInternal(package_name)
+ file_to_checksums = md5sum.CalculateDeviceMd5Sums(device_paths, self)
+ ret = set(file_to_checksums.values())
+ else:
+ logger.info('Cannot reuse package %s (data directory missing)',
+ package_name)
+ ret = set()
self._cache['package_apk_checksums'][package_name] = ret
return ret
@@ -2720,11 +2777,16 @@ class DeviceUtils(object):
@property
def pixel_density(self):
density = self.GetProp('ro.sf.lcd_density', cache=True)
- if not density and self.adb.is_emulator:
+ if not density:
+ # It might be an emulator, try the qemu prop.
density = self.GetProp('qemu.sf.lcd_density', cache=True)
return int(density)
@property
+ def is_emulator(self):
+ return _EMULATOR_RE.match(self.GetProp('ro.product.device', cache=True))
+
+ @property
def build_description(self):
"""Returns the build description of the system.
@@ -3186,11 +3248,12 @@ class DeviceUtils(object):
WebViewPackages: Dict of installed WebView providers, mapping "package
name" to "reason it's valid/invalid."
- It may return an empty dictionary if device does not
- support the "dumpsys webviewupdate" command.
+ The returned dictionary may not include all of the above keys: this depends
+ on the support of the platform's underlying WebViewUpdateService. This may
+ return an empty dictionary on OS versions which do not support querying the
+ WebViewUpdateService.
Raises:
- CommandFailedError on failure.
CommandTimeoutError on timeout.
DeviceUnreachableError on missing device.
"""
@@ -3229,12 +3292,6 @@ class DeviceUtils(object):
result['MinimumWebViewVersionCode'] = int(match.group(1))
if webview_packages:
result['WebViewPackages'] = webview_packages
-
- missing_fields = set(['CurrentWebViewPackage', 'FallbackLogicEnabled']) - \
- set(result.keys())
- if len(missing_fields) > 0:
- raise device_errors.CommandFailedError(
- '%s not found in dumpsys webviewupdate' % str(list(missing_fields)))
return result
@decorators.WithTimeoutAndRetriesFromInstance()
@@ -3552,9 +3609,6 @@ class DeviceUtils(object):
retries=1,
enable_usb_resets=False,
abis=None,
- # TODO(crbug.com/1097306): Remove this once clients have
- # stopped passing it.
- blacklist=None,
**kwargs):
"""Returns a list of DeviceUtils instances.
@@ -3607,10 +3661,6 @@ class DeviceUtils(object):
if device_arg:
device_arg = (device_arg, )
- # TODO(crbug.com/1097306): Remove this once clients have switched.
- if blacklist and not denylist:
- denylist = blacklist
-
denylisted_devices = denylist.Read() if denylist else []
# adb looks for ANDROID_SERIAL, so support it as well.
diff --git a/catapult/devil/devil/android/device_utils_test.py b/catapult/devil/devil/android/device_utils_test.py
index 38e64a97..62313c5b 100755
--- a/catapult/devil/devil/android/device_utils_test.py
+++ b/catapult/devil/devil/android/device_utils_test.py
@@ -31,8 +31,7 @@ from devil.android.sdk import version_codes
from devil.utils import cmd_helper
from devil.utils import mock_calls
-with devil_env.SysPath(
- os.path.join(devil_env.CATAPULT_ROOT_PATH, 'common', 'py_utils')):
+with devil_env.SysPath(os.path.join(devil_env.PY_UTILS_PATH)):
from py_utils import tempfile_ext
with devil_env.SysPath(devil_env.PYMOCK_PATH):
@@ -80,6 +79,7 @@ class _MockApkHelper(object):
self.perms = perms
self.splits = splits if splits else []
self.abis = [abis.ARM]
+ self.version_code = None
def GetPackageName(self):
return self.package_name
@@ -87,6 +87,9 @@ class _MockApkHelper(object):
def GetPermissions(self):
return self.perms
+ def GetVersionCode(self):
+ return self.version_code
+
def GetAbis(self):
return self.abis
@@ -332,119 +335,21 @@ class DeviceUtilsIsOnlineTest(DeviceUtilsTest):
class DeviceUtilsHasRootTest(DeviceUtilsTest):
def testHasRoot_true(self):
- with self.patch_call(
- self.call.device.build_type,
- return_value='userdebug'), (self.patch_call(
- self.call.device.build_system_root_image,
- return_value='')), (self.patch_call(
- self.call.device.build_version_sdk,
- return_value=version_codes.PIE)), (self.patch_call(
- self.call.device.product_name,
- return_value='notasailfish')), (self.assertCall(
- self.call.adb.Shell('ls /root'), 'foo\n')):
- self.assertTrue(self.device.HasRoot())
-
- def testhasRootSpecial_true(self):
- with self.patch_call(
- self.call.device.build_type,
- return_value='userdebug'), (self.patch_call(
- self.call.device.build_system_root_image,
- return_value='')), (self.patch_call(
- self.call.device.build_version_sdk,
- return_value=version_codes.PIE)), (self.patch_call(
- self.call.device.product_name,
- return_value='sailfish')), (self.assertCall(
- self.call.adb.Shell('getprop service.adb.root'),
- '1\n')):
+ with self.patch_call(self.call.device.build_type,
+ return_value='userdebug'), (self.assertCall(
+ self.call.adb.Shell('id'), 'uid=0(root)\n')):
self.assertTrue(self.device.HasRoot())
- def testhasRootSpecialAosp_true(self):
- with self.patch_call(
- self.call.device.build_type,
- return_value='userdebug'), (self.patch_call(
- self.call.device.build_system_root_image,
- return_value='')), (self.patch_call(
- self.call.device.build_version_sdk,
- return_value=version_codes.PIE)), (self.patch_call(
- self.call.device.product_name,
- return_value='aosp_sailfish')), (self.assertCall(
- self.call.adb.Shell('getprop service.adb.root'),
- '1\n')):
- self.assertTrue(self.device.HasRoot())
-
- def testhasRootEngBuild_true(self):
+ def testHasRootEngBuild_true(self):
with self.patch_call(self.call.device.build_type, return_value='eng'):
self.assertTrue(self.device.HasRoot())
def testHasRoot_false(self):
- with self.patch_call(
- self.call.device.build_type,
- return_value='userdebug'), (self.patch_call(
- self.call.device.build_system_root_image,
- return_value='')), (self.patch_call(
- self.call.device.build_version_sdk,
- return_value=version_codes.PIE)), (self.patch_call(
- self.call.device.product_name,
- return_value='notasailfish')), (self.assertCall(
- self.call.adb.Shell('ls /root'), self.ShellError())):
+ with self.patch_call(self.call.device.build_type,
+ return_value='userdebug'), (self.assertCall(
+ self.call.adb.Shell('id'), 'uid=2000(shell)\n')):
self.assertFalse(self.device.HasRoot())
- def testHasRootSpecial_false(self):
- with self.patch_call(
- self.call.device.build_type,
- return_value='userdebug'), (self.patch_call(
- self.call.device.build_system_root_image,
- return_value='')), (self.patch_call(
- self.call.device.build_version_sdk,
- return_value=version_codes.PIE)), (self.patch_call(
- self.call.device.product_name,
- return_value='sailfish')), (self.assertCall(
- self.call.adb.Shell('getprop service.adb.root'), '\n')):
- self.assertFalse(self.device.HasRoot())
-
- def testHasRootSpecialAosp_false(self):
- with self.patch_call(
- self.call.device.build_type,
- return_value='userdebug'), (self.patch_call(
- self.call.device.build_system_root_image,
- return_value='')), (self.patch_call(
- self.call.device.build_version_sdk,
- return_value=version_codes.PIE)), (self.patch_call(
- self.call.device.product_name,
- return_value='aosp_sailfish')), (self.assertCall(
- self.call.adb.Shell('getprop service.adb.root'), '\n')):
- self.assertFalse(self.device.HasRoot())
-
- def testHasRootSystemRootImage(self):
- with self.patch_call(
- self.call.device.build_type,
- return_value='userdebug'), (self.patch_call(
- self.call.device.build_system_root_image,
- return_value='true')), (self.patch_call(
- self.call.device.build_version_sdk,
- return_value=version_codes.PIE)), (self.patch_call(
- self.call.device.product_name,
- return_value='notasailfish')), (self.assertCall(
- self.call.adb.Shell('getprop service.adb.root'),
- '1\n')):
- self.assertTrue(self.device.HasRoot())
-
- def testHasRoot10(self):
- # All devices on Android 10 / Q and above should use the system-as-root
- # partition layout, though they may not have the property set.
- with self.patch_call(
- self.call.device.build_type,
- return_value='userdebug'), (self.patch_call(
- self.call.device.build_system_root_image,
- return_value='')), (self.patch_call(
- self.call.device.build_version_sdk,
- return_value=version_codes.Q)), (self.patch_call(
- self.call.device.product_name,
- return_value='notasailfish')), (self.assertCall(
- self.call.adb.Shell('getprop service.adb.root'),
- '1\n')):
- self.assertTrue(self.device.HasRoot())
-
class DeviceUtilsEnableRootTest(DeviceUtilsTest):
def testEnableRoot_succeeds(self):
@@ -530,21 +435,54 @@ class DeviceUtilsIsApplicationInstalledTest(DeviceUtilsTest):
self.assertTrue(self.device.IsApplicationInstalled('some.installed.app'))
def testIsApplicationInstalled_notInstalled(self):
- with self.assertCalls((self.call.device.RunShellCommand(
- ['pm', 'list', 'packages', 'not.installed.app'], check_return=True),
- '')):
+ with self.assertCalls(
+ (self.call.device.RunShellCommand(
+ ['pm', 'list', 'packages', 'not.installed.app'], check_return=True),
+ ''),
+ (self.call.device.RunShellCommand(
+ ['dumpsys', 'package'], check_return=True, large_output=True), [])):
self.assertFalse(self.device.IsApplicationInstalled('not.installed.app'))
def testIsApplicationInstalled_substringMatch(self):
- with self.assertCalls((self.call.device.RunShellCommand(
- ['pm', 'list', 'packages', 'substring.of.package'], check_return=True),
- [
- 'package:first.substring.of.package',
- 'package:second.substring.of.package',
- ])):
+ with self.assertCalls(
+ (self.call.device.RunShellCommand(
+ ['pm', 'list', 'packages', 'substring.of.package'],
+ check_return=True),
+ [
+ 'package:first.substring.of.package',
+ 'package:second.substring.of.package',
+ ]),
+ (self.call.device.RunShellCommand(
+ ['dumpsys', 'package'], check_return=True, large_output=True), [])):
self.assertFalse(
self.device.IsApplicationInstalled('substring.of.package'))
+ def testIsApplicationInstalled_dumpsysFallback(self):
+ with self.assertCalls(
+ (self.call.device.RunShellCommand(
+ ['pm', 'list', 'packages', 'some.installed.app'],
+ check_return=True), []),
+ (self.call.device.RunShellCommand(
+ ['dumpsys', 'package'], check_return=True, large_output=True),
+ ['Package [some.installed.app] (a12345):'])):
+ self.assertTrue(self.device.IsApplicationInstalled('some.installed.app'))
+
+ def testIsApplicationInstalled_dumpsysFallbackVersioned(self):
+ with self.assertCalls(
+ (self.call.device.RunShellCommand(
+ ['dumpsys', 'package'], check_return=True, large_output=True),
+ ['Package [some.installed.app_1234] (a12345):'])):
+ self.assertTrue(
+ self.device.IsApplicationInstalled('some.installed.app', 1234))
+
+ def testIsApplicationInstalled_dumpsysFallbackVersionNotNeeded(self):
+ with self.assertCalls(
+ (self.call.device.RunShellCommand(
+ ['dumpsys', 'package'], check_return=True, large_output=True),
+ ['Package [some.installed.app] (a12345):'])):
+ self.assertTrue(
+ self.device.IsApplicationInstalled('some.installed.app', 1234))
+
class DeviceUtilsGetApplicationPathsInternalTest(DeviceUtilsTest):
def testGetApplicationPathsInternal_exists(self):
@@ -913,13 +851,24 @@ class DeviceUtilsRebootTest(DeviceUtilsTest):
def testReboot_blocking(self):
with self.assertCalls(
+ (self.call.device.HasRoot(), False),
self.call.adb.Reboot(), (self.call.device.IsOnline(), True),
(self.call.device.IsOnline(), False),
self.call.device.WaitUntilFullyBooted(wifi=False, decrypt=False)):
self.device.Reboot(block=True)
+ def testReboot_blockingWithRoot(self):
+ with self.assertCalls(
+ (self.call.device.HasRoot(), True),
+ self.call.adb.Reboot(), (self.call.device.IsOnline(), True),
+ (self.call.device.IsOnline(), False),
+ self.call.device.WaitUntilFullyBooted(wifi=False, decrypt=False),
+ self.call.device.EnableRoot()):
+ self.device.Reboot(block=True)
+
def testReboot_blockUntilWifi(self):
with self.assertCalls(
+ (self.call.device.HasRoot(), False),
self.call.adb.Reboot(), (self.call.device.IsOnline(), True),
(self.call.device.IsOnline(), False),
self.call.device.WaitUntilFullyBooted(wifi=True, decrypt=False)):
@@ -927,6 +876,7 @@ class DeviceUtilsRebootTest(DeviceUtilsTest):
def testReboot_blockUntilDecrypt(self):
with self.assertCalls(
+ (self.call.device.HasRoot(), False),
self.call.adb.Reboot(), (self.call.device.IsOnline(), True),
(self.call.device.IsOnline(), False),
self.call.device.WaitUntilFullyBooted(wifi=False, decrypt=True)):
@@ -950,6 +900,7 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
reinstall=False,
streaming=None,
allow_downgrade=False),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True),
(self.call.device.GrantPermissions(TEST_PACKAGE, ['p1']), [])):
self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0)
@@ -966,6 +917,7 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
reinstall=False,
streaming=False,
allow_downgrade=False),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True),
(self.call.device.GrantPermissions(TEST_PACKAGE, ['p1']), [])):
self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0)
@@ -981,7 +933,8 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
(self.call.adb.Install(TEST_APK_PATH,
reinstall=False,
streaming=None,
- allow_downgrade=False))):
+ allow_downgrade=False)),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0)
def testInstall_findPermissions(self):
@@ -997,6 +950,7 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
reinstall=False,
streaming=None,
allow_downgrade=False)),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True),
(self.call.device.GrantPermissions(TEST_PACKAGE, ['p1']), [])):
self.device.Install(DeviceUtilsInstallTest.mock_apk, retries=0)
@@ -1011,6 +965,7 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
reinstall=False,
streaming=None,
allow_downgrade=False)),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True),
(self.call.device.GrantPermissions(TEST_PACKAGE, ['p1', 'p2']), [])):
self.device.Install(
DeviceUtilsInstallTest.mock_apk,
@@ -1024,7 +979,8 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
(self.call.device._GetApplicationPathsInternal(TEST_PACKAGE),
['/fake/data/app/test.package.apk']),
(self.call.device._ComputeStaleApks(TEST_PACKAGE, [TEST_APK_PATH]),
- ([], None)), (self.call.device.ForceStop(TEST_PACKAGE))):
+ ([], None)), (self.call.device.ForceStop(TEST_PACKAGE)),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.Install(
DeviceUtilsInstallTest.mock_apk, retries=0, permissions=[])
@@ -1041,7 +997,8 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
self.call.adb.Install(TEST_APK_PATH,
reinstall=False,
streaming=None,
- allow_downgrade=False)):
+ allow_downgrade=False),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.Install(
DeviceUtilsInstallTest.mock_apk, retries=0, permissions=[])
@@ -1058,7 +1015,8 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
self.call.adb.Install(TEST_APK_PATH,
reinstall=False,
streaming=None,
- allow_downgrade=False)):
+ allow_downgrade=False),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.Install(
DeviceUtilsInstallTest.mock_apk, retries=0, permissions=[])
@@ -1075,7 +1033,8 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
self.call.adb.Install(TEST_APK_PATH,
reinstall=True,
streaming=None,
- allow_downgrade=False)):
+ allow_downgrade=False),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.Install(
DeviceUtilsInstallTest.mock_apk,
reinstall=True,
@@ -1089,7 +1048,8 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
(self.call.device._GetApplicationPathsInternal(TEST_PACKAGE),
['/fake/data/app/test.package.apk']),
(self.call.device._ComputeStaleApks(TEST_PACKAGE, [TEST_APK_PATH]),
- ([], None)), (self.call.device.ForceStop(TEST_PACKAGE))):
+ ([], None)), (self.call.device.ForceStop(TEST_PACKAGE)),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.Install(
DeviceUtilsInstallTest.mock_apk,
reinstall=True,
@@ -1131,7 +1091,8 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
self.call.adb.Install(TEST_APK_PATH,
reinstall=True,
streaming=None,
- allow_downgrade=True)):
+ allow_downgrade=True),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.Install(
DeviceUtilsInstallTest.mock_apk,
reinstall=True,
@@ -1164,10 +1125,32 @@ class DeviceUtilsInstallTest(DeviceUtilsTest):
reinstall=False,
streaming=None,
allow_downgrade=False),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True),
(self.call.device.GrantPermissions(TEST_PACKAGE, None), [])):
self.device.Install(
mock_apk_with_fake, fake_modules=fake_modules, retries=0)
+ def testInstall_packageNotAvailableAfterInstall(self):
+ with self.patch_call(
+ self.call.device.product_name,
+ return_value='notflounder'), (self.patch_call(
+ self.call.device.build_version_sdk, return_value=23)), (
+ self.patch_call(self.call.device.IsApplicationInstalled,
+ return_value=False)):
+ with self.assertCalls(
+ (self.call.device._FakeInstall(set(), None, 'test.package')),
+ (mock.call.os.path.exists(TEST_APK_PATH), True),
+ (self.call.device._GetApplicationPathsInternal(TEST_PACKAGE), []),
+ self.call.adb.Install(TEST_APK_PATH,
+ reinstall=False,
+ streaming=None,
+ allow_downgrade=False)):
+ with self.assertRaisesRegexp(
+ device_errors.CommandFailedError,
+ 'not installed on device after explicit install attempt'):
+ self.device.Install(
+ DeviceUtilsInstallTest.mock_apk, retries=0)
+
class DeviceUtilsInstallSplitApkTest(DeviceUtilsTest):
@@ -1191,7 +1174,8 @@ class DeviceUtilsInstallSplitApkTest(DeviceUtilsTest):
partial=None,
reinstall=False,
streaming=None,
- allow_downgrade=False))):
+ allow_downgrade=False)),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.InstallSplitApk(
'base.apk', ['split1.apk', 'split2.apk'], permissions=[], retries=0)
@@ -1212,7 +1196,8 @@ class DeviceUtilsInstallSplitApkTest(DeviceUtilsTest):
partial=None,
reinstall=False,
streaming=False,
- allow_downgrade=False))):
+ allow_downgrade=False)),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.InstallSplitApk(
'base.apk', ['split1.apk', 'split2.apk'], permissions=[], retries=0)
@@ -1237,7 +1222,8 @@ class DeviceUtilsInstallSplitApkTest(DeviceUtilsTest):
partial=TEST_PACKAGE,
reinstall=True,
streaming=None,
- allow_downgrade=False))):
+ allow_downgrade=False)),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.InstallSplitApk(
DeviceUtilsInstallSplitApkTest.mock_apk,
['split1.apk', 'split2.apk'],
@@ -1266,7 +1252,8 @@ class DeviceUtilsInstallSplitApkTest(DeviceUtilsTest):
partial=TEST_PACKAGE,
reinstall=True,
streaming=None,
- allow_downgrade=True))):
+ allow_downgrade=True)),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.InstallSplitApk(
DeviceUtilsInstallSplitApkTest.mock_apk,
['split1.apk', 'split2.apk'],
@@ -1311,7 +1298,8 @@ class DeviceUtilsInstallSplitApkTest(DeviceUtilsTest):
partial=None,
reinstall=False,
streaming=None,
- allow_downgrade=False))):
+ allow_downgrade=False)),
+ (self.call.device.IsApplicationInstalled(TEST_PACKAGE, None), True)):
self.device.InstallSplitApk(
DeviceUtilsInstallSplitApkTest.mock_apk,
['split1.apk', 'split2.apk'],
@@ -3132,8 +3120,8 @@ class DeviceUtilsGetWebViewUpdateServiceDumpTest(DeviceUtilsTest):
with self.assertCall(
self.call.adb.Shell('dumpsys webviewupdate'),
'Fallback logic enabled: true'):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.GetWebViewUpdateServiceDump()
+ update = self.device.GetWebViewUpdateServiceDump()
+ self.assertEqual(True, update['FallbackLogicEnabled'])
def testGetWebViewUpdateServiceDump_noop(self):
with self.patch_call(
diff --git a/catapult/devil/devil/android/forwarder.py b/catapult/devil/devil/android/forwarder.py
index bf4c5ca1..9b1f82e4 100644
--- a/catapult/devil/devil/android/forwarder.py
+++ b/catapult/devil/devil/android/forwarder.py
@@ -435,14 +435,10 @@ class Forwarder(object):
(exit_code, output) = cmd_helper.GetCmdStatusAndOutputWithTimeout(
kill_cmd, Forwarder._TIMEOUT)
if exit_code == -9:
- # pkill can exit with -9, seemingly in cases where the process it's
- # asked to kill dies sometime during pkill running. In this case,
- # re-running should result in pkill succeeding.
- logging.warning(
- 'pkilling host forwarder returned -9, retrying through strace. '
- 'Output: %s', output)
- exit_code, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
- ['strace', '-f', '-s', '256'] + kill_cmd, Forwarder._TIMEOUT)
+ # pkill can exit with -9, which indicates that it was killed. It's
+ # possible that the forwarder was still killed, though, which will
+ # be checked later.
+ logging.warning('pkilling host forwarder returned -9.')
if exit_code in (0, 1):
# pkill exits with a 0 if it was able to signal at least one process.
# pkill exits with a 1 if it wasn't able to signal a process because
@@ -458,6 +454,7 @@ class Forwarder(object):
'\n '.join(host_forwarder_lines))
else:
logger.error('No remaining host_forwarder processes?')
+ return
_DumpHostLog()
error_msg = textwrap.dedent("""\
`{kill_cmd}` failed to kill host_forwarder.
diff --git a/catapult/devil/devil/android/sdk/adb_wrapper.py b/catapult/devil/devil/android/sdk/adb_wrapper.py
index 8cd73136..71928d58 100644
--- a/catapult/devil/devil/android/sdk/adb_wrapper.py
+++ b/catapult/devil/devil/android/sdk/adb_wrapper.py
@@ -35,11 +35,13 @@ ADB_KEYS_FILE = '/data/misc/adb/adb_keys'
ADB_HOST_KEYS_DIR = os.path.join(os.path.expanduser('~'), '.android')
DEFAULT_TIMEOUT = 30
+DEFAULT_LONG_TIMEOUT = DEFAULT_TIMEOUT * 10
+DEFAULT_SUPER_LONG_TIMEOUT = DEFAULT_LONG_TIMEOUT * 2
DEFAULT_RETRIES = 2
_ADB_VERSION_RE = re.compile(r'Android Debug Bridge version (\d+\.\d+\.\d+)')
_EMULATOR_RE = re.compile(r'^emulator-[0-9]+$')
-_DEVICE_NOT_FOUND_RE = re.compile(r"error: device '(?P<serial>.+)' not found")
+_DEVICE_NOT_FOUND_RE = re.compile(r"device '(?P<serial>.+)' not found")
_READY_STATE = 'device'
_VERITY_DISABLE_RE = re.compile(r'(V|v)erity (is )?(already )?disabled'
r'|Successfully disabled verity')
@@ -303,7 +305,7 @@ class AdbWrapper(object):
# inconsistent with error reporting so many command failures present
# differently.
if status != 0 or (check_error and output.startswith('error:')):
- not_found_m = _DEVICE_NOT_FOUND_RE.match(output)
+ not_found_m = _DEVICE_NOT_FOUND_RE.search(output)
device_waiting_m = _WAITING_FOR_DEVICE_RE.match(output)
if (device_waiting_m is not None
or (not_found_m is not None
@@ -476,7 +478,7 @@ class AdbWrapper(object):
local,
remote,
sync=False,
- timeout=60 * 5,
+ timeout=DEFAULT_SUPER_LONG_TIMEOUT,
retries=DEFAULT_RETRIES):
"""Pushes a file from the host to the device.
@@ -549,7 +551,11 @@ class AdbWrapper(object):
self._RunDeviceAdbCmd(push_cmd, timeout, retries)
- def Pull(self, remote, local, timeout=60 * 5, retries=DEFAULT_RETRIES):
+ def Pull(self,
+ remote,
+ local,
+ timeout=DEFAULT_LONG_TIMEOUT,
+ retries=DEFAULT_RETRIES):
"""Pulls a file from the device to the host.
Args:
@@ -832,7 +838,7 @@ class AdbWrapper(object):
reinstall=False,
sd_card=False,
streaming=None,
- timeout=60 * 2,
+ timeout=DEFAULT_LONG_TIMEOUT,
retries=DEFAULT_RETRIES):
"""Install an apk on the device.
@@ -883,7 +889,7 @@ class AdbWrapper(object):
allow_downgrade=False,
partial=False,
streaming=None,
- timeout=60 * 2,
+ timeout=DEFAULT_LONG_TIMEOUT,
retries=DEFAULT_RETRIES):
"""Install an apk with splits on the device.
@@ -1002,7 +1008,8 @@ class AdbWrapper(object):
VerifyLocalFileExists(path)
self._RunDeviceAdbCmd(['restore'] + [path], timeout, retries)
- def WaitForDevice(self, timeout=60 * 5, retries=DEFAULT_RETRIES):
+ def WaitForDevice(self, timeout=DEFAULT_LONG_TIMEOUT,
+ retries=DEFAULT_RETRIES):
"""Block until the device is online.
Args:
@@ -1047,7 +1054,9 @@ class AdbWrapper(object):
"""Remounts the /system partition on the device read-write."""
self._RunDeviceAdbCmd(['remount'], timeout, retries)
- def Reboot(self, to_bootloader=False, timeout=60 * 5,
+ def Reboot(self,
+ to_bootloader=False,
+ timeout=DEFAULT_LONG_TIMEOUT,
retries=DEFAULT_RETRIES):
"""Reboots the device.
@@ -1069,7 +1078,16 @@ class AdbWrapper(object):
timeout: (optional) Timeout per try in seconds.
retries: (optional) Number of retries to attempt.
"""
- output = self._RunDeviceAdbCmd(['root'], timeout, retries)
+ try:
+ output = self._RunDeviceAdbCmd(['root'], timeout, retries)
+ except device_errors.AdbCommandFailedError as e:
+ # For some devices, root can occasionally fail with this error and kick
+ # the device into adb 'offline' mode. Assuming this is transient, try
+ # waiting for the device to come back up before re-raising the exception
+ # and proceeding with any retries.
+ if 'unable to connect for root: closed' in e.output:
+ self.WaitForDevice()
+ raise
if 'cannot' in output:
raise device_errors.AdbCommandFailedError(
['root'], output, device_serial=self._device_serial)
@@ -1115,6 +1133,7 @@ class AdbWrapper(object):
['enable-verity'], output, device_serial=self._device_serial)
return output
+ # Deprecated use device_utils#is_emulator instead.
@property
def is_emulator(self):
return _EMULATOR_RE.match(self._device_serial)
diff --git a/catapult/devil/devil/android/sdk/adb_wrapper_test.py b/catapult/devil/devil/android/sdk/adb_wrapper_test.py
index f30ab152..1b3d5841 100755
--- a/catapult/devil/devil/android/sdk/adb_wrapper_test.py
+++ b/catapult/devil/devil/android/sdk/adb_wrapper_test.py
@@ -68,3 +68,12 @@ class AdbWrapperTest(unittest.TestCase):
get_cmd_mock.return_value = (1, '- waiting for device - ')
self.assertRaises(device_errors.DeviceUnreachableError, self.adb.Shell,
'/bin/true')
+
+ @mock.patch('devil.utils.cmd_helper.GetCmdStatusAndOutputWithTimeout')
+ def testRootConnectionClosedFailure(self, get_cmd_mock):
+ get_cmd_mock.side_effect = [
+ (1, 'unable to connect for root: closed'),
+ (0, ''),
+ ]
+ self.assertRaises(device_errors.AdbCommandFailedError, self.adb.Root,
+ retries=0)
diff --git a/catapult/devil/devil/android/sdk/bundletool.py b/catapult/devil/devil/android/sdk/bundletool.py
index 5c181c56..f210db14 100644
--- a/catapult/devil/devil/android/sdk/bundletool.py
+++ b/catapult/devil/devil/android/sdk/bundletool.py
@@ -9,7 +9,9 @@ from devil import base_error
from devil import devil_env
from devil.utils import cmd_helper
from devil.utils import lazy
-from py_utils import tempfile_ext
+
+with devil_env.SysPath(devil_env.PY_UTILS_PATH):
+ from py_utils import tempfile_ext
_bundletool_path = lazy.WeakConstant(lambda: devil_env.config.FetchPath(
'bundletool'))
diff --git a/catapult/devil/devil/android/tools/device_monitor.py b/catapult/devil/devil/android/tools/device_monitor.py
index 6128dae8..26e89a24 100755
--- a/catapult/devil/devil/android/tools/device_monitor.py
+++ b/catapult/devil/devil/android/tools/device_monitor.py
@@ -203,11 +203,6 @@ def main(argv):
parser = argparse.ArgumentParser(description='Launches the device monitor.')
script_common.AddEnvironmentArguments(parser)
parser.add_argument('--denylist-file', help='Path to device denylist file.')
- # TODO(crbug.com/1097306): Remove this once chromium_android/api.py stops
- # using it.
- parser.add_argument('--blacklist-file',
- dest='denylist_file',
- help=argparse.SUPPRESS)
args = parser.parse_args(argv)
logger = logging.getLogger()
diff --git a/catapult/devil/devil/android/tools/device_recovery.py b/catapult/devil/devil/android/tools/device_recovery.py
index f25c5a25..10c5fe51 100755
--- a/catapult/devil/devil/android/tools/device_recovery.py
+++ b/catapult/devil/devil/android/tools/device_recovery.py
@@ -114,6 +114,7 @@ def RecoverDevice(device, denylist, should_reboot=lambda device: True):
return
if should_reboot(device):
+ should_restore_root = device.HasRoot()
try:
device.WaitUntilFullyBooted(retries=0)
except (device_errors.CommandTimeoutError, device_errors.CommandFailedError,
@@ -154,6 +155,8 @@ def RecoverDevice(device, denylist, should_reboot=lambda device: True):
try:
device.WaitUntilFullyBooted(
retries=0, timeout=device.REBOOT_DEFAULT_TIMEOUT)
+ if should_restore_root:
+ device.EnableRoot()
except (device_errors.CommandFailedError,
device_errors.DeviceUnreachableError):
logger.exception('Failure while waiting for %s.', str(device))
@@ -230,8 +233,6 @@ def main():
parser = argparse.ArgumentParser()
logging_common.AddLoggingArguments(parser)
script_common.AddEnvironmentArguments(parser)
- # TODO(crbug.com/1097306): Remove this once callers switch to --denylist-file.
- parser.add_argument('--blacklist-file', help=argparse.SUPPRESS)
parser.add_argument('--denylist-file', help='Device denylist JSON file.')
parser.add_argument(
'--known-devices-file',
@@ -248,9 +249,6 @@ def main():
denylist = (device_denylist.Denylist(args.denylist_file)
if args.denylist_file else None)
- # TODO(crbug.com/1097306): Remove this once callers switch to --denylist-file.
- if not denylist and args.blacklist_file:
- denylist = device_denylist.Denylist(args.blacklist_file)
expected_devices = device_status.GetExpectedDevices(args.known_devices_files)
usb_devices = set(lsusb.get_android_devices())
diff --git a/catapult/devil/devil/android/tools/device_status.py b/catapult/devil/devil/android/tools/device_status.py
index d0eb7df1..40f714aa 100755
--- a/catapult/devil/devil/android/tools/device_status.py
+++ b/catapult/devil/devil/android/tools/device_status.py
@@ -226,11 +226,6 @@ def AddArguments(parser):
parser.add_argument(
'--json-output', help='Output JSON information into a specified file.')
parser.add_argument('--denylist-file', help='Device denylist JSON file.')
- # TODO(crbug.com/1097306): Remove this once //testing/scripts/host_info.py
- # stops using it.
- parser.add_argument('--blacklist-file',
- dest='denylist_file',
- help=argparse.SUPPRESS)
parser.add_argument(
'--known-devices-file',
action='append',
diff --git a/catapult/devil/devil/android/tools/provision_devices.py b/catapult/devil/devil/android/tools/provision_devices.py
index 4b0f44a2..9a324c48 100755
--- a/catapult/devil/devil/android/tools/provision_devices.py
+++ b/catapult/devil/devil/android/tools/provision_devices.py
@@ -625,9 +625,6 @@ def main(raw_args):
metavar='NUM',
help='wait for the device to reach this minimum battery'
' level before trying to continue')
- # TODO(crbug.com/1097306): Remove after updating clients.
- parser.add_argument('--output-device-blacklist',
- help=argparse.SUPPRESS)
parser.add_argument('--output-device-denylist',
help='Json file to output the device denylist.')
parser.add_argument(
@@ -674,10 +671,6 @@ def main(raw_args):
logging_common.InitializeLogging(args)
script_common.InitializeEnvironment(args)
- output_device_denylist = args.output_device_denylist
- if not output_device_denylist and args.output_device_blacklist:
- output_device_denylist = args.output_device_blacklist
-
try:
return ProvisionDevices(
args.devices,
@@ -691,7 +684,7 @@ def main(raw_args):
enable_java_debug=args.enable_java_debug,
max_battery_temp=args.max_battery_temp,
min_battery_level=args.min_battery_level,
- output_device_denylist=output_device_denylist,
+ output_device_denylist=args.output_device_denylist,
reboot_timeout=args.reboot_timeout,
remove_system_webview=args.remove_system_webview,
system_app_remove_list=args.system_app_remove_list,
diff --git a/catapult/devil/devil/android/tools/script_common.py b/catapult/devil/devil/android/tools/script_common.py
index ae2b7a84..de823662 100644
--- a/catapult/devil/devil/android/tools/script_common.py
+++ b/catapult/devil/devil/android/tools/script_common.py
@@ -2,7 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import argparse
import os
from devil import devil_env
@@ -66,22 +65,8 @@ def AddDeviceArguments(parser):
default=[],
help='Serial number of the Android device to use. (default: use all)')
- # TODO(crbug.com/1097306): Simplify this to an ungrouped --denylist-file
- # once all uses of --blacklist-file / args.blacklist_file have been updated.
- class DenylistAction(argparse.Action):
-
- #override
- def __call__(self, parser, namespace, values, option_string=None):
- setattr(namespace, 'denylist_file', values)
- setattr(namespace, 'blacklist_file', values)
-
- denylist_group = parser.add_mutually_exclusive_group()
- denylist_group.add_argument('--denylist-file',
- help='Device denylist JSON file.',
- action=DenylistAction)
- denylist_group.add_argument('--blacklist-file',
- help=argparse.SUPPRESS,
- action=DenylistAction)
+ parser.add_argument('--denylist-file',
+ help='Device denylist JSON file.')
def GetDevices(requested_devices, denylist_file):
diff --git a/catapult/devil/devil/android/tools/system_app.py b/catapult/devil/devil/android/tools/system_app.py
index c2f058e0..62bf5a59 100755
--- a/catapult/devil/devil/android/tools/system_app.py
+++ b/catapult/devil/devil/android/tools/system_app.py
@@ -34,8 +34,9 @@ logger = logging.getLogger(__name__)
SPECIAL_SYSTEM_APP_LOCATIONS = {
# Older versions of ArCore were installed in /data/app/ regardless of
# whether they were system apps or not. Newer versions install in /system/
- # if they are system apps, and in /data/app/ if they aren't.
- 'com.google.ar.core': ['/data/app/', '/system/'],
+ # if they are system apps, and in /data/app/ if they aren't. Some newer
+ # devices/OSes install in /product/app/ for system apps, as well.
+ 'com.google.ar.core': ['/data/app/', '/system/', '/product/app/'],
# On older versions of VrCore, the system app version is installed in
# /system/ like normal. However, at some point, this moved to /data/.
# So, we have to handle both cases. Like ArCore, this means we'll end up
diff --git a/catapult/devil/devil/android/tools/webview_app.py b/catapult/devil/devil/android/tools/webview_app.py
index 406de1cb..5866a66c 100755
--- a/catapult/devil/devil/android/tools/webview_app.py
+++ b/catapult/devil/devil/android/tools/webview_app.py
@@ -12,15 +12,11 @@ import re
import sys
if __name__ == '__main__':
- sys.path.append(
- os.path.abspath(
- os.path.join(os.path.dirname(__file__), '..', '..', '..')))
- sys.path.append(
- os.path.abspath(
- os.path.join(
- os.path.dirname(__file__), '..', '..', '..', '..', 'common',
- 'py_utils')))
+ _DEVIL_ROOT_DIR = os.path.abspath(
+ os.path.join(os.path.dirname(__file__), '..', '..', '..'))
+ sys.path.append(_DEVIL_ROOT_DIR)
+from devil import devil_env
from devil.android import apk_helper
from devil.android import device_errors
from devil.android.sdk import version_codes
@@ -29,7 +25,9 @@ from devil.android.tools import system_app
from devil.utils import cmd_helper
from devil.utils import parallelizer
from devil.utils import run_tests_helper
-from py_utils import tempfile_ext
+
+with devil_env.SysPath(devil_env.PY_UTILS_PATH):
+ from py_utils import tempfile_ext
logger = logging.getLogger(__name__)
diff --git a/catapult/devil/devil/devil_dependencies.json b/catapult/devil/devil/devil_dependencies.json
index 8e15e357..03e8d98a 100644
--- a/catapult/devil/devil/devil_dependencies.json
+++ b/catapult/devil/devil/devil_dependencies.json
@@ -16,7 +16,7 @@
"cloud_storage_bucket": "chromium-telemetry",
"file_info": {
"linux2_x86_64": {
- "cloud_storage_hash": "8bd43e3930f6eec643d5dc64cab9e5bb4ddf4909",
+ "cloud_storage_hash": "528d0e88a0d876b0549840f0797beffca4a6a796",
"download_path": "../bin/deps/linux2/x86_64/bin/adb"
}
}
diff --git a/catapult/devil/devil/devil_env.py b/catapult/devil/devil/devil_env.py
index b39e01c8..b61d1b0e 100644
--- a/catapult/devil/devil/devil_env.py
+++ b/catapult/devil/devil/devil_env.py
@@ -15,6 +15,7 @@ CATAPULT_ROOT_PATH = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', '..'))
DEPENDENCY_MANAGER_PATH = os.path.join(CATAPULT_ROOT_PATH, 'dependency_manager')
PYMOCK_PATH = os.path.join(CATAPULT_ROOT_PATH, 'third_party', 'mock')
+PY_UTILS_PATH = os.path.join(CATAPULT_ROOT_PATH, 'common', 'py_utils')
@contextlib.contextmanager
@@ -151,7 +152,9 @@ class _Environment(object):
devil_logger.propagate = False
devil_logger.addHandler(handler)
- import py_utils.cloud_storage
+ with SysPath(PY_UTILS_PATH):
+ import py_utils.cloud_storage
+
lock_logger = py_utils.cloud_storage.logger
lock_logger.setLevel(log_level)
lock_logger.propagate = False
diff --git a/catapult/devil/devil/utils/update_dependencies.py b/catapult/devil/devil/utils/update_dependencies.py
index df1f88b2..513c6382 100755
--- a/catapult/devil/devil/utils/update_dependencies.py
+++ b/catapult/devil/devil/utils/update_dependencies.py
@@ -116,7 +116,7 @@ def UpdateDependency(dependency_name, dependency_info, local_path, platform):
remote_path = '%s_%s' % (dependency_name, dependency_sha1)
gs_dest = 'gs://%s/%s/%s' % (bucket, folder, remote_path)
ec, gsutil_output = cmd_helper.GetCmdStatusAndOutput(
- ['gsutil', 'cp', local_path, gs_dest])
+ ['gsutil.py', 'cp', local_path, gs_dest])
if ec:
raise base_error.BaseError(
'Failed to upload %s to %s: %s' % (remote_path, gs_dest, gsutil_output))
diff --git a/catapult/devil/devil/utils/zip_utils.py b/catapult/devil/devil/utils/zip_utils.py
index 35c59056..aac9641e 100644
--- a/catapult/devil/devil/utils/zip_utils.py
+++ b/catapult/devil/devil/utils/zip_utils.py
@@ -9,18 +9,17 @@ import os
import sys
import zipfile
-_DEVIL_ROOT_DIR = os.path.abspath(
- os.path.join(os.path.dirname(__file__), '..', '..'))
if __name__ == '__main__':
+ _DEVIL_ROOT_DIR = os.path.abspath(
+ os.path.join(os.path.dirname(__file__), '..', '..'))
sys.path.append(_DEVIL_ROOT_DIR)
-_PY_UTILS_ROOT_DIR = os.path.abspath(
- os.path.join(_DEVIL_ROOT_DIR, '..', 'common', 'py_utils'))
-sys.path.append(_PY_UTILS_ROOT_DIR)
-
+from devil import devil_env
from devil import base_error
from devil.utils import cmd_helper
-from py_utils import tempfile_ext
+
+with devil_env.SysPath(devil_env.PY_UTILS_PATH):
+ from py_utils import tempfile_ext
logger = logging.getLogger(__name__)
diff --git a/catapult/devil/devil/utils/zip_utils_test.py b/catapult/devil/devil/utils/zip_utils_test.py
index 96a55f55..1afc3f48 100644
--- a/catapult/devil/devil/utils/zip_utils_test.py
+++ b/catapult/devil/devil/utils/zip_utils_test.py
@@ -6,8 +6,11 @@ import os
import unittest
import zipfile
+from devil import devil_env
from devil.utils import zip_utils
-from py_utils import tempfile_ext
+
+with devil_env.SysPath(devil_env.PY_UTILS_PATH):
+ from py_utils import tempfile_ext
class WriteZipFileTest(unittest.TestCase):
diff --git a/catapult/systrace/systrace/systrace_trace_viewer.html b/catapult/systrace/systrace/systrace_trace_viewer.html
index 04e8089b..473261d8 100644
--- a/catapult/systrace/systrace/systrace_trace_viewer.html
+++ b/catapult/systrace/systrace/systrace_trace_viewer.html
@@ -2901,8 +2901,6 @@
<div id="collapsing_controls"></div>
<tr-ui-b-info-bar-group id="import-warnings">
</tr-ui-b-info-bar-group>
- <tr-ui-b-info-bar-group id="polyfill-warning">
- </tr-ui-b-info-bar-group>
</div>
<middle-container>
<slot></slot>
@@ -3468,7 +3466,22 @@
* Do not edit directly.
*/
-'use strict';if(!window.CustomElements||window.CustomElements.hasNative){if(window.Polymer){throw new Error('Cannot proceed. Polymer already present.');}
+'use strict';const global=this.window||this.global;this.tr=(function(){if(global.tr)return global.tr;function exportPath(name){const parts=name.split('.');let cur=global;for(let part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{cur=cur[part]={};}}
+return cur;}
+function isExported(name){const parts=name.split('.');let cur=global;for(let part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{return false;}}
+return true;}
+function isDefined(name){const parts=name.split('.');let curObject=global;for(let i=0;i<parts.length;i++){const partName=parts[i];const nextObject=curObject[partName];if(nextObject===undefined)return false;curObject=nextObject;}
+return true;}
+let panicElement=undefined;const rawPanicMessages=[];function showPanicElementIfNeeded(){if(panicElement)return;const panicOverlay=document.createElement('div');panicOverlay.style.backgroundColor='white';panicOverlay.style.border='3px solid red';panicOverlay.style.boxSizing='border-box';panicOverlay.style.color='black';panicOverlay.style.display='flex';panicOverlay.style.height='100%';panicOverlay.style.left=0;panicOverlay.style.padding='8px';panicOverlay.style.position='fixed';panicOverlay.style.top=0;panicOverlay.style.webkitFlexDirection='column';panicOverlay.style.width='100%';panicElement=document.createElement('div');panicElement.style.webkitFlex='1 1 auto';panicElement.style.overflow='auto';panicOverlay.appendChild(panicElement);if(!document.body){setTimeout(function(){document.body.appendChild(panicOverlay);},150);}else{document.body.appendChild(panicOverlay);}}
+function showPanic(panicTitle,panicDetails){if(tr.isHeadless){if(panicDetails instanceof Error)throw panicDetails;throw new Error('Panic: '+panicTitle+':\n'+panicDetails);}
+if(panicDetails instanceof Error){panicDetails=panicDetails.stack;}
+showPanicElementIfNeeded();const panicMessageEl=document.createElement('div');panicMessageEl.innerHTML='<h2 id="message"></h2>'+'<pre id="details"></pre>';panicMessageEl.querySelector('#message').textContent=panicTitle;panicMessageEl.querySelector('#details').textContent=panicDetails;panicElement.appendChild(panicMessageEl);rawPanicMessages.push({title:panicTitle,details:panicDetails});}
+function hasPanic(){return rawPanicMessages.length!==0;}
+function getPanicText(){return rawPanicMessages.map(function(msg){return msg.title;}).join(', ');}
+function exportTo(namespace,fn){const obj=exportPath(namespace);const exports=fn();for(const propertyName in exports){const propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor){Object.defineProperty(obj,propertyName,propertyDescriptor);}}}
+function initialize(){if(global.isVinn){tr.isVinn=true;}else if(global.process&&global.process.versions.node){tr.isNode=true;}else{tr.isVinn=false;tr.isNode=false;tr.doc=document;tr.isMac=/Mac/.test(navigator.platform);tr.isWindows=/Win/.test(navigator.platform);tr.isChromeOS=/CrOS/.test(navigator.userAgent);tr.isLinux=/Linux/.test(navigator.userAgent);}
+tr.isHeadless=tr.isVinn||tr.isNode;}
+return{initialize,exportTo,isExported,isDefined,showPanic,hasPanic,getPanicText,};})();tr.initialize();'use strict';if(!window.CustomElements||window.CustomElements.hasNative){if(window.Polymer){throw new Error('Cannot proceed. Polymer already present.');}
window.Polymer={};window.Polymer.dom='shadow';}
(function(){function resolve(){document.body.removeAttribute('unresolved');}
if(window.WebComponents){addEventListener('WebComponentsReady',resolve);}else{if(document.readyState==='interactive'||document.readyState==='complete'){resolve();}else{addEventListener('DOMContentLoaded',resolve);}}}());window.Polymer={Settings:function(){var settings=window.Polymer||{};if(!settings.noUrlSettings){var parts=location.search.slice(1).split('&');for(var i=0,o;i<parts.length&&(o=parts[i]);i++){o=o.split('=');o[0]&&(settings[o[0]]=o[1]||true);}}
@@ -4062,22 +4075,7 @@ if(parentNode){if(!this._instance){this._instance=this.stamp();var root=this._in
this._instance=null;}},_showHideChildren:function(){var hidden=this.__hideTemplateChildren__||!this.if;if(this._instance){this._instance._showHideChildren(hidden);}},_forwardParentProp:function(prop,value){if(this._instance){this._instance.__setProperty(prop,value,true);}},_forwardParentPath:function(path,value){if(this._instance){this._instance._notifyPath(path,value,true);}}});Polymer({is:'dom-bind',properties:{notifyDomChange:{type:Boolean}},extends:'template',_template:null,created:function(){var self=this;Polymer.RenderStatus.whenReady(function(){if(document.readyState=='loading'){document.addEventListener('DOMContentLoaded',function(){self._markImportsReady();});}else{self._markImportsReady();}});},_ensureReady:function(){if(!this._readied){this._readySelf();}},_markImportsReady:function(){this._importsReady=true;this._ensureReady();},_registerFeatures:function(){this._prepConstructor();},_insertChildren:function(){var refNode;var parentNode=Polymer.dom(this).parentNode;if(parentNode.localName==this.is){refNode=parentNode;parentNode=Polymer.dom(parentNode).parentNode;}else{refNode=this;}
Polymer.dom(parentNode).insertBefore(this.root,refNode);},_removeChildren:function(){if(this._children){for(var i=0;i<this._children.length;i++){this.root.appendChild(this._children[i]);}}},_initFeatures:function(){},_scopeElementClass:function(element,selector){if(this.dataHost){return this.dataHost._scopeElementClass(element,selector);}else{return selector;}},_configureInstanceProperties:function(){},_prepConfigure:function(){var config={};for(var prop in this._propertyEffects){config[prop]=this[prop];}
var setupConfigure=this._setupConfigure;this._setupConfigure=function(){setupConfigure.call(this,config);};},attached:function(){if(this._importsReady){this.render();}},detached:function(){this._removeChildren();},render:function(){this._ensureReady();if(!this._children){this._template=this;this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepConfigure();this._prepBindings();this._prepPropertyInfo();Polymer.Base._initFeatures.call(this);this._children=Polymer.TreeApi.arrayCopyChildNodes(this.root);}
-this._insertChildren();if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}}});'use strict';if(!window.CustomElements||window.CustomElements.hasNative){if(!Polymer.Settings.useNativeShadow){tr.showPanic('Polymer error','base should use native shadow when possible.');}}'use strict';const global=this.window||this.global;this.tr=(function(){if(global.tr)return global.tr;function exportPath(name){const parts=name.split('.');let cur=global;for(let part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{cur=cur[part]={};}}
-return cur;}
-function isExported(name){const parts=name.split('.');let cur=global;for(let part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{return false;}}
-return true;}
-function isDefined(name){const parts=name.split('.');let curObject=global;for(let i=0;i<parts.length;i++){const partName=parts[i];const nextObject=curObject[partName];if(nextObject===undefined)return false;curObject=nextObject;}
-return true;}
-let panicElement=undefined;const rawPanicMessages=[];function showPanicElementIfNeeded(){if(panicElement)return;const panicOverlay=document.createElement('div');panicOverlay.style.backgroundColor='white';panicOverlay.style.border='3px solid red';panicOverlay.style.boxSizing='border-box';panicOverlay.style.color='black';panicOverlay.style.display='flex';panicOverlay.style.height='100%';panicOverlay.style.left=0;panicOverlay.style.padding='8px';panicOverlay.style.position='fixed';panicOverlay.style.top=0;panicOverlay.style.webkitFlexDirection='column';panicOverlay.style.width='100%';panicElement=document.createElement('div');panicElement.style.webkitFlex='1 1 auto';panicElement.style.overflow='auto';panicOverlay.appendChild(panicElement);if(!document.body){setTimeout(function(){document.body.appendChild(panicOverlay);},150);}else{document.body.appendChild(panicOverlay);}}
-function showPanic(panicTitle,panicDetails){if(tr.isHeadless){if(panicDetails instanceof Error)throw panicDetails;throw new Error('Panic: '+panicTitle+':\n'+panicDetails);}
-if(panicDetails instanceof Error){panicDetails=panicDetails.stack;}
-showPanicElementIfNeeded();const panicMessageEl=document.createElement('div');panicMessageEl.innerHTML='<h2 id="message"></h2>'+'<pre id="details"></pre>';panicMessageEl.querySelector('#message').textContent=panicTitle;panicMessageEl.querySelector('#details').textContent=panicDetails;panicElement.appendChild(panicMessageEl);rawPanicMessages.push({title:panicTitle,details:panicDetails});}
-function hasPanic(){return rawPanicMessages.length!==0;}
-function getPanicText(){return rawPanicMessages.map(function(msg){return msg.title;}).join(', ');}
-function exportTo(namespace,fn){const obj=exportPath(namespace);const exports=fn();for(const propertyName in exports){const propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor){Object.defineProperty(obj,propertyName,propertyDescriptor);}}}
-function initialize(){if(global.isVinn){tr.isVinn=true;}else if(global.process&&global.process.versions.node){tr.isNode=true;}else{tr.isVinn=false;tr.isNode=false;tr.doc=document;tr.isMac=/Mac/.test(navigator.platform);tr.isWindows=/Win/.test(navigator.platform);tr.isChromeOS=/CrOS/.test(navigator.userAgent);tr.isLinux=/Linux/.test(navigator.userAgent);}
-tr.isHeadless=tr.isVinn||tr.isNode;}
-return{initialize,exportTo,isExported,isDefined,showPanic,hasPanic,getPanicText,};})();tr.initialize();'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
+this._insertChildren();if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}}});'use strict';if(!window.CustomElements||window.CustomElements.hasNative){if(!Polymer.Settings.useNativeShadow){tr.showPanic('Polymer error','base should use native shadow when possible.');}}'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
EventTarget.decorate=function(target){for(const k in EventTarget.prototype){if(k==='decorate')continue;const v=EventTarget.prototype[k];if(typeof v!=='function')continue;target[k]=v;}};EventTarget.prototype={addEventListener(type,handler){if(!this.listeners_){this.listeners_=Object.create(null);}
if(!(type in this.listeners_)){this.listeners_[type]=[handler];}else{const handlers=this.listeners_[type];if(handlers.indexOf(handler)<0){handlers.push(handler);}}},removeEventListener(type,handler){if(!this.listeners_)return;if(type in this.listeners_){const handlers=this.listeners_[type];const index=handlers.indexOf(handler);if(index>=0){if(handlers.length===1){delete this.listeners_[type];}else{handlers.splice(index,1);}}}},dispatchEvent(event){if(!this.listeners_)return true;event.__defineGetter__('target',()=>this);const realPreventDefault=event.preventDefault;event.preventDefault=function(){realPreventDefault.call(this);this.rawReturnValue=false;};const type=event.type;let prevented=0;if(type in this.listeners_){const handlers=this.listeners_[type].concat();for(let i=0,handler;handler=handlers[i];i++){if(handler.handleEvent){prevented|=handler.handleEvent.call(handler,event)===false;}else{prevented|=handler.call(this,event)===false;}}}
return!prevented&&event.rawReturnValue;},async dispatchAsync(event){if(!this.listeners_)return true;const listeners=this.listeners_[event.type];if(listeners===undefined)return;await Promise.all(listeners.slice().map(listener=>{if(listener.handleEvent){return listener.handleEvent.call(listener,event);}
@@ -4574,8 +4572,8 @@ ChromeGpuHelper.PROCESS_NAME='GPU Process';ChromeGpuHelper.isGpuProcess=function
return process.findAllThreadsNamed('CrGpuMain').length>0;};ChromeGpuHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype};return{ChromeGpuHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){const NET_CATEGORIES=new Set(['net','netlog','disabled-by-default-netlog','disabled-by-default-network']);class ChromeThreadHelper{constructor(thread){this.thread=thread;}
getNetworkEvents(){const networkEvents=[];for(const slice of this.thread.asyncSliceGroup.slices){const categories=tr.b.getCategoryParts(slice.category);const isNetEvent=category=>NET_CATEGORIES.has(category);if(categories.filter(isNetEvent).length===0)continue;networkEvents.push(slice);}
return networkEvents;}}
-return{ChromeThreadHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){const ChromeThreadHelper=tr.model.helpers.ChromeThreadHelper;function ChromeRendererHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain')||process.findAtMostOneThreadNamed('Chrome_InProcRendererThread');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)return false;if(t.name.startsWith('CompositorTileWorker'))return true;if(t.name.startsWith('CompositorRasterWorker'))return true;return false;});this.dedicatedWorkerThreads_=process.findAllThreadsMatching(function(t){return t.name&&t.name.startsWith('DedicatedWorker');});this.foregroundWorkerThreads_=process.findAllThreadsMatching(function(t){return t.name&&t.name.startsWith('ThreadPoolForegroundWorker');});if(!process.name){process.name=ChromeRendererHelper.PROCESS_NAME;}}
-ChromeRendererHelper.PROCESS_NAME='Renderer';ChromeRendererHelper.isRenderProcess=function(process){if(process.findAtMostOneThreadNamed('CrRendererMain'))return true;if(process.findAtMostOneThreadNamed('Compositor'))return true;return false;};ChromeRendererHelper.isTracingProcess=function(process){return process.labels!==undefined&&process.labels.length===1&&process.labels[0]==='chrome://tracing';};ChromeRendererHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;},get dedicatedWorkerThreads(){return this.dedicatedWorkerThreads_;},get foregroundWorkerThreads(){return this.foregroundWorkerThreads_;},get isChromeTracingUI(){return ChromeRendererHelper.isTracingProcess(this.process);},};return{ChromeRendererHelper,};});'use strict';tr.exportTo('tr.model.um',function(){class Segment extends tr.model.TimedEvent{constructor(start,duration){super(start);this.duration=duration;this.expectations_=[];}
+return{ChromeThreadHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){const ChromeThreadHelper=tr.model.helpers.ChromeThreadHelper;function ChromeRendererHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain')||process.findAtMostOneThreadNamed('Chrome_InProcRendererThread');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)return false;if(t.name.startsWith('CompositorTileWorker'))return true;if(t.name.startsWith('CompositorRasterWorker'))return true;return false;});this.dedicatedWorkerThreads_=process.findAllThreadsMatching(function(t){return t.name&&t.name.startsWith('DedicatedWorker');});this.serviceWorkerThreads_=process.findAllThreadsMatching(function(t){return t.name&&t.name.startsWith('ServiceWorker');});this.foregroundWorkerThreads_=process.findAllThreadsMatching(function(t){return t.name&&t.name.startsWith('ThreadPoolForegroundWorker');});if(!process.name){process.name=ChromeRendererHelper.PROCESS_NAME;}}
+ChromeRendererHelper.PROCESS_NAME='Renderer';ChromeRendererHelper.isRenderProcess=function(process){if(process.findAtMostOneThreadNamed('CrRendererMain'))return true;if(process.findAtMostOneThreadNamed('Compositor'))return true;return false;};ChromeRendererHelper.isTracingProcess=function(process){return process.labels!==undefined&&process.labels.length===1&&process.labels[0]==='chrome://tracing';};ChromeRendererHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;},get dedicatedWorkerThreads(){return this.dedicatedWorkerThreads_;},get serviceWorkerThreads(){return this.serviceWorkerThreads_;},get foregroundWorkerThreads(){return this.foregroundWorkerThreads_;},get isChromeTracingUI(){return ChromeRendererHelper.isTracingProcess(this.process);},};return{ChromeRendererHelper,};});'use strict';tr.exportTo('tr.model.um',function(){class Segment extends tr.model.TimedEvent{constructor(start,duration){super(start);this.duration=duration;this.expectations_=[];}
get expectations(){return this.expectations_;}
clone(){const clone=new Segment(this.start,this.duration);clone.expectations.push(...this.expectations);return clone;}
addSegment(other){this.duration+=other.duration;this.expectations.push(...other.expectations);}}
@@ -4799,7 +4797,8 @@ const markers=this.markersBySyncId_.get(syncId);if(markers.length===2){throw new
if(markers[0].domainId===domainId){throw new Error('A clock domain cannot sync with itself.');}
markers.push(marker);this.onSyncCompleted_(markers[0],marker);},get completeSyncIds(){const completeSyncIds=[];for(const[syncId,markers]of this.markersBySyncId){if(markers.length===2)completeSyncIds.push(syncId);}
return completeSyncIds;},get markersBySyncId(){return this.markersBySyncId_;},get domainsSeen(){return this.domainsSeen_;},getModelTimeTransformer(domainId){this.onDomainSeen_(domainId);if(!this.modelDomainId_){this.selectModelDomainId_();}
-return this.getTimeTransformerRaw_(domainId,this.modelDomainId_).fn;},getTimeTransformerError(fromDomainId,toDomainId){this.onDomainSeen_(fromDomainId);this.onDomainSeen_(toDomainId);return this.getTimeTransformerRaw_(fromDomainId,toDomainId).error;},getTimeTransformerRaw_(fromDomainId,toDomainId){const transformer=this.getTransformerBetween_(fromDomainId,toDomainId);if(!transformer){throw new Error('No clock sync markers exist pairing clock domain "'+
+return this.getTimeTransformerRaw_(domainId,this.modelDomainId_).fn;},getModelTimeTransformerInverse(domainId){this.onDomainSeen_(domainId);if(!this.modelDomainId_){this.selectModelDomainId_();}
+return this.getTimeTransformerRaw_(this.modelDomainId_,domainId).fn;},getTimeTransformerError(fromDomainId,toDomainId){this.onDomainSeen_(fromDomainId);this.onDomainSeen_(toDomainId);return this.getTimeTransformerRaw_(fromDomainId,toDomainId).error;},getTimeTransformerRaw_(fromDomainId,toDomainId){const transformer=this.getTransformerBetween_(fromDomainId,toDomainId);if(!transformer){throw new Error('No clock sync markers exist pairing clock domain "'+
fromDomainId+'" '+'with target clock domain "'+
toDomainId+'".');}
return transformer;},getTransformerBetween_(fromDomainId,toDomainId){const visitedDomainIds=new Set();const queue=[{domainId:fromDomainId,transformer:Transformer.IDENTITY}];while(queue.length>0){queue.sort((domain1,domain2)=>domain1.transformer.error-domain2.transformer.error);const current=queue.shift();if(current.domainId===toDomainId){return current.transformer;}
@@ -5154,7 +5153,8 @@ for(const event of this.childEvents()){event.addBoundsToRange(bounds);}},shiftWo
for(const event of this.childEvents()){event.start+=shiftAmount;}
this.updateBounds();},convertTimestampToModelTime(sourceClockDomainName,ts){if(sourceClockDomainName!=='traceEventClock'){throw new Error('Only traceEventClock is supported.');}
return tr.b.Unit.timestampFromUs(ts)+
-this.timestampShiftToZeroAmount_;},get numProcesses(){let n=0;for(const p in this.processes){n++;}
+this.timestampShiftToZeroAmount_;},convertTimestampFromModelTime(targetClockDomainName,ts){if(targetClockDomainName!=='traceEventClock'){throw new Error('Only traceEventClock is supported.');}
+const convertFn=this.clockSyncManager.getModelTimeTransformerInverse(tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL);return convertFn(ts)-this.timestampShiftToZeroAmount_;},get numProcesses(){let n=0;for(const p in this.processes){n++;}
return n;},getProcess(pid){return this.processes[pid];},getOrCreateProcess(pid){if(!this.processes[pid]){this.processes[pid]=new Process(this,pid);}
return this.processes[pid];},addStackFrame(stackFrame){if(this.stackFrames[stackFrame.id]){throw new Error('Stack frame already exists');}
this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},updateCategories_(){const categoriesDict={};this.userModel.addCategoriesToDict(categoriesDict);this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(const pid in this.processes){this.processes[pid].addCategoriesToDict(categoriesDict);}
@@ -5683,10 +5683,10 @@ const profileTreeMap=this.profileTrees_.get(sampleType);if(profileTreeMap.has(id
const profileTree=new tr.model.ProfileTree();profileTreeMap.set(id,profileTree);const info=this.profileInfo_.get(id);if(info!==undefined){profileTree.startTime=info.startTime;profileTree.pid=info.pid;profileTree.tid=info.tid;}
return profileTree;},processSample(event){if(event.args===undefined||event.args.data===undefined){return;}
if(event.id===undefined){throw new Error('No event ID in sample');}
-const data=event.args.data;if(data.startTime!==undefined){this.profileInfo_.set(event.id,{startTime:data.startTime,pid:event.pid,tid:event.tid});}
+const data=event.args.data;if(data.startTime!==undefined){this.profileInfo_.set(`${event.pid} ${event.id}`,{startTime:data.startTime,pid:event.pid,tid:event.tid});}
const timeDeltas=data.timeDeltas;for(const sampleType in data){if(sampleType==='timeDeltas'||sampleType==='startTime'){continue;}
if(data[sampleType].samples&&timeDeltas&&data[sampleType].samples.length!==timeDeltas.length){throw new Error('samples and timeDeltas array should have same length');}
-const profileTree=this.getOrCreateProfileTree_(sampleType,event.id);const nodes=data[sampleType].nodes;const samples=data[sampleType].samples;if(nodes!==undefined){for(const node of nodes){const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);const profileNode=ProfileNodeType.constructFromObject(profileTree,node);if(profileNode===undefined){continue;}
+const profileTree=this.getOrCreateProfileTree_(sampleType,`${event.pid} ${event.id}`);const nodes=data[sampleType].nodes;const samples=data[sampleType].samples;if(nodes!==undefined){for(const node of nodes){const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);const profileNode=ProfileNodeType.constructFromObject(profileTree,node);if(profileNode===undefined){continue;}
profileTree.add(profileNode);}}
if(samples!==undefined){const thread=this.model_.getOrCreateProcess(profileTree.pid).getOrCreateThread(profileTree.tid);for(let i=0,len=samples.length;i<len;++i){const node=profileTree.getNode(samples[i]);profileTree.endTime+=timeDeltas[i];if(node===undefined)continue;const start=this.toModelTimeFromUs_(profileTree.endTime);this.model_.samples.push(new tr.model.Sample(start,node.sampleTitle,node,thread));}}}},processLegacyV8Sample(event){const data=event.args.data;const sampleType='legacySample';const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);if(data.vm_state==='js'&&!data.stack.length)return;const profileTree=this.getOrCreateProfileTree_(sampleType,event.pid);if(profileTree.getNode(-1)===undefined){profileTree.add(new ProfileNodeType(-1,{url:'',scriptId:-1,functionName:'unknown'},undefined));}
let node=undefined;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){const map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();let parentNode=undefined;for(let i=0;i<data.stack.length;i++){const entry=map.lookupEntry(data.stack[i]);if(entry===undefined){node=profileTree.getNode(-1);}else{node=profileTree.getNode(entry.id);if(node===undefined){const sourceInfo=entry.sourceInfo;node=new ProfileNodeType(entry.id,{functionName:entry.name,url:entry.sourceInfo.file,lineNumber:sourceInfo.line!==-1?sourceInfo.line:undefined,columnNumber:sourceInfo.column!==-1?sourceInfo.column:undefined,scriptid:entry.sourceInfo.scriptId},parentNode);profileTree.add(node);}}
@@ -6066,7 +6066,10 @@ this.importer.registerEventHandler(hwcEventName,handler.bind(this));}};Parser.re
const kswapdWakeRE=/nid=(\d+) order=(\d+)/;const kswapdSleepRE=/nid=(\d+)/;const reclaimBeginRE=/order=(\d+) may_writepage=\d+ gfp_flags=(.+)/;const reclaimEndRE=/nr_reclaimed=(\d+)/;const lowmemoryRE=/([^ ]+) \((\d+)\), page cache (\d+)kB \(limit (\d+)kB\), free (-?\d+)Kb/;MemReclaimParser.prototype={__proto__:Parser.prototype,kswapdWake(eventName,cpuNumber,pid,ts,eventBase){const event=kswapdWakeRE.exec(eventBase.details);if(!event)return false;const tgid=parseInt(eventBase.tgid);const nid=parseInt(event[1]);const order=parseInt(event[2]);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){if(order>kthread.order){kthread.order=order;}}else{kthread.openSliceTS=ts;kthread.order=order;}
kthread.waitingFor='kswapSleep';return true;},kswapdSleep(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.waitingFor!=='kswapSleep')return false;kthread.waitingFor=undefined;if(kthread.openSliceTS){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim',eventBase.threadName,kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order});}
kthread.openSliceTS=undefined;kthread.order=undefined;return true;},reclaimBegin(eventName,cpuNumber,pid,ts,eventBase){const event=reclaimBeginRE.exec(eventBase.details);if(!event)return false;const order=parseInt(event[1]);const gfp=event[2];const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.openMemReclaimSliceTS=ts;kthread.order=order;kthread.gfp=gfp;kthread.waitingFor='reclaimEnd';return true;},reclaimEnd(eventName,cpuNumber,pid,ts,eventBase){const event=reclaimEndRE.exec(eventBase.details);if(!event)return false;const nrReclaimed=parseInt(event[1]);const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.waitingFor!=='reclaimEnd')return false;kthread.waitingFor=undefined;if(kthread.openMemReclaimSliceTS!==undefined){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim','direct reclaim',kthread.openMemReclaimSliceTS,ts-kthread.openMemReclaimSliceTS,0,0,{order:kthread.order,gfp:kthread.gfp,nr_reclaimed:nrReclaimed});kthread.openMemReclaimSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;}
-return false;},lowmemoryKill(eventName,cpuNumber,pid,ts,eventBase){const event=lowmemoryRE.exec(eventBase.details);if(!event)return false;const tgid=parseInt(eventBase.tgid);const killedName=event[1];const killedPid=parseInt(event[2]);const cache=parseInt(event[3]);const free=parseInt(event[5]);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.thread.sliceGroup.pushCompleteSlice('lowmemory','low memory kill',ts,0,0,0,{killed_name:killedName,killed_pid:killedPid,cache,free});return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency_limits',PowerParser.prototype.cpuFrequencyLimitsEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
+return false;},lowmemoryKill(eventName,cpuNumber,pid,ts,eventBase){const event=lowmemoryRE.exec(eventBase.details);if(!event)return false;const tgid=parseInt(eventBase.tgid);const killedName=event[1];const killedPid=parseInt(event[2]);const cache=parseInt(event[3]);const free=parseInt(event[5]);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.thread.sliceGroup.pushCompleteSlice('lowmemory','low memory kill',ts,0,0,0,{killed_name:killedName,killed_pid:killedPid,cache,free});return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function MSMParser(importer){Parser.call(this,importer);importer.registerEventHandler('msm_gpu_freq_change',MSMParser.prototype.gpuFrequency.bind(this));importer.registerEventHandler('msm_gpu_submit_flush',MSMParser.prototype.gpuSubmitFlush.bind(this));importer.registerEventHandler('msm_gpu_submit_retired',MSMParser.prototype.gpuSubmitRetired.bind(this));this.model_=importer.model_;this.submits={};this.num_submits=0;}
+MSMParser.prototype={__proto__:Parser.prototype,gpuFrequency(eventName,cpuNumber,pid,ts,eventBase){const event=/new_freq=(\d+)/.exec(eventBase.details);if(!event)return false;const freq=parseInt(event[1]);const counter=this.model_.kernel.getOrCreateCounter('GPU','GPU Frequency');if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries('frequency',ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,freq);});return true;},gpuSubmitFlush(eventName,cpuNumber,pid,ts,eventBase){const event=/id=(\d+) pid=(\d+) ring=(\d+):(\d+) ticks=(\d+)/.exec(eventBase.details);if(!event)return false;const id=parseInt(event[1]);const submit={};submit.flushTS=ts;submit.flushTicks=parseInt(event[5]);submit.pid=parseInt(event[2]);this.submits[id]=submit;this.num_submits++;return true;},gpuSubmitRetired(eventName,cpuNumber,pid,ts,eventBase){const event=/id=(\d+) pid=(\d+) ring=(\d+):(\d+) elapsed=(\d+) ns mhz=(\d+) start=(\d+) end=(\d+)/.exec(eventBase.details);if(!event)return false;const id=parseInt(event[1]);if(!(id in this.submits))return true;const submit=this.submits[id];delete this.submits[id];this.num_submits--;const gpuThread=this.importer.getOrCreatePseudoThread('GPU');submit.elapsedNs=parseInt(event[5]);submit.mhz=parseInt(event[6]);submit.startTicks=parseInt(event[7]);submit.endTicks=parseInt(event[8]);function ticks2ms(ticks){return ticks/19200;}
+const queuedDuration=ticks2ms(submit.startTicks-submit.flushTicks);const runningDuration=ticks2ms(submit.endTicks-submit.startTicks);submit.queuedDuration=queuedDuration;submit.runningDuration=runningDuration;const queued=new tr.model.AsyncSlice('',event[1]+' queued',tr.b.ColorScheme.getColorIdForReservedName('thread_state_runnable'),submit.flushTS,submit,queuedDuration);const running=new tr.model.AsyncSlice('',event[1]+' running',tr.b.ColorScheme.getColorIdForReservedName('thread_state_running'),submit.flushTS+queuedDuration,submit,runningDuration);const async=new tr.model.AsyncSlice('','pipeline',ColorScheme.getColorIdForGeneralPurposeString('ongpu:'+submit.pid),submit.flushTS,submit,queuedDuration+runningDuration);async.hidden=true;async.subSlices.push(queued);async.subSlices.push(running);gpuThread.thread.asyncSliceGroup.push(async);const onGpu=new tr.model.ThreadSlice('',event[1],ColorScheme.getColorIdForGeneralPurposeString('ongpu:'+submit.pid),submit.flushTS+queuedDuration,submit,runningDuration);gpuThread.thread.sliceGroup.pushSlice(onGpu);return true;}};Parser.register(MSMParser);return{MSMParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency_limits',PowerParser.prototype.cpuFrequencyLimitsEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
PowerParser.prototype={__proto__:Parser.prototype,cpuStateSlice(ts,targetCpuNumber,eventType,cpuState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);if(eventType!=='1'){this.importer.model.importWarning({type:'parse_error',message:'Don\'t understand power_start events of '+'type '+eventType});return;}
const powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
powerCounter.series.forEach(function(series){series.addCounterSample(ts,cpuState);});},cpuIdleSlice(ts,targetCpuNumber,cpuState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name)));}
@@ -6472,8 +6475,7 @@ return tr.b.math.Rect.fromXYWH(position[0],position[1],size[0],size[1]);}
function scrollIntoViewIfNeeded(el){const pr=el.parentElement.getBoundingClientRect();const cr=el.getBoundingClientRect();if(cr.top<pr.top){el.scrollIntoView(true);}else if(cr.bottom>pr.bottom){el.scrollIntoView(false);}}
function extractUrlString(url){let extracted=url.replace(/url\((.*)\)/,'$1');extracted=extracted.replace(/\"(.*)\"/,'$1');return extracted;}
function toThreeDigitLocaleString(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}
-function isUnknownElementName(name){return document.createElement(name)instanceof HTMLUnknownElement;}
-return{isUnknownElementName,toThreeDigitLocaleString,instantiateTemplate,windowRectForElement,scrollIntoViewIfNeeded,extractUrlString,};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)return{};const THIS_DOC=document._currentScript.ownerDocument;const Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate(){Polymer.dom(this).classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);const createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);Polymer.dom(this.shadow_).appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=Polymer.dom(this.shadow_).querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);Polymer.dom(this.shadow_).querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new MutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(Polymer.dom(this.shadow_).querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get(){return Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent;},set(title){Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return Polymer.dom(this.shadow_).querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)return;this.visible_=newValue;const e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_(){this.visible_?this.show_():this.hide_();},show_(){Polymer.dom(this.parentEl_).appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));this.closeBtn_.addEventListener('click',this.onClose_);}
+return{toThreeDigitLocaleString,instantiateTemplate,windowRectForElement,scrollIntoViewIfNeeded,extractUrlString,};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)return{};const THIS_DOC=document._currentScript.ownerDocument;const Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate(){Polymer.dom(this).classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);const createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);Polymer.dom(this.shadow_).appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=Polymer.dom(this.shadow_).querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);Polymer.dom(this.shadow_).querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new MutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(Polymer.dom(this.shadow_).querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get(){return Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent;},set(title){Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return Polymer.dom(this.shadow_).querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)return;this.visible_=newValue;const e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_(){this.visible_?this.show_():this.hide_();},show_(){Polymer.dom(this.parentEl_).appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));this.closeBtn_.addEventListener('click',this.onClose_);}
this.parentEl_.addEventListener('focusin',this.onFocusIn_);this.tabIndex=0;const elList=Polymer.dom(this).querySelectorAll('button, input, list, select, a');if(elList.length>0){if(elList[0]===this.closeBtn_){if(elList.length>1)return elList[1].focus();}else{return elList[0].focus();}}
this.focus();},hide_(){Polymer.dom(this.parentEl_).removeChild(this);this.parentEl_.removeEventListener('focusin',this.onFocusIn_);if(this.closeBtn_){this.closeBtn_.removeEventListener('click',this.onClose_);}
document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_(e){this.visible=false;if((e.type!=='keydown')||(e.type==='keydown'&&e.keyCode===27)){e.stopPropagation();}
@@ -7090,7 +7092,7 @@ asDictInto_(d){d.diagnostics=this._diagnostics.map(d=>d.asDictOrReference());}
static deserialize(data,deserializer){return new UnmergeableDiagnosticSet(d.map(i=>deserializer.getDiagnostic(i).diagnostic));}
serialize(serializer){return this._diagnostics.map(d=>serializer.getOrAllocateDiagnosticId('',d));}
static fromDict(d){return new UnmergeableDiagnosticSet(d.diagnostics.map(d=>((typeof d==='string')?new tr.v.d.DiagnosticRef(d):tr.v.d.Diagnostic.fromDict(d))));}}
-tr.v.d.Diagnostic.register(UnmergeableDiagnosticSet,{elementName:'tr-v-ui-unmergeable-diagnostic-set-span'});return{UnmergeableDiagnosticSet,};});'use strict';tr.exportTo('tr.v.d',function(){const RESERVED_INFOS={ANGLE_REVISIONS:{name:'angleRevisions',type:tr.v.d.GenericSet},ARCHITECTURES:{name:'architectures',type:tr.v.d.GenericSet},BENCHMARKS:{name:'benchmarks',type:tr.v.d.GenericSet},BENCHMARK_START:{name:'benchmarkStart',type:tr.v.d.DateRange},BENCHMARK_DESCRIPTIONS:{name:'benchmarkDescriptions',type:tr.v.d.GenericSet},BOTS:{name:'bots',type:tr.v.d.GenericSet},BUG_COMPONENTS:{name:'bugComponents',type:tr.v.d.GenericSet},BUILDS:{name:'builds',type:tr.v.d.GenericSet},CATAPULT_REVISIONS:{name:'catapultRevisions',type:tr.v.d.GenericSet},CHROMIUM_COMMIT_POSITIONS:{name:'chromiumCommitPositions',type:tr.v.d.GenericSet},CHROMIUM_REVISIONS:{name:'chromiumRevisions',type:tr.v.d.GenericSet},DESCRIPTION:{name:'description',type:tr.v.d.GenericSet},DEVICE_IDS:{name:'deviceIds',type:tr.v.d.GenericSet},DOCUMENTATION_URLS:{name:'documentationUrls',type:tr.v.d.GenericSet},INFO_BLURB:{name:'infoBlurb',type:tr.v.d.GenericSet},FUCHSIA_GARNET_REVISIONS:{name:'fuchsiaGarnetRevisions',type:tr.v.d.GenericSet},FUCHSIA_PERIDOT_REVISIONS:{name:'fuchsiaPeridotRevisions',type:tr.v.d.GenericSet},FUCHSIA_TOPAZ_REVISIONS:{name:'fuchsiaTopazRevisions',type:tr.v.d.GenericSet},FUCHSIA_ZIRCON_REVISIONS:{name:'fuchsiaZirconRevisions',type:tr.v.d.GenericSet},GPUS:{name:'gpus',type:tr.v.d.GenericSet},IS_REFERENCE_BUILD:{name:'isReferenceBuild',type:tr.v.d.GenericSet},LABELS:{name:'labels',type:tr.v.d.GenericSet},LOG_URLS:{name:'logUrls',type:tr.v.d.GenericSet},MASTERS:{name:'masters',type:tr.v.d.GenericSet},MEMORY_AMOUNTS:{name:'memoryAmounts',type:tr.v.d.GenericSet},OS_NAMES:{name:'osNames',type:tr.v.d.GenericSet},OS_VERSIONS:{name:'osVersions',type:tr.v.d.GenericSet},OWNERS:{name:'owners',type:tr.v.d.GenericSet},POINT_ID:{name:'pointId',type:tr.v.d.GenericSet},PRODUCT_VERSIONS:{name:'productVersions',type:tr.v.d.GenericSet},REVISION_TIMESTAMPS:{name:'revisionTimestamps',type:tr.v.d.DateRange},SKIA_REVISIONS:{name:'skiaRevisions',type:tr.v.d.GenericSet},STATISTICS_NAMES:{name:'statisticsNames',type:tr.v.d.GenericSet},STORIES:{name:'stories',type:tr.v.d.GenericSet},STORYSET_REPEATS:{name:'storysetRepeats',type:tr.v.d.GenericSet},STORY_TAGS:{name:'storyTags',type:tr.v.d.GenericSet},SUMMARY_KEYS:{name:'summaryKeys',type:tr.v.d.GenericSet},TEST_PATH:{name:'testPath',type:tr.v.d.GenericSet},TRACE_START:{name:'traceStart',type:tr.v.d.DateRange},TRACE_URLS:{name:'traceUrls',type:tr.v.d.GenericSet},V8_COMMIT_POSITIONS:{name:'v8CommitPositions',type:tr.v.d.DateRange},V8_REVISIONS:{name:'v8Revisions',type:tr.v.d.GenericSet},WEBRTC_REVISIONS:{name:'webrtcRevisions',type:tr.v.d.GenericSet},WEBRTC_INTERNAL_REVISIONS:{name:'webrtcInternalRevisions',type:tr.v.d.GenericSet},};const RESERVED_NAMES={};const RESERVED_NAMES_TO_TYPES=new Map();for(const[codename,info]of Object.entries(RESERVED_INFOS)){RESERVED_NAMES[codename]=info.name;if(RESERVED_NAMES_TO_TYPES.has(info.name)){throw new Error(`Duplicate reserved name "${info.name}"`);}
+tr.v.d.Diagnostic.register(UnmergeableDiagnosticSet,{elementName:'tr-v-ui-unmergeable-diagnostic-set-span'});return{UnmergeableDiagnosticSet,};});'use strict';tr.exportTo('tr.v.d',function(){const RESERVED_INFOS={ALERT_GROUPING:{name:'alertGrouping',type:tr.v.d.GenericSet},ANGLE_REVISIONS:{name:'angleRevisions',type:tr.v.d.GenericSet},ARCHITECTURES:{name:'architectures',type:tr.v.d.GenericSet},BENCHMARKS:{name:'benchmarks',type:tr.v.d.GenericSet},BENCHMARK_START:{name:'benchmarkStart',type:tr.v.d.DateRange},BENCHMARK_DESCRIPTIONS:{name:'benchmarkDescriptions',type:tr.v.d.GenericSet},BOTS:{name:'bots',type:tr.v.d.GenericSet},BUG_COMPONENTS:{name:'bugComponents',type:tr.v.d.GenericSet},BUILDS:{name:'builds',type:tr.v.d.GenericSet},CATAPULT_REVISIONS:{name:'catapultRevisions',type:tr.v.d.GenericSet},CHROMIUM_COMMIT_POSITIONS:{name:'chromiumCommitPositions',type:tr.v.d.GenericSet},CHROMIUM_REVISIONS:{name:'chromiumRevisions',type:tr.v.d.GenericSet},DESCRIPTION:{name:'description',type:tr.v.d.GenericSet},DEVICE_IDS:{name:'deviceIds',type:tr.v.d.GenericSet},DOCUMENTATION_URLS:{name:'documentationLinks',type:tr.v.d.GenericSet},INFO_BLURB:{name:'infoBlurb',type:tr.v.d.GenericSet},FUCHSIA_GARNET_REVISIONS:{name:'fuchsiaGarnetRevisions',type:tr.v.d.GenericSet},FUCHSIA_PERIDOT_REVISIONS:{name:'fuchsiaPeridotRevisions',type:tr.v.d.GenericSet},FUCHSIA_TOPAZ_REVISIONS:{name:'fuchsiaTopazRevisions',type:tr.v.d.GenericSet},FUCHSIA_ZIRCON_REVISIONS:{name:'fuchsiaZirconRevisions',type:tr.v.d.GenericSet},GPUS:{name:'gpus',type:tr.v.d.GenericSet},IS_REFERENCE_BUILD:{name:'isReferenceBuild',type:tr.v.d.GenericSet},LABELS:{name:'labels',type:tr.v.d.GenericSet},LOG_URLS:{name:'logUrls',type:tr.v.d.GenericSet},MASTERS:{name:'masters',type:tr.v.d.GenericSet},MEMORY_AMOUNTS:{name:'memoryAmounts',type:tr.v.d.GenericSet},OS_NAMES:{name:'osNames',type:tr.v.d.GenericSet},OS_VERSIONS:{name:'osVersions',type:tr.v.d.GenericSet},OWNERS:{name:'owners',type:tr.v.d.GenericSet},POINT_ID:{name:'pointId',type:tr.v.d.GenericSet},PRODUCT_VERSIONS:{name:'productVersions',type:tr.v.d.GenericSet},REVISION_TIMESTAMPS:{name:'revisionTimestamps',type:tr.v.d.DateRange},SKIA_REVISIONS:{name:'skiaRevisions',type:tr.v.d.GenericSet},STATISTICS_NAMES:{name:'statisticsNames',type:tr.v.d.GenericSet},STORIES:{name:'stories',type:tr.v.d.GenericSet},STORYSET_REPEATS:{name:'storysetRepeats',type:tr.v.d.GenericSet},STORY_TAGS:{name:'storyTags',type:tr.v.d.GenericSet},SUMMARY_KEYS:{name:'summaryKeys',type:tr.v.d.GenericSet},TEST_PATH:{name:'testPath',type:tr.v.d.GenericSet},TRACE_START:{name:'traceStart',type:tr.v.d.DateRange},TRACE_URLS:{name:'traceUrls',type:tr.v.d.GenericSet},V8_COMMIT_POSITIONS:{name:'v8CommitPositions',type:tr.v.d.DateRange},V8_REVISIONS:{name:'v8Revisions',type:tr.v.d.GenericSet},WEBRTC_REVISIONS:{name:'webrtcRevisions',type:tr.v.d.GenericSet},WEBRTC_INTERNAL_REVISIONS:{name:'webrtcInternalRevisions',type:tr.v.d.GenericSet},};const RESERVED_NAMES={};const RESERVED_NAMES_TO_TYPES=new Map();for(const[codename,info]of Object.entries(RESERVED_INFOS)){RESERVED_NAMES[codename]=info.name;if(RESERVED_NAMES_TO_TYPES.has(info.name)){throw new Error(`Duplicate reserved name "${info.name}"`);}
RESERVED_NAMES_TO_TYPES.set(info.name,info.type);}
const RESERVED_NAMES_SET=new Set(Object.values(RESERVED_NAMES));return{RESERVED_INFOS,RESERVED_NAMES,RESERVED_NAMES_SET,RESERVED_NAMES_TO_TYPES,};});'use strict';tr.exportTo('tr.v.d',function(){class DiagnosticMap extends Map{constructor(opt_allowReservedNames){super();if(opt_allowReservedNames===undefined){opt_allowReservedNames=true;}
this.allowReservedNames_=opt_allowReservedNames;}
@@ -7134,13 +7136,17 @@ return[this.count,this.diagnosticMaps.map(d=>d.asDict())];}}
const DEFAULT_SUMMARY_OPTIONS=new Map([['avg',true],['count',true],['geometricMean',false],['max',true],['min',true],['nans',false],['std',true],['sum',true],]);class Histogram{constructor(name,unit,opt_binBoundaries){if(!(unit instanceof tr.b.Unit)){throw new Error('unit must be a Unit: '+unit);}
let binBoundaries=opt_binBoundaries;if(!binBoundaries){const baseUnit=unit.baseUnit?unit.baseUnit:unit;binBoundaries=DEFAULT_BOUNDARIES_FOR_UNIT.get(baseUnit.unitName);}
this.binBoundariesDict_=binBoundaries.asDict();this.allBins=binBoundaries.bins.slice();this.description='';const allowReservedNames=false;this.diagnostics_=new tr.v.d.DiagnosticMap(allowReservedNames);this.maxNumSampleValues_=this.defaultMaxNumSampleValues_;this.name_=name;this.nanDiagnosticMaps=[];this.numNans=0;this.running_=undefined;this.sampleValues_=[];this.sampleMeans_=[];this.summaryOptions=new Map(DEFAULT_SUMMARY_OPTIONS);this.summaryOptions.set('percentile',[]);this.summaryOptions.set('iprs',[]);this.summaryOptions.set('ci',[]);this.unit=unit;}
-static create(name,unit,samples,opt_options){const options=opt_options||{};const hist=new Histogram(name,unit,options.binBoundaries);if(options.description)hist.description=options.description;if(options.summaryOptions){let summaryOptions=options.summaryOptions;if(!(summaryOptions instanceof Map)){summaryOptions=Object.entries(summaryOptions);}
+static create(name,unit,samples,opt_options){const options=opt_options||{};const hist=new Histogram(name,unit,options.binBoundaries);if(options.alertGrouping!==undefined){hist.setAlertGrouping(options.alertGrouping);}
+if(options.description)hist.description=options.description;if(options.summaryOptions){let summaryOptions=options.summaryOptions;if(!(summaryOptions instanceof Map)){summaryOptions=Object.entries(summaryOptions);}
for(const[name,value]of summaryOptions){hist.summaryOptions.set(name,value);}}
if(options.diagnostics!==undefined){let diagnostics=options.diagnostics;if(!(diagnostics instanceof Map)){diagnostics=Object.entries(diagnostics);}
for(const[name,diagnostic]of diagnostics){if(!diagnostic)continue;hist.diagnostics.set(name,diagnostic);}}
if(!(samples instanceof Array))samples=[samples];for(const sample of samples){if(typeof sample==='object'){hist.addSample(sample.value,sample.diagnostics);}else{hist.addSample(sample);}}
return hist;}
get diagnostics(){return this.diagnostics_;}
+setAlertGrouping(alertGrouping){if(alertGrouping===undefined||alertGrouping===null||alertGrouping.length===undefined){throw Error('alertGrouping must be an array');}
+for(const alertGroup of alertGrouping){if(!Object.values(tr.v.d.ALERT_GROUPS).includes(alertGroup)){throw Error(`Alert group ${alertGroup} must be added to `+'/tracing/value/diagnostics/alert_groups.html');}}
+this.diagnostics.set(tr.v.d.RESERVED_NAMES.ALERT_GROUPING,new tr.v.d.GenericSet(alertGrouping));}
get running(){return this.running_;}
get maxNumSampleValues(){return this.maxNumSampleValues_;}
set maxNumSampleValues(n){this.maxNumSampleValues_=n;tr.b.math.Statistics.uniformlySampleArray(this.sampleValues_,this.maxNumSampleValues_);}
@@ -7362,7 +7368,7 @@ return true;}
Polymer({is:'tr-ui-a-generic-object-view',ready(){this.object_=undefined;},get object(){return this.object_;},set object(object){this.object_=object;this.updateContents_();},updateContents_(){Polymer.dom(this.$.content).textContent='';this.appendElementsForType_('',this.object_,0,0,5,'');},appendElementsForType_(label,object,indent,depth,maxDepth,suffix){if(depth>maxDepth){this.appendSimpleText_(label,indent,'<recursion limit reached>',suffix);return;}
if(object===undefined){this.appendSimpleText_(label,indent,'undefined',suffix);return;}
if(object===null){this.appendSimpleText_(label,indent,'null',suffix);return;}
-if(!(object instanceof Object)){const type=typeof object;if(type!=='string'){return this.appendSimpleText_(label,indent,object,suffix);}
+if(!(object instanceof Object)){const type=typeof object;if(type!=='string'){return this.appendSimpleText_(label,indent,String(object),suffix);}
let objectReplaced=false;if((object[0]==='{'&&object[object.length-1]==='}')||(object[0]==='['&&object[object.length-1]===']')){try{object=JSON.parse(object);objectReplaced=true;}catch(e){}}
if(!objectReplaced){if(object.includes('\n')){const lines=object.split('\n');lines.forEach(function(line,i){let text;let ioff;let ll;let ss;if(i===0){text='"'+line;ioff=0;ll=label;ss='';}else if(i<lines.length-1){text=line;ioff=1;ll='';ss='';}else{text=line+'"';ioff=1;ll='';ss=suffix;}
const el=this.appendSimpleText_(ll,indent+ioff*label.length+ioff,text,ss);el.style.whiteSpace='pre';return el;},this);return;}
@@ -7700,7 +7706,8 @@ rows.push({name:'Title',value:title});}
if(event.category){rows.push({name:'Category',value:event.category});}
if(event.model!==undefined){const ufc=event.model.getUserFriendlyCategoryFromEvent(event);if(ufc!==undefined){rows.push({name:'User Friendly Category',value:ufc});}}
if(event.name){rows.push({name:'Name',value:event.name});}
-rows.push({name:'Start',value:tr.v.ui.createScalarSpan(event.start,{unit:tr.b.Unit.byName.timeStampInMs})});if(event.duration){rows.push({name:'Wall Duration',value:tr.v.ui.createScalarSpan(event.duration,{unit:tr.b.Unit.byName.timeDurationInMs})});}
+rows.push({name:'Start',value:tr.v.ui.createScalarSpan(event.start,{unit:tr.b.Unit.byName.timeStampInMs})});if(event.category==='android'&&event.model!==undefined){rows.push({name:'Start (Absolute time)',value:tr.v.ui.createScalarSpan(event.model.convertTimestampFromModelTime('traceEventClock',event.start),{unit:tr.b.Unit.byName.timeStampInMs})});}
+if(event.duration){rows.push({name:'Wall Duration',value:tr.v.ui.createScalarSpan(event.duration,{unit:tr.b.Unit.byName.timeDurationInMs})});}
if(event.cpuDuration){rows.push({name:'CPU Duration',value:tr.v.ui.createScalarSpan(event.cpuDuration,{unit:tr.b.Unit.byName.timeDurationInMs})});}
if(event.subSlices!==undefined&&event.subSlices.length!==0){if(event.selfTime){rows.push({name:'Self Time',value:tr.v.ui.createScalarSpan(event.selfTime,{unit:tr.b.Unit.byName.timeDurationInMs})});}
if(event.cpuSelfTime){const cpuSelfTimeEl=tr.v.ui.createScalarSpan(event.cpuSelfTime,{unit:tr.b.Unit.byName.timeDurationInMs});if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
@@ -8064,21 +8071,21 @@ MetricRegistry.checkFilename(metric.name);});return{MetricRegistry,};});'use str
if(slice.title==='RenderAccessibilityImpl::SendLocationChanges'){renderAccessibilityLocationsHist.addSample(slice.duration,{event:new tr.v.d.RelatedEventSet(slice)});}}}
for(const browserHelper of Object.values(chromeHelper.browserHelpers)){const mainThread=browserHelper.mainThread;if(mainThread===undefined)continue;for(const slice of mainThread.getDescendantEvents()){if(slice.title==='BrowserAccessibilityManager::OnAccessibilityEvents'){browserAccessibilityEventsHist.addSample(slice.duration,{event:new tr.v.d.RelatedEventSet(slice)});}}}
histograms.addHistogram(browserAccessibilityEventsHist);histograms.addHistogram(renderAccessibilityEventsHist);histograms.addHistogram(renderAccessibilityLocationsHist);}
-tr.metrics.MetricRegistry.register(accessibilityMetric);return{accessibilityMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const MESSAGE_LOOP_EVENT_NAME='Startup.BrowserMessageLoopStartTime';const CONTENT_START_EVENT_NAME='content::Start';const NAVIGATION_EVENT_NAME='Navigation StartToCommit';const FIRST_CONTENTFUL_PAINT_EVENT_NAME='firstContentfulPaint';function androidStartupMetric(histograms,model){let messageLoopStartEvents=[];let navigationEvents=[];const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper)return;for(const helper of chromeHelper.browserHelpers){for(const ev of helper.mainThread.asyncSliceGroup.childEvents()){if(ev.title===MESSAGE_LOOP_EVENT_NAME){messageLoopStartEvents.push(ev);}else if(ev.title===NAVIGATION_EVENT_NAME){navigationEvents.push(ev);}}}
+tr.metrics.MetricRegistry.register(accessibilityMetric);return{accessibilityMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const MESSAGE_LOOP_EVENT_NAME='Startup.BrowserMessageLoopStartTime';const CONTENT_START_EVENT_NAME='content::Start';const NAVIGATION_EVENT_NAME='Navigation StartToCommit';const FIRST_CONTENTFUL_PAINT_EVENT_NAME='firstContentfulPaint';const APPLICATION_START_EVENT_NAME='Startup.LoadTime.ProcessCreateToApplicationStart';function androidStartupMetric(histograms,model){let messageLoopStartEvents=[];let applicationStartEvents=[];let navigationEvents=[];const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper)return;for(const helper of chromeHelper.browserHelpers){for(const ev of helper.mainThread.asyncSliceGroup.childEvents()){if(ev.title===MESSAGE_LOOP_EVENT_NAME){messageLoopStartEvents.push(ev);}else if(ev.title===APPLICATION_START_EVENT_NAME){applicationStartEvents.push(ev);}else if(ev.title===NAVIGATION_EVENT_NAME){navigationEvents.push(ev);}}}
let contentStartEvents=[];let firstContentfulPaintEvents=[];const rendererHelpers=chromeHelper.rendererHelpers;const pids=Object.keys(rendererHelpers);for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){if(!rendererHelper.mainThread)continue;for(const ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(ev.title===FIRST_CONTENTFUL_PAINT_EVENT_NAME){firstContentfulPaintEvents.push(ev);break;}else if(ev.title===CONTENT_START_EVENT_NAME){contentStartEvents.push(ev);}}}
-let totalBrowserStarts=messageLoopStartEvents.length;let totalContentStartEvents=contentStartEvents.length;let totalFcpEvents=firstContentfulPaintEvents.length;let totalNavigations=navigationEvents.length;if(totalFcpEvents!==totalBrowserStarts||totalNavigations!==totalBrowserStarts||totalContentStartEvents!==totalBrowserStarts||totalBrowserStarts===0){messageLoopStartEvents=[];contentStartEvents=[];navigationEvents=[];firstContentfulPaintEvents=[];for(const proc of Object.values(model.processes)){for(const ev of proc.getDescendantEvents()){if(ev.title===MESSAGE_LOOP_EVENT_NAME){messageLoopStartEvents.push(ev);}else if(ev.title===NAVIGATION_EVENT_NAME){navigationEvents.push(ev);}else if(ev.title===CONTENT_START_EVENT_NAME){contentStartEvents.push(ev);}}
+let totalBrowserStarts=messageLoopStartEvents.length;let totalContentStartEvents=contentStartEvents.length;let totalFcpEvents=firstContentfulPaintEvents.length;let totalNavigations=navigationEvents.length;let totalApplicationStartEvents=applicationStartEvents.length;if(totalFcpEvents!==totalBrowserStarts||totalNavigations!==totalBrowserStarts||totalContentStartEvents!==totalBrowserStarts||totalApplicationStartEvents!==totalBrowserStarts||totalBrowserStarts===0){messageLoopStartEvents=[];contentStartEvents=[];navigationEvents=[];firstContentfulPaintEvents=[];applicationStartEvents=[];for(const proc of Object.values(model.processes)){for(const ev of proc.getDescendantEvents()){if(ev.title===MESSAGE_LOOP_EVENT_NAME){messageLoopStartEvents.push(ev);}else if(ev.title===APPLICATION_START_EVENT_NAME){applicationStartEvents.push(ev);}else if(ev.title===NAVIGATION_EVENT_NAME){navigationEvents.push(ev);}else if(ev.title===CONTENT_START_EVENT_NAME){contentStartEvents.push(ev);}}
for(const ev of proc.getDescendantEvents()){if(ev.title===FIRST_CONTENTFUL_PAINT_EVENT_NAME){firstContentfulPaintEvents.push(ev);break;}}}
-totalBrowserStarts=messageLoopStartEvents.length;totalContentStartEvents=contentStartEvents.length;totalNavigations=navigationEvents.length;totalFcpEvents=firstContentfulPaintEvents.length;}
+totalBrowserStarts=messageLoopStartEvents.length;totalContentStartEvents=contentStartEvents.length;totalNavigations=navigationEvents.length;totalFcpEvents=firstContentfulPaintEvents.length;totalApplicationStartEvents=applicationStartEvents.length;}
function orderEvents(event1,event2){return event1.start-event2.start;}
-messageLoopStartEvents.sort(orderEvents);contentStartEvents.sort(orderEvents);navigationEvents.sort(orderEvents);firstContentfulPaintEvents.sort(orderEvents);if(totalFcpEvents<totalBrowserStarts){throw new Error('Found fewer FCP events ('+totalFcpEvents+') than browser starts ('+totalBrowserStarts+')');}
-const messageLoopStartHistogram=histograms.createHistogram('messageloop_start_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const contentStartHistogram=histograms.createHistogram('experimental_content_start_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const navigationStartHistogram=histograms.createHistogram('experimental_navigation_start_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const navigationCommitHistogram=histograms.createHistogram('navigation_commit_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const firstContentfulPaintHistogram=histograms.createHistogram('first_contentful_paint_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);let contentIndex=0;let navIndex=0;let fcpIndex=0;for(let loopStartIndex=0;loopStartIndex<totalBrowserStarts;){const startEvent=messageLoopStartEvents[loopStartIndex];if(fcpIndex===totalFcpEvents){break;}
-const contentStartEvent=contentIndex<contentStartEvents.length?contentStartEvents[contentIndex]:null;if(contentStartEvent&&contentStartEvent.start<startEvent.start){contentIndex++;continue;}
-const navEvent=navIndex<navigationEvents.length?navigationEvents[navIndex]:null;if(navEvent&&navEvent.start<startEvent.start){navIndex++;continue;}
-const fcpEvent=firstContentfulPaintEvents[fcpIndex];if(fcpEvent.start<startEvent.start){fcpIndex++;continue;}
+messageLoopStartEvents.sort(orderEvents);applicationStartEvents.sort(orderEvents);contentStartEvents.sort(orderEvents);navigationEvents.sort(orderEvents);firstContentfulPaintEvents.sort(orderEvents);if(totalFcpEvents<totalBrowserStarts){throw new Error('Found fewer FCP events ('+totalFcpEvents+') than browser starts ('+totalBrowserStarts+')');}
+const messageLoopStartHistogram=histograms.createHistogram('messageloop_start_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const contentStartHistogram=histograms.createHistogram('experimental_content_start_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const navigationStartHistogram=histograms.createHistogram('experimental_navigation_start_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const navigationCommitHistogram=histograms.createHistogram('navigation_commit_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const firstContentfulPaintHistogram=histograms.createHistogram('first_contentful_paint_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);const applicationStartHistogram=histograms.createHistogram('process_create_to_app_start_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[]);let contentIndex=0;let navIndex=0;let fcpIndex=0;for(let loopStartIndex=0;loopStartIndex<totalBrowserStarts;){const loopStartEvent=messageLoopStartEvents[loopStartIndex];const applicationStartEvent=applicationStartEvents[loopStartIndex];if(fcpIndex===totalFcpEvents){break;}
+const contentStartEvent=contentIndex<contentStartEvents.length?contentStartEvents[contentIndex]:null;if(contentStartEvent&&contentStartEvent.start<loopStartEvent.start){contentIndex++;continue;}
+const navEvent=navIndex<navigationEvents.length?navigationEvents[navIndex]:null;if(navEvent&&navEvent.start<loopStartEvent.start){navIndex++;continue;}
+const fcpEvent=firstContentfulPaintEvents[fcpIndex];if(fcpEvent.start<loopStartEvent.start){fcpIndex++;continue;}
loopStartIndex++;if(fcpIndex<2){continue;}
-messageLoopStartHistogram.addSample(startEvent.duration,{events:new tr.v.d.RelatedEventSet([startEvent])});if(contentStartEvent){contentStartHistogram.addSample(contentStartEvent.start-startEvent.start,{events:new tr.v.d.RelatedEventSet([startEvent,contentStartEvent])});}
-if(navEvent){navigationStartHistogram.addSample(navEvent.start-startEvent.start,{events:new tr.v.d.RelatedEventSet([startEvent,navEvent])});navigationCommitHistogram.addSample(navEvent.end-startEvent.start,{events:new tr.v.d.RelatedEventSet([startEvent,navEvent])});}
-firstContentfulPaintHistogram.addSample(fcpEvent.end-startEvent.start,{events:new tr.v.d.RelatedEventSet([startEvent,fcpEvent])});}}
+messageLoopStartHistogram.addSample(loopStartEvent.duration,{events:new tr.v.d.RelatedEventSet([loopStartEvent])});if(contentStartEvent){contentStartHistogram.addSample(contentStartEvent.start-loopStartEvent.start,{events:new tr.v.d.RelatedEventSet([loopStartEvent,contentStartEvent])});}
+if(navEvent){navigationStartHistogram.addSample(navEvent.start-loopStartEvent.start,{events:new tr.v.d.RelatedEventSet([loopStartEvent,navEvent])});navigationCommitHistogram.addSample(navEvent.end-loopStartEvent.start,{events:new tr.v.d.RelatedEventSet([loopStartEvent,navEvent])});}
+firstContentfulPaintHistogram.addSample(fcpEvent.end-loopStartEvent.start,{events:new tr.v.d.RelatedEventSet([loopStartEvent,fcpEvent])});if(applicationStartEvent){applicationStartHistogram.addSample(applicationStartEvent.duration,{events:new tr.v.d.RelatedEventSet([applicationStartEvent])});}}}
tr.metrics.MetricRegistry.register(androidStartupMetric);return{androidStartupMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const MAX_INPUT_EVENT_TO_STARTUP_DELAY_IN_MS=2000;const MIN_DRAW_DELAY_IN_MS=80;const MAX_DRAW_DELAY_IN_MS=2000;function findProcess(processName,model){for(const pid in model.processes){const process=model.processes[pid];if(process.name===processName){return process;}}
return undefined;}
function findThreads(process,threadPrefix){if(process===undefined)return undefined;const threads=[];for(const tid in process.threads){const thread=process.threads[tid];if(thread.name.startsWith(threadPrefix)){threads.push(thread);}}
@@ -8139,7 +8146,7 @@ function topGarbageCollectionEventName(event){if(event.title===FULL_GC_EVENT){if
return TOP_GC_EVENTS[event.title];}
function topGarbageCollectionEventNames(){return Object.values(TOP_GC_EVENTS);}
function subGarbageCollectionEventName(event){const topEvent=findParent(event,isTopGarbageCollectionEvent);const prefix=topEvent?topGarbageCollectionEventName(topEvent):'unknown';const name=event.title.replace('V8.GC_MC_','').replace('V8.GC_SCAVENGER_','').replace('V8.GC_','').replace(/_/g,'-').toLowerCase();return prefix+'-'+name;}
-function jsExecutionThreads(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let threads=[];for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){if(rendererHelper.isChromeTracingUI)continue;threads.push(rendererHelper.mainThread);threads=threads.concat(rendererHelper.dedicatedWorkerThreads);threads=threads.concat(rendererHelper.foregroundWorkerThreads);}
+function jsExecutionThreads(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let threads=[];for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){if(rendererHelper.isChromeTracingUI)continue;threads.push(rendererHelper.mainThread);threads=threads.concat(rendererHelper.dedicatedWorkerThreads);threads=threads.concat(rendererHelper.serviceWorkerThreads);threads=threads.concat(rendererHelper.foregroundWorkerThreads);}
return threads;}
function groupAndProcessEvents(model,filterCallback,groupCallback,processCallback,groups){const groupToEvents={};if(groups){for(const group of groups){groupToEvents[group]=[];}}
const threads=jsExecutionThreads(model);for(const thread of threads){for(const event of thread.sliceGroup.childEvents()){if(!filterCallback(event))continue;const group=groupCallback(event);if(groups&&!(group in groupToEvents)){continue;}
@@ -8163,8 +8170,10 @@ return mu;}
function addMutatorUtilization(metricName,eventFilter,timeWindows,rendererHelpers,histograms){const histogramMap=new Map();for(const timeWindow of timeWindows){const summaryOptions={avg:false,count:false,max:false,min:true,std:false,sum:false};const description=`The minimum mutator utilization in ${timeWindow}ms time window`;const histogram=histograms.createHistogram(`${metricName}-${timeWindow}ms_window`,tr.b.Unit.byName.normalizedPercentage_biggerIsBetter,[],{summaryOptions,description});histogramMap.set(timeWindow,histogram);}
for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;if(rendererHelper.mainThread===undefined)continue;const pauses=[];for(const event of rendererHelper.mainThread.sliceGroup.childEvents()){if(eventFilter(event)&&event.end>event.start){pauses.push({start:event.start,end:event.end});}}
pauses.sort((a,b)=>a.start-b.start);const start=rendererHelper.mainThread.bounds.min;const end=rendererHelper.mainThread.bounds.max;for(const timeWindow of timeWindows){const mu=mutatorUtilization(start,end,timeWindow,pauses);histogramMap.get(timeWindow).addSample(mu.min);}}}
-return{addMutatorUtilization,findParent,forcedGCEventName,filterEvents,filterAndOrderEvents,groupAndProcessEvents,isForcedGarbageCollectionEvent,isFullMarkCompactorEvent,isGarbageCollectionEvent,isIdleTask,isIncrementalMarkingEvent,isLatencyMarkCompactorEvent,isLowMemoryEvent,isMarkCompactorSummaryEvent,isMarkCompactorMarkingSummaryEvent,isMemoryMarkCompactorEvent,isNotForcedMarkCompactorEvent,isNotForcedTopGarbageCollectionEvent,isNotForcedSubGarbageCollectionEvent,isScavengerEvent,isScavengerStackScanningEvent,isSubGarbageCollectionEvent,isTopGarbageCollectionEvent,isTopV8ExecuteEvent,isV8Event,isV8ExecuteEvent,isV8RCSEvent,isCompileRCSCategory,isCompileOptimizeRCSCategory,isCompileUnoptimizeRCSCategory,isCompileParseRCSCategory,mutatorUtilization,rangeForMemoryDumps,subGarbageCollectionEventName,topGarbageCollectionEventName,topGarbageCollectionEventNames,unionOfIntervals,};});'use strict';tr.exportTo('tr.metrics.blink',function(){const BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP={'BlinkGC.AtomicPauseMarkEpilogue':'blink-gc-atomic-pause-mark-epilogue','BlinkGC.AtomicPauseMarkPrologue':'blink-gc-atomic-pause-mark-prologue','BlinkGC.AtomicPauseMarkRoots':'blink-gc-atomic-pause-mark-roots','BlinkGC.IncrementalMarkingStartMarking':'blink-gc-incremental-start','BlinkGC.IncrementalMarkingStep':'blink-gc-incremental-step','BlinkGC.UnifiedMarkingStep':'blink-gc-unified-marking-by-v8','BlinkGC.CompleteSweep':'blink-gc-complete-sweep','BlinkGC.LazySweepInIdle':'blink-gc-sweep-task-foreground','BlinkGC.LazySweepOnAllocation':'blink-gc-sweep-allocation','BlinkGC.AtomicPauseSweepAndCompact':'blink-gc-atomic-pause-sweep-and-compact'};const BLINK_TOP_GC_ROOTS_MARKING_EVENTS=['BlinkGC.VisitRoots'];const BLINK_GC_ATOMIC_PAUSE_TRANSITIVE_CLOSURE_EVENTS=['BlinkGC.AtomicPauseMarkTransitiveClosure'];const BLINK_GC_FOREGROUND_MARKING_TRANSITIVE_CLOSURE_EVENTS=['BlinkGC.AtomicPauseMarkTransitiveClosure','BlinkGC.IncrementalMarkingStep','BlinkGC.UnifiedMarkingStep'];const BLINK_TOP_GC_FOREGROUND_MARKING_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.IncrementalMarkingStartMarking',].concat(BLINK_GC_FOREGROUND_MARKING_TRANSITIVE_CLOSURE_EVENTS);const BLINK_GC_FORCED_FOREGROUND_MARKING_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.IncrementalMarkingStartMarking','BlinkGC.MarkBailOutObjects','BlinkGC.MarkFlushV8References','BlinkGC.MarkFlushEphemeronPairs',];const BLINK_TOP_GC_BACKGROUND_MARKING_EVENTS=['BlinkGC.ConcurrentMarkingStep'];const BLINK_TOP_GC_FOREGROUND_SWEEPING_EVENTS=['BlinkGC.CompleteSweep','BlinkGC.LazySweepInIdle','BlinkGC.LazySweepOnAllocation'];const BLINK_TOP_GC_BACKGROUND_SWEEPING_EVENTS=['BlinkGC.ConcurrentSweepingStep'];const BLINK_TOP_GC_EVENTS=Object.keys(BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP).concat(BLINK_GC_ATOMIC_PAUSE_TRANSITIVE_CLOSURE_EVENTS);const ATOMIC_PAUSE_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.AtomicPauseMarkTransitiveClosure','BlinkGC.AtomicPauseSweepAndCompact'];function blinkGarbageCollectionEventName(event){return BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP[event.title];}
+return{addMutatorUtilization,findParent,forcedGCEventName,filterEvents,filterAndOrderEvents,groupAndProcessEvents,isForcedGarbageCollectionEvent,isFullMarkCompactorEvent,isGarbageCollectionEvent,isIdleTask,isIncrementalMarkingEvent,isLatencyMarkCompactorEvent,isLowMemoryEvent,isMarkCompactorSummaryEvent,isMarkCompactorMarkingSummaryEvent,isMemoryMarkCompactorEvent,isNotForcedMarkCompactorEvent,isNotForcedTopGarbageCollectionEvent,isNotForcedSubGarbageCollectionEvent,isScavengerEvent,isScavengerStackScanningEvent,isSubGarbageCollectionEvent,isTopGarbageCollectionEvent,isTopV8ExecuteEvent,isV8Event,isV8ExecuteEvent,isV8RCSEvent,isCompileRCSCategory,isCompileOptimizeRCSCategory,isCompileUnoptimizeRCSCategory,isCompileParseRCSCategory,mutatorUtilization,rangeForMemoryDumps,subGarbageCollectionEventName,topGarbageCollectionEventName,topGarbageCollectionEventNames,unionOfIntervals,};});'use strict';tr.exportTo('tr.metrics.blink',function(){const BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP={'BlinkGC.AtomicPauseMarkEpilogue':'blink-gc-atomic-pause-mark-epilogue','BlinkGC.AtomicPauseMarkPrologue':'blink-gc-atomic-pause-mark-prologue','BlinkGC.AtomicPauseMarkRoots':'blink-gc-atomic-pause-mark-roots','BlinkGC.IncrementalMarkingStartMarking':'blink-gc-incremental-start','BlinkGC.IncrementalMarkingStep':'blink-gc-incremental-step','BlinkGC.UnifiedMarkingStep':'blink-gc-unified-marking-by-v8','BlinkGC.CompleteSweep':'blink-gc-complete-sweep','BlinkGC.LazySweepInIdle':'blink-gc-sweep-task-foreground','BlinkGC.LazySweepOnAllocation':'blink-gc-sweep-allocation','BlinkGC.AtomicPauseSweepAndCompact':'blink-gc-atomic-pause-sweep-and-compact'};const BLINK_NON_AGGREGATED_GC_EVENTS_NEW_NAMES_MAP={'BlinkGC.AtomicPauseMarkEpilogue':'blink:gc:main_thread:cycle:full:atomic:mark:epilogue','BlinkGC.AtomicPauseMarkPrologue':'blink:gc:main_thread:cycle:full:atomic:mark:prologue','BlinkGC.AtomicPauseMarkRoots':'blink:gc:main_thread:cycle:full:atomic:mark:roots','BlinkGC.IncrementalMarkingStartMarking':'blink:gc:main_thread:cycle:full:incremental:mark:start','BlinkGC.IncrementalMarkingStep':'blink:gc:main_thread:cycle:full:incremental:mark:step','BlinkGC.UnifiedMarkingStep':'unified:gc:main_thread:cycle:full:mark:step','BlinkGC.CompleteSweep':'blink:gc:main_thread:cycle:full:sweep:complete','BlinkGC.LazySweepInIdle':'blink:gc:main_thread:cycle:full:sweep:idle','BlinkGC.LazySweepOnAllocation':'blink:gc:main_thread:cycle:full:sweep:on_allocation','BlinkGC.AtomicPauseSweepAndCompact':'blink:gc:main_thread:cycle:full:atomic:sweep:compact'};const BLINK_TOP_GC_ROOTS_MARKING_EVENTS=['BlinkGC.VisitRoots'];const BLINK_GC_ATOMIC_PAUSE_TRANSITIVE_CLOSURE_EVENTS=['BlinkGC.AtomicPauseMarkTransitiveClosure'];const BLINK_GC_FOREGROUND_MARKING_TRANSITIVE_CLOSURE_EVENTS=['BlinkGC.AtomicPauseMarkTransitiveClosure','BlinkGC.IncrementalMarkingStep','BlinkGC.UnifiedMarkingStep'];const BLINK_TOP_GC_FOREGROUND_MARKING_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.IncrementalMarkingStartMarking',].concat(BLINK_GC_FOREGROUND_MARKING_TRANSITIVE_CLOSURE_EVENTS);const BLINK_GC_FORCED_FOREGROUND_MARKING_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.IncrementalMarkingStartMarking','BlinkGC.MarkBailOutObjects','BlinkGC.MarkFlushV8References','BlinkGC.MarkFlushEphemeronPairs',];const BLINK_TOP_GC_BACKGROUND_MARKING_EVENTS=['BlinkGC.ConcurrentMarkingStep'];const BLINK_TOP_GC_FOREGROUND_SWEEPING_EVENTS=['BlinkGC.CompleteSweep','BlinkGC.LazySweepInIdle','BlinkGC.LazySweepOnAllocation'];const BLINK_TOP_GC_BACKGROUND_SWEEPING_EVENTS=['BlinkGC.ConcurrentSweepingStep'];const BLINK_TOP_GC_EVENTS=Object.keys(BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP).concat(BLINK_GC_ATOMIC_PAUSE_TRANSITIVE_CLOSURE_EVENTS);const ATOMIC_PAUSE_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.AtomicPauseMarkTransitiveClosure','BlinkGC.AtomicPauseSweepAndCompact'];function blinkGarbageCollectionEventName(event){return BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP[event.title];}
function blinkGarbageCollectionEventNames(){return Object.values(BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP);}
+function blinkGarbageCollectionEventNewName(event){return BLINK_NON_AGGREGATED_GC_EVENTS_NEW_NAMES_MAP[event.title];}
+function blinkGarbageCollectionEventNewNames(){return Object.values(BLINK_NON_AGGREGATED_GC_EVENTS_NEW_NAMES_MAP);}
function isNonForcedEvent(event){return(!event.args||!event.args.forced)&&!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);}
function isNonForcedBlinkGarbageCollectionEvent(event){return BLINK_TOP_GC_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
function isNonForcedNonAggregatedBlinkGarbageCollectionEvent(event){return event.title in BLINK_NON_AGGREGATED_GC_EVENTS_NAMES_MAP&&isNonForcedEvent(event);}
@@ -8181,32 +8190,27 @@ function isNonForcedBlinkGarbageCollectionForegroundSweepingEvent(event){return
function isNonForcedBlinkGarbageCollectionBackgroundSweepingEvent(event){return BLINK_TOP_GC_BACKGROUND_SWEEPING_EVENTS.includes(event.title)&&isNonForcedEvent(event);}
function isNonNestedNonForcedBlinkGarbageCollectionEvent(event){return isNonForcedBlinkGarbageCollectionEvent(event)&&!tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isGarbageCollectionEvent);}
function blinkGcMetric(histograms,model){addDurationOfTopEvents(histograms,model);addDurationOfAtomicPause(histograms,model);addDurationOfAtomicPauseTransitiveClosure(histograms,model);addTotalDurationOfTopEvents(histograms,model);addTotalDurationOfBlinkAndV8TopEvents(histograms,model);addTotalDurationOfRootsMarking(histograms,model);addTotalDurationOfMarkingTransitiveClosure(histograms,model);addTotalDurationOfForegroundMarking(histograms,model);addTotalDurationOfForcedForegroundMarking(histograms,model);addTotalDurationOfBackgroundMarking(histograms,model);addTotalDurationOfForegroundSweeping(histograms,model);addTotalDurationOfBackgroundSweeping(histograms,model);}
-tr.metrics.MetricRegistry.register(blinkGcMetric);const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
-function createNumericForTotalEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:false,count:true,max:false,min:false,std:false,sum:true,percentile:[0.90]});return n;}
-function createNumericForUnifiedEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:false,count:true,max:true,min:false,std:false,sum:true,percentile:[0.90]});return n;}
-function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedNonAggregatedBlinkGarbageCollectionEvent,blinkGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForTopEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
-histograms.addHistogram(cpuDuration);},blinkGarbageCollectionEventNames());}
-function addDurationOfAtomicPause(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionAtomicPauseEvent,event=>event.args.epoch,function(group,events){const cpuDuration=createNumericForTopEventTime('blink-gc-atomic-pause');cpuDuration.addSample(events.reduce((acc,current)=>acc+current.cpuDuration,0));histograms.addHistogram(cpuDuration);});}
-function addDurationOfAtomicPauseTransitiveClosure(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionAtomicPauseTransitiveColsureEvent,event=>event.args.epoch,function(group,events){const cpuDuration=createNumericForTopEventTime('blink-gc-atomic-pause-mark-transitive-closure');cpuDuration.addSample(events.reduce((acc,current)=>acc+current.cpuDuration,0));histograms.addHistogram(cpuDuration);});}
-function addTotalDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionEvent,event=>'blink-gc-total',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
-histograms.addHistogram(cpuDuration);},['blink-gc-total']);}
-function addTotalDurationOfRootsMarking(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionRootsMarkingEvent,event=>'blink-gc-mark-roots',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
-histograms.addHistogram(cpuDuration);},['blink-gc-mark-roots']);}
-function addTotalDurationOfMarkingTransitiveClosure(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionMarkingTransitiveColsureEvent,event=>'blink-gc-mark-transitive-closure',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
-histograms.addHistogram(cpuDuration);},['blink-gc-mark-transitive-closure']);}
-function addTotalDurationOfForegroundMarking(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionForegroundMarkingEvent,event=>'blink-gc-mark-foreground',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
-histograms.addHistogram(cpuDuration);},['blink-gc-mark-foreground']);}
-function addTotalDurationOfForcedForegroundMarking(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionForcedForegroundMarkEvent,event=>'blink-gc-mark-foreground-forced',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
-histograms.addHistogram(cpuDuration);},['blink-gc-mark-foreground-forced']);}
-function addTotalDurationOfBackgroundMarking(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionBackgroundMarkingEvent,event=>'blink-gc-mark-background',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
-histograms.addHistogram(cpuDuration);},['blink-gc-mark-background']);}
-function addTotalDurationOfForegroundSweeping(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionForegroundSweepingEvent,event=>'blink-gc-sweep-foreground',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
-histograms.addHistogram(cpuDuration);},['blink-gc-sweep-foreground']);}
-function addTotalDurationOfBackgroundSweeping(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedBlinkGarbageCollectionBackgroundSweepingEvent,event=>'blink-gc-sweep-background',function(name,events){const cpuDuration=createNumericForTotalEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
-histograms.addHistogram(cpuDuration);},['blink-gc-sweep-background']);}
+function getEventEpochUniqueId(event){return event.parentContainer.parent.stableId+':'+event.args.epoch;}
+tr.metrics.MetricRegistry.register(blinkGcMetric);const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForEventTime(name){const n=new tr.v.Histogram(name,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:true,std:true,sum:true,percentile:[0.90]});return n;}
+function addDurationOfTopEvents(histograms,model){const nameToNumeric={};const nameToEpochNumeric={};for(const name of blinkGarbageCollectionEventNames()){nameToNumeric[name]=createNumericForEventTime(name);}
+for(const name of blinkGarbageCollectionEventNewNames()){nameToEpochNumeric[name]=createNumericForEventTime(name);}
+tr.metrics.v8.utils.groupAndProcessEvents(model,isNonForcedNonAggregatedBlinkGarbageCollectionEvent,getEventEpochUniqueId,function(epoch,events){const namesToPerEpochDurations={};for(const event of events){nameToNumeric[blinkGarbageCollectionEventName(event)].addSample(event.cpuDuration);const name=blinkGarbageCollectionEventNewName(event);namesToPerEpochDurations[name]=(namesToPerEpochDurations[name]||0)+event.cpuDuration;}
+for(const name in namesToPerEpochDurations){nameToEpochNumeric[name].addSample(namesToPerEpochDurations[name]);}});for(const name of blinkGarbageCollectionEventNames()){histograms.addHistogram(nameToNumeric[name]);}
+for(const name of blinkGarbageCollectionEventNewNames()){histograms.addHistogram(nameToEpochNumeric[name]);}}
+function addIndividualDurationsOfEvents(histograms,model,name,filter){const cpuDuration=createNumericForEventTime(name);tr.metrics.v8.utils.groupAndProcessEvents(model,filter,event=>name,function(group,events){for(const event of events){cpuDuration.addSample(event.cpuDuration);}},[name]);histograms.addHistogram(cpuDuration);}
+function addPerEpochDurationsOfEvents(histograms,model,name,filter){const cpuDuration=createNumericForEventTime(name);tr.metrics.v8.utils.groupAndProcessEvents(model,filter,getEventEpochUniqueId,function(epoch,events){cpuDuration.addSample(events.reduce((acc,current)=>acc+current.cpuDuration,0));});histograms.addHistogram(cpuDuration);}
+function addDurationOfAtomicPause(histograms,model){addIndividualDurationsOfEvents(histograms,model,'blink-gc-atomic-pause',isNonForcedBlinkGarbageCollectionAtomicPauseEvent);addPerEpochDurationsOfEvents(histograms,model,'blink:gc:main_thread:cycle:full:atomic',isNonForcedBlinkGarbageCollectionAtomicPauseEvent);}
+function addDurationOfAtomicPauseTransitiveClosure(histograms,model){addIndividualDurationsOfEvents(histograms,model,'blink-gc-atomic-pause-mark-transitive-closure',isNonForcedBlinkGarbageCollectionAtomicPauseTransitiveColsureEvent);addPerEpochDurationsOfEvents(histograms,model,'blink:gc:main_thread:cycle:full:atomic:mark:transitive_closure',isNonForcedBlinkGarbageCollectionAtomicPauseTransitiveColsureEvent);}
+function addTotalDurationOfTopEvents(histograms,model){addIndividualDurationsOfEvents(histograms,model,'blink-gc-total',isNonForcedBlinkGarbageCollectionEvent);addPerEpochDurationsOfEvents(histograms,model,'blink:gc:main_thread:cycle:full',isNonForcedBlinkGarbageCollectionEvent);}
+function addTotalDurationOfRootsMarking(histograms,model){addIndividualDurationsOfEvents(histograms,model,'blink-gc-mark-roots',isNonForcedBlinkGarbageCollectionRootsMarkingEvent);addPerEpochDurationsOfEvents(histograms,model,'blink:gc:main_thread:cycle:full:mark:roots',isNonForcedBlinkGarbageCollectionRootsMarkingEvent);}
+function addTotalDurationOfMarkingTransitiveClosure(histograms,model){addIndividualDurationsOfEvents(histograms,model,'blink-gc-mark-transitive-closure',isNonForcedBlinkGarbageCollectionMarkingTransitiveColsureEvent);addPerEpochDurationsOfEvents(histograms,model,'blink:gc:main_thread:cycle:full:mark:transitive_closure',isNonForcedBlinkGarbageCollectionMarkingTransitiveColsureEvent);}
+function addTotalDurationOfForegroundMarking(histograms,model){addIndividualDurationsOfEvents(histograms,model,'blink-gc-mark-foreground',isNonForcedBlinkGarbageCollectionForegroundMarkingEvent);addPerEpochDurationsOfEvents(histograms,model,'blink:gc:main_thread:cycle:full:mark',isNonForcedBlinkGarbageCollectionForegroundMarkingEvent);}
+function addTotalDurationOfForcedForegroundMarking(histograms,model){addIndividualDurationsOfEvents(histograms,model,'blink-gc-mark-foreground-forced',isNonForcedBlinkGarbageCollectionForcedForegroundMarkEvent);addPerEpochDurationsOfEvents(histograms,model,'blink:gc:main_thread:cycle:full:mark:forced',isNonForcedBlinkGarbageCollectionForcedForegroundMarkEvent);}
+function addTotalDurationOfBackgroundMarking(histograms,model){addIndividualDurationsOfEvents(histograms,model,'blink-gc-mark-background',isNonForcedBlinkGarbageCollectionBackgroundMarkingEvent);addPerEpochDurationsOfEvents(histograms,model,'blink:gc:concurrent_thread:cycle:full:mark',isNonForcedBlinkGarbageCollectionBackgroundMarkingEvent);}
+function addTotalDurationOfForegroundSweeping(histograms,model){addIndividualDurationsOfEvents(histograms,model,'blink-gc-sweep-foreground',isNonForcedBlinkGarbageCollectionForegroundSweepingEvent);addPerEpochDurationsOfEvents(histograms,model,'blink:gc:main_thread:cycle:full:sweep',isNonForcedBlinkGarbageCollectionForegroundSweepingEvent);}
+function addTotalDurationOfBackgroundSweeping(histograms,model){addIndividualDurationsOfEvents(histograms,model,'blink-gc-sweep-background',isNonForcedBlinkGarbageCollectionBackgroundSweepingEvent);addPerEpochDurationsOfEvents(histograms,model,'blink:gc:concurrent_thread:cycle:full:sweep',isNonForcedBlinkGarbageCollectionBackgroundSweepingEvent);}
function isV8OrBlinkTopLevelGarbageCollectionEvent(event){return tr.metrics.v8.utils.isNotForcedTopGarbageCollectionEvent(event)||isNonNestedNonForcedBlinkGarbageCollectionEvent(event);}
-function addTotalDurationOfBlinkAndV8TopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isV8OrBlinkTopLevelGarbageCollectionEvent,event=>'unified-gc-total',function(name,events){const cpuDuration=createNumericForUnifiedEventTime(name);for(const event of events){cpuDuration.addSample(event.cpuDuration);}
-histograms.addHistogram(cpuDuration);},['unified-gc-total']);}
+function addTotalDurationOfBlinkAndV8TopEvents(histograms,model){addIndividualDurationsOfEvents(histograms,model,'unified-gc-total',isV8OrBlinkTopLevelGarbageCollectionEvent);}
return{blinkGcMetric,};});'use strict';tr.exportTo('tr.metrics.blink',function(){function leakDetectionMetric(histograms,model){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper===undefined){throw new Error('Chrome is not present.');}
const rendererHelpers=modelHelper.rendererHelpers;if(Object.keys(rendererHelpers).length===0){throw new Error('Renderer process is not present.');}
const pids=Object.keys(rendererHelpers);const chromeDumps=tr.metrics.sh.splitGlobalDumpsByBrowserName(model,undefined).get('chrome');const sumCounter=new Map();for(const pid of pids){for(const[key,count]of countLeakedBlinkObjects(chromeDumps,pid)){sumCounter.set(key,(sumCounter.get(key)||0)+count);}}
@@ -8233,10 +8237,21 @@ return processNumerics;}
function cpuProcessMetric(histograms,model){const snapshots=getCpuSnapshotsFromModel(model);const processNumerics=buildNumericsFromSnapshots(snapshots);for(const[processName,processData]of processNumerics){const numeric=processData.numeric;const missingSnapshotCount=snapshots.length-numeric.numValues;for(let i=0;i<missingSnapshotCount;i++){numeric.addSample(0);}
numeric.diagnostics.set('paths',new
tr.v.d.GenericSet([...processData.paths]));histograms.addHistogram(numeric);}}
-tr.metrics.MetricRegistry.register(cpuProcessMetric);return{cpuProcessMetric,};});'use strict';tr.exportTo('tr.metrics',function(){function mediaMetric(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper===undefined)return;for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const mainThread=rendererHelper.mainThread;if(mainThread===undefined)continue;const videoThreads=rendererHelper.process.findAllThreadsMatching(thread=>(thread.name?thread.name.startsWith('ThreadPoolSingleThreadSharedForegroundBlocking'):false));const compositorThread=rendererHelper.compositorThread;if(compositorThread!==undefined){videoThreads.push(compositorThread);}
+tr.metrics.MetricRegistry.register(cpuProcessMetric);return{cpuProcessMetric,};});'use strict';tr.exportTo('tr.metrics',function(){function customMetric(histograms,model,opt_options){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper){return;}
+const TITLE_PREFIX='custom_metric:';const traces=new Map();const benchmarkValues=new Map();for(const helper of chromeHelper.browserHelpers){if(!helper.mainThread)continue;for(const slice of helper.mainThread.sliceGroup.slices.concat(helper.mainThread.asyncSliceGroup.slices)){if(!slice.error&&slice.title.startsWith(TITLE_PREFIX)){if(!traces.has(slice.title)){traces.set(slice.title,[]);}
+traces.get(slice.title).push(slice.duration);}}}
+const BENCHMARK_BEGIN='benchmark_begin';const BENCHMARK_END='benchmark_end';const BENCHMARK_VALUE='benchmark_value';const marks=new Map();for(const helper of Object.values(chromeHelper.rendererHelpers)){for(const event of helper.mainThread.sliceGroup.childEvents()){const navId=getNavigationId(event);if(!navId||!event.category.includes('blink.user_timing'))continue;const{title}=event;const index=title.lastIndexOf(':');if(index===-1){continue;}
+const name=title.substring(0,index);const lastPart=title.substring(index+1);if(lastPart===BENCHMARK_BEGIN){marks.set(name,event);}else if(lastPart===BENCHMARK_END){if(!marks.has(name)){continue;}
+const range=tr.b.math.Range.fromExplicitRange(marks.get(name).start,event.start);if(!traces.has(name)){traces.set(name,[]);}
+traces.get(name).push(range.duration);marks.delete(name);}else if(lastPart===BENCHMARK_VALUE){const index2=name.lastIndexOf(':');if(index2===-1){continue;}
+const key=name.substring(0,index2);const value=Number(name.substring(index2+1));if(key&&!isNaN(value)){if(!benchmarkValues.has(key)){benchmarkValues.set(key,[]);}
+benchmarkValues.get(key).push(value);}}}}
+traces.forEach((value,key)=>{histograms.createHistogram(key,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,value);});benchmarkValues.forEach((value,key)=>{histograms.createHistogram(key,tr.b.Unit.byName.unitlessNumber_smallerIsBetter,value);});}
+function getNavigationId(event){return event.args.data&&event.args.data.navigationId;}
+tr.metrics.MetricRegistry.register(customMetric,{supportsRangeOfInterest:false,});return{customMetric,};});'use strict';tr.exportTo('tr.metrics',function(){function mediaMetric(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper===undefined)return;for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const mainThread=rendererHelper.mainThread;if(mainThread===undefined)continue;const videoThreads=rendererHelper.process.findAllThreadsMatching(thread=>(thread.name?thread.name.startsWith('ThreadPoolSingleThreadSharedForegroundBlocking'):false));const compositorThread=rendererHelper.compositorThread;if(compositorThread!==undefined){videoThreads.push(compositorThread);}
const audioThreads=rendererHelper.process.findAllThreadsNamed('AudioOutputDevice');if(audioThreads.length===0&&videoThreads.length===0)continue;const processData=new PerProcessData();processData.recordPlayStarts(mainThread);if(!processData.hasPlaybacks)continue;if(videoThreads.length!==0){processData.calculateTimeToVideoPlays(videoThreads);processData.calculateDroppedFrameCounts(videoThreads);}
if(audioThreads.length!==0){processData.calculateTimeToAudioPlays(audioThreads);}
-processData.calculateSeekTimes(mainThread);processData.calculateBufferingTimes(mainThread);processData.addMetricToHistograms(histograms);}}
+processData.calculateSeekTimes(mainThread);processData.calculateBufferingTimes(mainThread);const allThreads=rendererHelper.process.findAllThreadsMatching(function(){return true;});processData.calculateVideoPlaybackQuality(allThreads);processData.addMetricToHistograms(histograms);}}
class PerProcessData{constructor(){this.playbackIdToDataMap_=new Map();}
recordPlayStarts(mainThread){for(const event of mainThread.sliceGroup.getDescendantEvents()){if(event.title==='WebMediaPlayerImpl::DoLoad'){const id=event.args.id;if(this.playbackIdToDataMap_.has(id)){throw new Error('Unexpected multiple initialization of a media playback');}
this.playbackIdToDataMap_.set(id,new PerPlaybackData(event.start));}}}
@@ -8246,15 +8261,18 @@ calculateTimeToAudioPlays(audioThreads){for(const audioThread of audioThreads){f
calculateSeekTimes(mainThread){for(const event of mainThread.sliceGroup.getDescendantEvents()){if(event.title==='WebMediaPlayerImpl::DoSeek'){this.getPerPlaybackObject_(event.args.id).processDoSeek(event.args.target,event.start);}else if(event.title==='WebMediaPlayerImpl::OnPipelineSeeked'){this.getPerPlaybackObject_(event.args.id).processOnPipelineSeeked(event.args.target,event.start);}else if(event.title==='WebMediaPlayerImpl::BufferingHaveEnough'){this.getPerPlaybackObject_(event.args.id).processBufferingHaveEnough(event.start);}}}
calculateBufferingTimes(mainThread){for(const event of mainThread.sliceGroup.getDescendantEvents()){if(event.title==='WebMediaPlayerImpl::OnEnded'){this.getPerPlaybackObject_(event.args.id).processOnEnded(event.start,event.args.duration);}}}
calculateDroppedFrameCounts(videoThreads){for(const thread of videoThreads){for(const event of thread.sliceGroup.getDescendantEvents()){if(event.title==='VideoFramesDropped'){this.getPerPlaybackObject_(event.args.id).processVideoFramesDropped(event.args.count);}}}}
+calculateVideoPlaybackQuality(threads){for(const thread of threads){for(const event of thread.sliceGroup.getDescendantEvents()){if(event.title==='VideoPlaybackRoughness'){this.getPerPlaybackObject_(event.args.id).processVideoRoughness(event.args.roughness);}else if(event.title==='VideoPlaybackFreezing'){this.getPerPlaybackObject_(event.args.id).processVideoFreezing(event.args.freezing);}}}}
addMetricToHistograms(histograms){for(const[id,playbackData]of this.playbackIdToDataMap_){playbackData.addMetricToHistograms(histograms);}}
getPerPlaybackObject_(playbackId){let perPlaybackObject=this.playbackIdToDataMap_.get(playbackId);if(perPlaybackObject===undefined){perPlaybackObject=new PerPlaybackData(undefined);this.playbackIdToDataMap_.set(playbackId,perPlaybackObject);}
return perPlaybackObject;}}
-class PerPlaybackData{constructor(playStartTime){this.playStart_=playStartTime;this.timeToVideoPlay_=undefined;this.timeToAudioPlay_=undefined;this.bufferingTime_=undefined;this.droppedFrameCount_=0;this.seekError_=false;this.seekTimes_=new Map();this.currentSeek_=undefined;}
+class PerPlaybackData{constructor(playStartTime){this.playStart_=playStartTime;this.timeToVideoPlay_=undefined;this.timeToAudioPlay_=undefined;this.bufferingTime_=undefined;this.droppedFrameCount_=0;this.seekError_=false;this.seekTimes_=new Map();this.currentSeek_=undefined;this.roughness_=undefined;this.freezing_=undefined;}
get timeToVideoPlay(){return this.timeToVideoPlay_;}
get timeToAudioPlay(){return this.timeToAudioPlay_;}
get bufferingTime(){return this.bufferingTime_;}
get droppedFrameCount(){return(this.timeToVideoPlay_!==undefined)?this.droppedFrameCount_:undefined;}
get seekTimes(){if(this.seekError_||this.currentSeek_!==undefined)return new Map();return this.seekTimes_;}
+get roughness(){return this.roughness_;}
+get freezing(){return this.freezing_;}
processVideoRenderTime(videoRenderTime){if(this.playStart_!==undefined&&this.timeToVideoPlay_===undefined){this.timeToVideoPlay_=videoRenderTime-this.playStart_;}}
processAudioRenderTime(audioRenderTime){if(this.playStart_!==undefined&&this.timeToAudioPlay_===undefined){this.timeToAudioPlay_=audioRenderTime-this.playStart_;}}
processVideoFramesDropped(count){this.droppedFrameCount_+=count;}
@@ -8268,11 +8286,20 @@ processBufferingHaveEnough(time){if(this.seekError_)return;const currentSeek=thi
if(currentSeek.pipelineSeekTime===undefined){return;}
currentSeek.seekTime=time-currentSeek.startTime;this.currentSeek_=undefined;}
processOnEnded(playEndTime,duration){if(this.playStart_===undefined)return;if(this.seekTimes_.size!==0||this.seekError_)return;if(this.bufferingTime_!==undefined)return;duration=tr.b.convertUnit(duration,tr.b.UnitPrefixScale.METRIC.NONE,tr.b.UnitPrefixScale.METRIC.MILLI);const playTime=playEndTime-this.playStart_;if(this.timeToVideoPlay_!==undefined){this.bufferingTime_=playTime-duration-this.timeToVideoPlay_;}else if(this.timeToAudioPlay!==undefined){this.bufferingTime_=playTime-duration-this.timeToAudioPlay_;}}
+processVideoRoughness(roughness){if(this.roughness_===undefined||this.roughness_>roughness){this.roughness_=roughness;}}
+processVideoFreezing(freezing){if(this.freezing_===undefined||this.freezing_>freezing){this.freezing_=freezing;}}
addMetricToHistograms(histograms){this.addSample_(histograms,'time_to_video_play',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,this.timeToVideoPlay);this.addSample_(histograms,'time_to_audio_play',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,this.timeToAudioPlay);this.addSample_(histograms,'dropped_frame_count',tr.b.Unit.byName.count_smallerIsBetter,this.droppedFrameCount);for(const[key,value]of this.seekTimes.entries()){const keyString=key.toString().replace('.','_');this.addSample_(histograms,'pipeline_seek_time_'+keyString,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,value.pipelineSeekTime);this.addSample_(histograms,'seek_time_'+keyString,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,value.seekTime);}
-this.addSample_(histograms,'buffering_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,this.bufferingTime);}
+this.addSample_(histograms,'buffering_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,this.bufferingTime);this.addSample_(histograms,'roughness',tr.b.Unit.byName.count_smallerIsBetter,this.roughness);this.addSample_(histograms,'freezing',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,this.freezing);}
addSample_(histograms,name,unit,sample){if(sample===undefined)return;const histogram=histograms.getHistogramNamed(name);if(histogram===undefined){histograms.createHistogram(name,unit,sample);}else{histogram.addSample(sample);}}}
tr.metrics.MetricRegistry.register(mediaMetric);return{mediaMetric,};});'use strict';tr.exportTo('tr.metrics',function(){function memoryAblationMetric(histograms,model){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper.gpuHelper)return;const gpuProcess=modelHelper.gpuHelper.process;const events=[...gpuProcess.findTopmostSlicesNamed('Memory.GPU.PeakMemoryUsage.AblationTimes')];const allocHistogram=histograms.createHistogram('Ablation Alloc',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{binBoundaries:tr.v.HistogramBinBoundaries.createLinear(0,10000,20),description:'The amount of time spent allocating the ablation '+'memory',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});const deallocHistogram=histograms.createHistogram('Ablation Dealloc',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],{binBoundaries:tr.v.HistogramBinBoundaries.createLinear(0,10000,20),description:'The amount of time spent deallocating the ablation '+'memory',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});for(let i=0;i<events.length;i++){allocHistogram.addSample(events[i].args.alloc);deallocHistogram.addSample(events[i].args.dealloc);}}
-tr.metrics.MetricRegistry.register(memoryAblationMetric,{requiredCategories:['gpu.memory'],});return{memoryAblationMetric,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const UNKNOWN_THREAD_NAME='Unknown';const CATEGORY_THREAD_MAP=new Map();CATEGORY_THREAD_MAP.set('total_all',[/.*/]);CATEGORY_THREAD_MAP.set('browser',[/^Browser Compositor$/,/^CrBrowserMain$/]);CATEGORY_THREAD_MAP.set('display_compositor',[/^VizCompositorThread$/]);CATEGORY_THREAD_MAP.set('GPU',[/^Chrome_InProcGpuThread$/,/^CrGpuMain$/]);CATEGORY_THREAD_MAP.set('IO',[/IOThread/]);CATEGORY_THREAD_MAP.set('raster',[/CompositorTileWorker/]);CATEGORY_THREAD_MAP.set('renderer_compositor',[/^Compositor$/]);CATEGORY_THREAD_MAP.set('renderer_main',[/^CrRendererMain$/]);CATEGORY_THREAD_MAP.set('total_rendering',[/^Browser Compositor$/,/^Chrome_InProcGpuThread$/,/^Compositor$/,/CompositorTileWorker/,/^CrBrowserMain$/,/^CrGpuMain$/,/^CrRendererMain$/,/IOThread/,/^VizCompositorThread$/]);const ALL_CATEGORIES=[...CATEGORY_THREAD_MAP.keys(),'other'];function addValueToMap_(map,key,value){const oldValue=map.get(key)||0;map.set(key,oldValue+value);}
+tr.metrics.MetricRegistry.register(memoryAblationMetric,{requiredCategories:['gpu.memory'],});return{memoryAblationMetric,};});'use strict';tr.exportTo('tr.metrics.pa',function(){function pcscanMetric(histograms,model){function createNumericForProcess(name,processName,desc){function createNumericForEventTime(name,desc){const n=new tr.v.Histogram(name,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);n.description=desc;n.customizeSummaryOptions({avg:true,count:true,max:true,min:true,std:true,sum:true});return n;}
+const scheme=['pa','pcscan',processName];if(name)scheme.push(name);return createNumericForEventTime(scheme.join(':'),desc);}
+function createHistsForProcess(processName){return{scan:createNumericForProcess('scan',processName,'Time for scanning heap for quarantine pointers'),sweep:createNumericForProcess('sweep',processName,'Time for sweeping quarantine'),clear:createNumericForProcess('clear',processName,'Time for clearing quarantine entries'),total:createNumericForProcess('',processName,'Total time for PCScan execution')};}
+function addSample(hists,slice){if(!(slice instanceof tr.model.ThreadSlice))return;if(slice.category!=='partition_alloc')return;if(slice.title==='PCScan.Scan'){hists.scan.addSample(slice.duration);}else if(slice.title==='PCScan.Sweep'){hists.sweep.addSample(slice.duration);}else if(slice.title==='PCScan.Clear'){hists.clear.addSample(slice.duration);}else if(slice.title==='PCScan'){hists.total.addSample(slice.duration);}}
+function addHistsForProcess(processHists,processHelpers){for(const helper of Object.values(processHelpers)){const processName=tr.e.chrome.chrome_processes.canonicalizeProcessName(helper.process.name);if(!processHists.has(processName)){processHists.set(processName,createHistsForProcess(processName));}
+for(const slice of helper.process.getDescendantEvents()){addSample(processHists.get(processName),slice);}}}
+const helper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const processHists=new Map();addHistsForProcess(processHists,helper.browserHelpers);addHistsForProcess(processHists,helper.rendererHelpers);for(const hists of processHists.values()){for(const hist of Object.values(hists)){histograms.addHistogram(hist);}}}
+tr.metrics.MetricRegistry.register(pcscanMetric);return{pcscanMetric,};});'use strict';tr.exportTo('tr.metrics.rendering',function(){const UNKNOWN_THREAD_NAME='Unknown';const CATEGORY_THREAD_MAP=new Map();CATEGORY_THREAD_MAP.set('total_all',[/.*/]);CATEGORY_THREAD_MAP.set('browser',[/^Browser Compositor$/,/^CrBrowserMain$/]);CATEGORY_THREAD_MAP.set('display_compositor',[/^VizCompositorThread$/]);CATEGORY_THREAD_MAP.set('GPU',[/^Chrome_InProcGpuThread$/,/^CrGpuMain$/]);CATEGORY_THREAD_MAP.set('IO',[/IOThread/]);CATEGORY_THREAD_MAP.set('raster',[/CompositorTileWorker/]);CATEGORY_THREAD_MAP.set('renderer_compositor',[/^Compositor$/]);CATEGORY_THREAD_MAP.set('renderer_main',[/^CrRendererMain$/]);CATEGORY_THREAD_MAP.set('total_rendering',[/^Browser Compositor$/,/^Chrome_InProcGpuThread$/,/^Compositor$/,/CompositorTileWorker/,/^CrBrowserMain$/,/^CrGpuMain$/,/^CrRendererMain$/,/IOThread/,/^VizCompositorThread$/]);const ALL_CATEGORIES=[...CATEGORY_THREAD_MAP.keys(),'other'];function addValueToMap_(map,key,value){const oldValue=map.get(key)||0;map.set(key,oldValue+value);}
function addToArrayInMap_(map,key,value){const arr=map.get(key)||[];arr.push(value);map.set(key,arr);}
function*getCategories_(threadName){let isOther=true;for(const[category,regexps]of CATEGORY_THREAD_MAP){for(const regexp of regexps){if(regexp.test(threadName)){if(category!=='total_all')isOther=false;yield category;break;}}}
if(isOther)yield'other';}
@@ -8304,11 +8331,11 @@ if(eventsByEnvironment[BROWSER_ENVIRONMENT].length>0){return eventsByEnvironment
return legacyEvents;}
function computeFrameSegments_(events,segments,opt_minFrameCount){const minFrameCount=opt_minFrameCount||MIN_FRAME_COUNT;const frameEvents=events.map(e=>new FrameEvent(e));const frameSegments=[];for(const segment of segments){const filtered=segment.boundsRange.filterArray(frameEvents,x=>x.eventStart);if(filtered.length<minFrameCount)continue;for(let i=1;i<filtered.length;i++){const duration=filtered[i].frameStart-filtered[i-1].frameStart;frameSegments.push(new FrameSegment(filtered[i-1],duration));}}
return frameSegments;}
-function addBasicFrameTimeHistograms_(histograms,frameSegments,prefix){const frameTimes=(frameSegments.length===0)?[0]:frameSegments.map(x=>x.duration);histograms.createHistogram(`${prefix}frame_times`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,frameTimes,{binBoundaries:tr.v.HistogramBinBoundaries.createLinear(0,50,20),description:'Raw frame times.',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});histograms.createHistogram(`${prefix}percentage_smooth`,tr.b.Unit.byName.unitlessNumber_biggerIsBetter,100*tr.b.math.Statistics.sum(frameTimes,(x=>(x<17?1:0)))/frameTimes.length,{description:'Percentage of frames that were hitting 60 FPS.',summaryOptions:{},});}
+function addBasicFrameTimeHistograms_(histograms,frameSegments,prefix){const frameTimes=(frameSegments.length===0)?[0]:frameSegments.map(x=>x.duration);histograms.createHistogram(`${prefix}frame_times`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,frameTimes,{binBoundaries:tr.v.HistogramBinBoundaries.createLinear(0,50,20),description:'Raw frame times.',summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,});}
function addFrameTimeHistograms(histograms,model,segments,opt_minFrameCount){const minFrameCount=opt_minFrameCount||MIN_FRAME_COUNT;const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const events=getDisplayCompositorPresentationEvents_(modelHelper);if(!events)return;addFrameTimeHistogramsHelper(histograms,model,segments,events,'',true,minFrameCount);const eventsExp=getDisplayCompositorPresentationEventsExp_(modelHelper);if(eventsExp&&eventsExp.length>0){addFrameTimeHistogramsHelper(histograms,model,segments,eventsExp,'exp_',false,minFrameCount);}}
function addFrameTimeHistogramsHelper(histograms,model,segments,events,prefix,addCpuMetrics,minFrameCount){const frameSegments=computeFrameSegments_(events,segments,minFrameCount);addBasicFrameTimeHistograms_(histograms,frameSegments,prefix+'');if(addCpuMetrics){tr.metrics.rendering.addCpuUtilizationHistograms(histograms,model,frameSegments,(thread,segment)=>thread.getCpuTimeForRange(segment.boundsRange),category=>`thread_${category}_cpu_time_per_frame`,'CPU cores of a thread group per frame');tr.metrics.rendering.addCpuUtilizationHistograms(histograms,model,frameSegments,(thread,segment)=>thread.getNumToplevelSlicesForRange(segment.boundsRange),category=>`tasks_per_frame_${category}`,'Number of tasks of a thread group per frame');let totalWallTime=0;let totalCpuTime=0;for(const segment of frameSegments){for(const thread of model.getAllThreads()){totalCpuTime+=thread.getCpuTimeForRange(segment.boundsRange);totalWallTime+=thread.getWallTimeForRange(segment.boundsRange);}}
histograms.createHistogram('cpu_wall_time_ratio',tr.b.Unit.byName.unitlessNumber_biggerIsBetter,totalCpuTime/totalWallTime,{description:'Ratio of total cpu-time vs. wall-time.',summaryOptions:{},});}
-const refreshPeriod=getRefreshPeriod(model,frameSegments.map(fs=>fs.boundsRange));frameSegments.forEach(fs=>fs.updateLength(refreshPeriod));const validFrames=frameSegments.filter(fs=>fs.length>=MIN_FRAME_LENGTH);const totalFrameDuration=tr.b.math.Statistics.sum(frameSegments,fs=>fs.duration);addJankCountHistograms(histograms,validFrames,prefix);const frameLengths=validFrames.map(frame=>frame.length);histograms.createHistogram(prefix+'frame_lengths',tr.b.Unit.byName.unitlessNumber_smallerIsBetter,frameLengths,{binBoundaries:tr.v.HistogramBinBoundaries.createLinear(0,5,20),summaryOptions:tr.metrics.rendering.SUMMARY_OPTIONS,description:'Frame times in vsyncs.'});histograms.createHistogram(prefix+'avg_surface_fps',tr.b.Unit.byName.unitlessNumber_biggerIsBetter,frameLengths.length/tr.b.convertUnit(totalFrameDuration,tr.b.UnitScale.TIME.MILLI_SEC,tr.b.UnitScale.TIME.SEC),{description:'Average frames per second.',summaryOptions:{},});}
+const refreshPeriod=getRefreshPeriod(model,frameSegments.map(fs=>fs.boundsRange));frameSegments.forEach(fs=>fs.updateLength(refreshPeriod));const validFrames=frameSegments.filter(fs=>fs.length>=MIN_FRAME_LENGTH);const totalFrameDuration=tr.b.math.Statistics.sum(frameSegments,fs=>fs.duration);addJankCountHistograms(histograms,validFrames,prefix);const frameLengths=validFrames.map(frame=>frame.length);histograms.createHistogram(prefix+'avg_surface_fps',tr.b.Unit.byName.unitlessNumber_biggerIsBetter,frameLengths.length/tr.b.convertUnit(totalFrameDuration,tr.b.UnitScale.TIME.MILLI_SEC,tr.b.UnitScale.TIME.SEC),{description:'Average frames per second.',summaryOptions:{},});}
function addUIFrameTimeHistograms(histograms,model,segments,opt_minFrameCount){const minFrameCount=opt_minFrameCount||MIN_FRAME_COUNT;const events=getUIPresentationEvents_(model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper));if(events.length===0)return;const frameSegments=computeFrameSegments_(events,segments,minFrameCount);addBasicFrameTimeHistograms_(histograms,frameSegments,'ui_');}
function addJankCountHistograms(histograms,validFrames,prefix){const jankEvents=[];for(let i=1;i<validFrames.length;i++){const change=Math.round((validFrames[i].length-validFrames[i-1].length));if(change>0&&change<PAUSE_THRESHOLD){jankEvents.push(validFrames[i].event);}}
const jankCount=jankEvents.length;const diagnostics=new tr.v.d.DiagnosticMap();diagnostics.set('events',new tr.v.d.RelatedEventSet(jankEvents));diagnostics.set('timestamps',new tr.v.d.GenericSet(jankEvents.map(e=>e.start)));const histogram=histograms.createHistogram(prefix+'jank_count',tr.b.Unit.byName.count_smallerIsBetter,{value:jankCount,diagnostics},{description:'Number of changes in frame rate.',summaryOptions:{},});}
@@ -8432,7 +8459,7 @@ function collectRectsBasedSpeedIndexSamplesFromLoadExpectations(model,chromeHelp
const rendererHelper=chromeHelper.rendererHelpers[expectation.renderProcess.pid];addRectsBasedSpeedIndexSample(rectsBasedSpeedIndexSamples,rendererHelper,expectation.navigationStart.start,expectation.duration,expectation.navigationStart.args.frame);}
return rectsBasedSpeedIndexSamples;}
function rectsBasedSpeedIndexMetric(histograms,model){const rectsBasedSpeedIndexHistogram=histograms.createHistogram('rectsBasedSpeedIndex',timeDurationInMs_smallerIsBetter,[],{binBoundaries:BIN_BOUNDARIES,description:' the average time at which visible parts of the'+' page are displayed (in ms).',summaryOptions:SUMMARY_OPTIONS,});const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const samples=collectRectsBasedSpeedIndexSamplesFromLoadExpectations(model,chromeHelper);for(const sample of samples){rectsBasedSpeedIndexHistogram.addSample(sample.value);}}
-tr.metrics.MetricRegistry.register(rectsBasedSpeedIndexMetric);return{rectsBasedSpeedIndexMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){const LONG_TASK_THRESHOLD_MS=50;const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const unitlessNumber_smallerIsBetter=tr.b.Unit.byName.unitlessNumber_smallerIsBetter;const RelatedEventSet=tr.v.d.RelatedEventSet;const hasCategoryAndName=tr.metrics.sh.hasCategoryAndName;const EventFinderUtils=tr.e.chrome.EventFinderUtils;function createBreakdownDiagnostic(breakdownTree){const breakdownDiagnostic=new tr.v.d.Breakdown();breakdownDiagnostic.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(const label in breakdownTree){breakdownDiagnostic.set(label,breakdownTree[label].total);}
+tr.metrics.MetricRegistry.register(rectsBasedSpeedIndexMetric);return{rectsBasedSpeedIndexMetric};});'use strict';tr.exportTo('tr.v.d',function(){const ALERT_GROUPS={CPU_USAGE:'cpu_usage',LOADING_PAINT:'loading_paint',LOADING_INTERACTIVITY:'loading_interactivity',LOADING_LAYOUT:'loading_layout',};return{ALERT_GROUPS,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const LONG_TASK_THRESHOLD_MS=50;const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const unitlessNumber_smallerIsBetter=tr.b.Unit.byName.unitlessNumber_smallerIsBetter;const RelatedEventSet=tr.v.d.RelatedEventSet;const hasCategoryAndName=tr.metrics.sh.hasCategoryAndName;const EventFinderUtils=tr.e.chrome.EventFinderUtils;function createBreakdownDiagnostic(breakdownTree){const breakdownDiagnostic=new tr.v.d.Breakdown();breakdownDiagnostic.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(const label in breakdownTree){breakdownDiagnostic.set(label,breakdownTree[label].total);}
return breakdownDiagnostic;}
const LOADING_METRIC_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,1e3,20).addLinearBins(3e3,20).addExponentialBins(20e3,20);const TIME_TO_INTERACTIVE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,40e3,35).addExponentialBins(80e3,15);const LAYOUT_SHIFT_SCORE_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,50,25);const SUMMARY_OPTIONS={avg:true,count:false,max:true,min:true,std:true,sum:false,};function findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,ts){const objects=rendererHelper.process.objects;const frameLoaderInstances=objects.instancesByTypeName_.FrameLoader;if(frameLoaderInstances===undefined)return undefined;let snapshot;for(const instance of frameLoaderInstances){if(!instance.isAliveAt(ts))continue;const maybeSnapshot=instance.getSnapshotAt(ts);if(frameIdRef!==maybeSnapshot.args.frame.id_ref)continue;snapshot=maybeSnapshot;}
return snapshot;}
@@ -8473,7 +8500,7 @@ return{firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstCpuId
function addSamplesToHistogram(samples,histogram,histograms){for(const sample of samples){histogram.addSample(sample.value,sample.diagnostics);if(histogram.name!=='timeToFirstContentfulPaint')continue;if(!sample.breakdownTree)continue;for(const[category,breakdown]of Object.entries(sample.breakdownTree)){const relatedName=`${histogram.name}:${category}`;let relatedHist=histograms.getHistogramsNamed(relatedName)[0];if(!relatedHist){relatedHist=histograms.createHistogram(relatedName,histogram.unit,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,summaryOptions:{count:false,max:false,min:false,sum:false,},});let relatedNames=histogram.diagnostics.get('breakdown');if(!relatedNames){relatedNames=new tr.v.d.RelatedNameMap();histogram.diagnostics.set('breakdown',relatedNames);}
relatedNames.set(category,relatedName);}
relatedHist.addSample(breakdown.total,{breakdown:tr.v.d.Breakdown.fromEntries(Object.entries(breakdown.events)),});}}}
-function loadingMetric(histograms,model){const firstPaintHistogram=histograms.createHistogram('timeToFirstPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to first paint',summaryOptions:SUMMARY_OPTIONS,});const firstContentfulPaintHistogram=histograms.createHistogram('timeToFirstContentfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to first contentful paint',summaryOptions:SUMMARY_OPTIONS,});const firstContentfulPaintCpuTimeHistogram=histograms.createHistogram('cpuTimeToFirstContentfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'CPU time to first contentful paint',summaryOptions:SUMMARY_OPTIONS,});const onLoadHistogram=histograms.createHistogram('timeToOnload',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to onload. '+'This is temporary metric used for PCv1/v2 sanity checking',summaryOptions:SUMMARY_OPTIONS,});const firstMeaningfulPaintHistogram=histograms.createHistogram('timeToFirstMeaningfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to first meaningful paint',summaryOptions:SUMMARY_OPTIONS,});const firstMeaningfulPaintCpuTimeHistogram=histograms.createHistogram('cpuTimeToFirstMeaningfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'CPU time to first meaningful paint',summaryOptions:SUMMARY_OPTIONS,});const timeToInteractiveHistogram=histograms.createHistogram('timeToInteractive',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time to Interactive',summaryOptions:SUMMARY_OPTIONS,});const totalBlockingTimeHistogram=histograms.createHistogram('totalBlockingTime',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Total Blocking Time',summaryOptions:SUMMARY_OPTIONS,});const timeToFirstCpuIdleHistogram=histograms.createHistogram('timeToFirstCpuIdle',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time to First CPU Idle',summaryOptions:SUMMARY_OPTIONS,});const aboveTheFoldLoadedToVisibleHistogram=histograms.createHistogram('aboveTheFoldLoadedToVisible',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time from first visible to load for AMP pages only.',summaryOptions:SUMMARY_OPTIONS,});const firstViewportReadyHistogram=histograms.createHistogram('timeToFirstViewportReady',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time from navigation to load for AMP pages only. ',summaryOptions:SUMMARY_OPTIONS,});const largestImagePaintHistogram=histograms.createHistogram('largestImagePaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'Time to Largest Image Paint',summaryOptions:SUMMARY_OPTIONS,});const largestTextPaintHistogram=histograms.createHistogram('largestTextPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'Time to Largest Text Paint',summaryOptions:SUMMARY_OPTIONS,});const largestContentfulPaintHistogram=histograms.createHistogram('largestContentfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'Time to Largest Contentful Paint',summaryOptions:SUMMARY_OPTIONS,});const layoutShiftHistogram=histograms.createHistogram('mainFrameCumulativeLayoutShift',unitlessNumber_smallerIsBetter,[],{binBoundaries:LAYOUT_SHIFT_SCORE_BOUNDARIES,description:'Main Frame Document Cumulative Layout Shift Score',summaryOptions:SUMMARY_OPTIONS,});const navigationStartHistogram=histograms.createHistogram('navigationStart',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'navigationStart',summaryOptions:SUMMARY_OPTIONS,});tr.metrics.sh.rectsBasedSpeedIndexMetric(histograms,model);const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const pid in chromeHelper.rendererHelpers){const rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;const samplesSet=collectLoadingMetricsForRenderer(rendererHelper);const lcpSamples=findLargestContentfulPaintHistogramSamples(chromeHelper.browserHelper.mainThread.sliceGroup.slices);addSamplesToHistogram(lcpSamples,largestContentfulPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstPaintSamples,firstPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstContentfulPaintSamples,firstContentfulPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstContentfulPaintCpuTimeSamples,firstContentfulPaintCpuTimeHistogram,histograms);addSamplesToHistogram(samplesSet.onLoadSamples,onLoadHistogram,histograms);addSamplesToHistogram(samplesSet.aboveTheFoldLoadedToVisibleSamples,aboveTheFoldLoadedToVisibleHistogram,histograms);addSamplesToHistogram(samplesSet.firstViewportReadySamples,firstViewportReadyHistogram,histograms);addSamplesToHistogram(samplesSet.largestImagePaintSamples,largestImagePaintHistogram,histograms);addSamplesToHistogram(samplesSet.largestTextPaintSamples,largestTextPaintHistogram,histograms);addSamplesToHistogram(samplesSet.layoutShiftSamples,layoutShiftHistogram,histograms);addSamplesToHistogram(samplesSet.navigationStartSamples,navigationStartHistogram,histograms);}
+function loadingMetric(histograms,model){const firstPaintHistogram=histograms.createHistogram('timeToFirstPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to first paint',summaryOptions:SUMMARY_OPTIONS,alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_PAINT],});const firstContentfulPaintHistogram=histograms.createHistogram('timeToFirstContentfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to first contentful paint',summaryOptions:SUMMARY_OPTIONS,alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_PAINT],});const firstContentfulPaintCpuTimeHistogram=histograms.createHistogram('cpuTimeToFirstContentfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'CPU time to first contentful paint',summaryOptions:SUMMARY_OPTIONS,alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_PAINT],});const onLoadHistogram=histograms.createHistogram('timeToOnload',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to onload. '+'This is temporary metric used for PCv1/v2 sanity checking',summaryOptions:SUMMARY_OPTIONS,});const firstMeaningfulPaintHistogram=histograms.createHistogram('timeToFirstMeaningfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'time to first meaningful paint',summaryOptions:SUMMARY_OPTIONS,alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_PAINT],});const firstMeaningfulPaintCpuTimeHistogram=histograms.createHistogram('cpuTimeToFirstMeaningfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'CPU time to first meaningful paint',summaryOptions:SUMMARY_OPTIONS,alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_PAINT],});const timeToInteractiveHistogram=histograms.createHistogram('timeToInteractive',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time to Interactive',summaryOptions:SUMMARY_OPTIONS,alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_PAINT],alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_INTERACTIVITY],});const totalBlockingTimeHistogram=histograms.createHistogram('totalBlockingTime',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Total Blocking Time',summaryOptions:SUMMARY_OPTIONS,alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_INTERACTIVITY],});const timeToFirstCpuIdleHistogram=histograms.createHistogram('timeToFirstCpuIdle',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time to First CPU Idle',summaryOptions:SUMMARY_OPTIONS,alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_INTERACTIVITY],});const aboveTheFoldLoadedToVisibleHistogram=histograms.createHistogram('aboveTheFoldLoadedToVisible',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time from first visible to load for AMP pages only.',summaryOptions:SUMMARY_OPTIONS,});const firstViewportReadyHistogram=histograms.createHistogram('timeToFirstViewportReady',timeDurationInMs_smallerIsBetter,[],{binBoundaries:TIME_TO_INTERACTIVE_BOUNDARIES,description:'Time from navigation to load for AMP pages only. ',summaryOptions:SUMMARY_OPTIONS,});const largestImagePaintHistogram=histograms.createHistogram('largestImagePaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'Time to Largest Image Paint',summaryOptions:SUMMARY_OPTIONS,});const largestTextPaintHistogram=histograms.createHistogram('largestTextPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'Time to Largest Text Paint',summaryOptions:SUMMARY_OPTIONS,});const largestContentfulPaintHistogram=histograms.createHistogram('largestContentfulPaint',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'Time to Largest Contentful Paint',summaryOptions:SUMMARY_OPTIONS,alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_PAINT],});const layoutShiftHistogram=histograms.createHistogram('mainFrameCumulativeLayoutShift',unitlessNumber_smallerIsBetter,[],{binBoundaries:LAYOUT_SHIFT_SCORE_BOUNDARIES,description:'Main Frame Document Cumulative Layout Shift Score',summaryOptions:SUMMARY_OPTIONS,alertGrouping:[tr.v.d.ALERT_GROUPS.LOADING_LAYOUT],});const navigationStartHistogram=histograms.createHistogram('navigationStart',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'navigationStart',summaryOptions:SUMMARY_OPTIONS,});tr.metrics.sh.rectsBasedSpeedIndexMetric(histograms,model);const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const pid in chromeHelper.rendererHelpers){const rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;const samplesSet=collectLoadingMetricsForRenderer(rendererHelper);const lcpSamples=findLargestContentfulPaintHistogramSamples(chromeHelper.browserHelper.mainThread.sliceGroup.slices);addSamplesToHistogram(lcpSamples,largestContentfulPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstPaintSamples,firstPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstContentfulPaintSamples,firstContentfulPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstContentfulPaintCpuTimeSamples,firstContentfulPaintCpuTimeHistogram,histograms);addSamplesToHistogram(samplesSet.onLoadSamples,onLoadHistogram,histograms);addSamplesToHistogram(samplesSet.aboveTheFoldLoadedToVisibleSamples,aboveTheFoldLoadedToVisibleHistogram,histograms);addSamplesToHistogram(samplesSet.firstViewportReadySamples,firstViewportReadyHistogram,histograms);addSamplesToHistogram(samplesSet.largestImagePaintSamples,largestImagePaintHistogram,histograms);addSamplesToHistogram(samplesSet.largestTextPaintSamples,largestTextPaintHistogram,histograms);addSamplesToHistogram(samplesSet.layoutShiftSamples,layoutShiftHistogram,histograms);addSamplesToHistogram(samplesSet.navigationStartSamples,navigationStartHistogram,histograms);}
const samplesSet=collectMetricsFromLoadExpectations(model,chromeHelper);addSamplesToHistogram(samplesSet.firstMeaningfulPaintSamples,firstMeaningfulPaintHistogram,histograms);addSamplesToHistogram(samplesSet.firstMeaningfulPaintCpuTimeSamples,firstMeaningfulPaintCpuTimeHistogram,histograms);addSamplesToHistogram(samplesSet.interactiveSamples,timeToInteractiveHistogram,histograms);addSamplesToHistogram(samplesSet.firstCpuIdleSamples,timeToFirstCpuIdleHistogram,histograms);addSamplesToHistogram(samplesSet.totalBlockingTimeSamples,totalBlockingTimeHistogram,histograms);}
tr.metrics.MetricRegistry.register(loadingMetric);return{loadingMetric,createBreakdownDiagnostic};});'use strict';tr.exportTo('tr.metrics',function(){const SPA_NAVIGATION_START_TO_FIRST_PAINT_DURATION_BIN_BOUNDARY=tr.v.HistogramBinBoundaries.createExponential(1,1000,50);function spaNavigationMetric(histograms,model){const histogram=new tr.v.Histogram('spaNavigationStartToFpDuration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,SPA_NAVIGATION_START_TO_FIRST_PAINT_DURATION_BIN_BOUNDARY);histogram.description='Latency between the input event causing'+' a SPA navigation and the first paint event after it';histogram.customizeSummaryOptions({count:false,sum:false,});const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper){return;}
const rendererHelpers=modelHelper.rendererHelpers;if(!rendererHelpers){return;}
@@ -8488,7 +8515,7 @@ let allProcessCpuTime=0;for(const pid in model.processes){const process=model.pr
let processCpuTime=0;for(const tid in process.threads){const thread=process.threads[tid];processCpuTime+=thread.getCpuTimeForRange(rangeOfInterest);}
allProcessCpuTime+=processCpuTime;}
let normalizedAllProcessCpuTime=0;if(rangeOfInterest.duration>0){normalizedAllProcessCpuTime=allProcessCpuTime/rangeOfInterest.duration;}
-const unit=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const cpuTimeHist=new tr.v.Histogram('cpu_time_percentage',unit,CPU_TIME_PERCENTAGE_BOUNDARIES);cpuTimeHist.description='Percent CPU utilization, normalized against a single core. Can be '+'greater than 100% if machine has multiple cores.';cpuTimeHist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false});cpuTimeHist.addSample(normalizedAllProcessCpuTime);histograms.addHistogram(cpuTimeHist);}
+const unit=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const cpuTimeHist=new tr.v.Histogram('cpu_time_percentage',unit,CPU_TIME_PERCENTAGE_BOUNDARIES);cpuTimeHist.description='Percent CPU utilization, normalized against a single core. Can be '+'greater than 100% if machine has multiple cores.';cpuTimeHist.setAlertGrouping([tr.v.d.ALERT_GROUPS.CPU_USAGE]);cpuTimeHist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false});cpuTimeHist.addSample(normalizedAllProcessCpuTime);histograms.addHistogram(cpuTimeHist);}
tr.metrics.MetricRegistry.register(cpuTimeMetric,{supportsRangeOfInterest:true});return{cpuTimeMetric,};});'use strict';tr.exportTo('tr.v',function(){class HistogramDeserializer{static deserialize(data){const deserializer=new HistogramDeserializer(data[0],data[1]);return data.slice(2).map(datum=>tr.v.Histogram.deserialize(datum,deserializer));}
constructor(objects,diagnostics){this.objects_=objects;this.diagnostics_=[];for(const[type,diagnosticsByName]of Object.entries(diagnostics||{})){for(const[name,diagnosticsById]of Object.entries(diagnosticsByName)){for(const[id,data]of Object.entries(diagnosticsById)){const diagnostic=tr.v.d.Diagnostic.deserialize(type,data,this);this.diagnostics_[parseInt(id)]={name,diagnostic};}}}}
getObject(id){return this.objects_[id];}
@@ -8924,13 +8951,16 @@ function collectSpeedIndexSamplesFromLoadExpectations(model,chromeHelper){const
const rendererHelper=chromeHelper.rendererHelpers[expectation.renderProcess.pid];addSpeedIndexScreenshotsBasedSample(speedIndexScreenshotsBasedSamples,expectation.navigationStart,expectation.duration,chromeHelper.browserHelper);}
return speedIndexScreenshotsBasedSamples;}
function screenshotsBasedSpeedIndexMetric(histograms,model){const speedIndexScreenshotsBasedHistogram=histograms.createHistogram('speedIndexScreenshotsBased',timeDurationInMs_smallerIsBetter,[],{binBoundaries:LOADING_METRIC_BOUNDARIES,description:'The average time at which visible parts of the'+' page are displayed.',summaryOptions:SUMMARY_OPTIONS,});const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const samples=collectSpeedIndexSamplesFromLoadExpectations(model,chromeHelper);for(const sample of samples){speedIndexScreenshotsBasedHistogram.addSample(sample.value);}}
-tr.metrics.MetricRegistry.register(screenshotsBasedSpeedIndexMetric);return{screenshotsBasedSpeedIndexMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function webviewStartupMetric(histograms,model){const startupWallHist=new tr.v.Histogram('webview_startup_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupWallHist.description='WebView startup wall time';const startupCPUHist=new tr.v.Histogram('webview_startup_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupCPUHist.description='WebView startup CPU time';const loadWallHist=new tr.v.Histogram('webview_url_load_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadWallHist.description='WebView blank URL load wall time';const loadCPUHist=new tr.v.Histogram('webview_url_load_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadCPUHist.description='WebView blank URL load CPU time';for(const slice of model.getDescendantEvents()){if(!(slice instanceof tr.model.ThreadSlice))continue;if(slice.title==='WebViewStartupInterval'){startupWallHist.addSample(slice.duration);startupCPUHist.addSample(slice.cpuDuration);}
+tr.metrics.MetricRegistry.register(screenshotsBasedSpeedIndexMetric);return{screenshotsBasedSpeedIndexMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function weblayerStartupMetric(histograms,model){const startupWallHist=new tr.v.Histogram('weblayer_startup_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupWallHist.description='WebLayer startup wall time';const loadWallHist=new tr.v.Histogram('weblayer_url_load_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadWallHist.description='WebLayer blank URL load wall time';for(const slice of model.getDescendantEvents()){if(!(slice instanceof tr.model.ThreadSlice))continue;if(slice.title==='WebLayerStartupInterval'){startupWallHist.addSample(slice.duration);}
+if(slice.title==='WebLayerBlankUrlLoadInterval'){loadWallHist.addSample(slice.duration);}}
+histograms.addHistogram(startupWallHist);histograms.addHistogram(loadWallHist);}
+tr.metrics.MetricRegistry.register(weblayerStartupMetric);return{weblayerStartupMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function webviewStartupMetric(histograms,model){const startupWallHist=new tr.v.Histogram('webview_startup_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupWallHist.description='WebView startup wall time';const startupCPUHist=new tr.v.Histogram('webview_startup_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupCPUHist.description='WebView startup CPU time';const loadWallHist=new tr.v.Histogram('webview_url_load_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadWallHist.description='WebView blank URL load wall time';const loadCPUHist=new tr.v.Histogram('webview_url_load_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadCPUHist.description='WebView blank URL load CPU time';for(const slice of model.getDescendantEvents()){if(!(slice instanceof tr.model.ThreadSlice))continue;if(slice.title==='WebViewStartupInterval'){startupWallHist.addSample(slice.duration);startupCPUHist.addSample(slice.cpuDuration);}
if(slice.title==='WebViewBlankUrlLoadInterval'){loadWallHist.addSample(slice.duration);loadCPUHist.addSample(slice.cpuDuration);}}
histograms.addHistogram(startupWallHist);histograms.addHistogram(startupCPUHist);histograms.addHistogram(loadWallHist);histograms.addHistogram(loadCPUHist);}
tr.metrics.MetricRegistry.register(webviewStartupMetric);return{webviewStartupMetric,};});'use strict';tr.exportTo('tr.metrics.tabs',function(){function tabsMetric(histograms,model,opt_options){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!chromeHelper){return;}
const tabSwitchRequestDelays=[];const TAB_SWITCHING_REQUEST_TITLE='TabSwitchVisibilityRequest';let startTabSwitchVisibilityRequest=Number.MAX_SAFE_INTEGER;for(const helper of chromeHelper.browserHelpers){if(!helper.mainThread)continue;for(const slice of helper.mainThread.asyncSliceGroup.slices){if(slice.title===TAB_SWITCHING_REQUEST_TITLE&&!slice.error){tabSwitchRequestDelays.push(slice.duration);if(slice.start<startTabSwitchVisibilityRequest){startTabSwitchVisibilityRequest=slice.start;}}}}
histograms.createHistogram('tab_switching_request_delay',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tabSwitchRequestDelays,{description:'Delay before tab-request is made',summaryOptions:{sum:false}});const tabSwitchLatencies=[];const TAB_SWITCHING_SLICE_TITLE='TabSwitching::Latency';function extractLatencyFromHelpers(helpers,legacy){for(const helper of helpers){if(!helper.mainThread){continue;}
-const thread=helper.mainThread;for(const slice of thread.asyncSliceGroup.slices){if(slice.title===TAB_SWITCHING_SLICE_TITLE&&(legacy||slice.args.latency)&&slice.start>startTabSwitchVisibilityRequest){tabSwitchLatencies.push(legacy?slice.duration:slice.args.latency);}}}}
+const thread=helper.mainThread;for(const slice of thread.asyncSliceGroup.slices){if(slice.title===TAB_SWITCHING_SLICE_TITLE&&(legacy||slice.args.latency)&&slice.start>startTabSwitchVisibilityRequest-1){tabSwitchLatencies.push(legacy?slice.duration:slice.args.latency);}}}}
extractLatencyFromHelpers(chromeHelper.browserHelpers);extractLatencyFromHelpers(Object.values(chromeHelper.rendererHelpers));if(tabSwitchLatencies.length===0){extractLatencyFromHelpers(chromeHelper.browserHelpers,true);}
histograms.createHistogram('tab_switching_latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tabSwitchLatencies,{description:'Tab switching time in ms',summaryOptions:{sum:false}});}
tr.metrics.MetricRegistry.register(tabsMetric,{supportsRangeOfInterest:false,});return{tabsMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const MEMORY_INFRA_TRACING_CATEGORY='disabled-by-default-memory-infra';const TIME_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1e-3,1e5,30);const BYTE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e9,30);const COUNT_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e5,30);const SUMMARY_OPTIONS=tr.v.Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS;function addMemoryInfraHistograms(histograms,model,categoryNamesToTotalEventSizes){const memoryDumpCount=model.globalMemoryDumps.length;if(memoryDumpCount===0)return;let totalOverhead=0;let nonMemoryInfraThreadOverhead=0;const overheadByProvider={};for(const process of Object.values(model.processes)){for(const thread of Object.values(process.threads)){for(const slice of Object.values(thread.sliceGroup.slices)){if(slice.category!==MEMORY_INFRA_TRACING_CATEGORY)continue;totalOverhead+=slice.duration;if(thread.name!=='MemoryInfra'){nonMemoryInfraThreadOverhead+=slice.duration;}
@@ -8948,20 +8978,17 @@ return{sum,bins};}
function mergeBins_(x,y){x.sum+=y.sum;const allBins=[...x.bins,...y.bins];allBins.sort((a,b)=>a.min-b.min);x.bins=[];let last=undefined;for(const bin of allBins){if(last!==undefined&&bin.min===last.min){if(last.max!==bin.max)throw new Error('Incompatible bins');if(bin.count===0)continue;last.count+=bin.count;for(const event of bin.events){last.events.add(event);}
last.processes.addDiagnostic(bin.processes);}else{if(last!==undefined&&bin.min<last.max){throw new Error('Incompatible bins');}
x.bins.push(bin);last=bin;}}}
-function subtractBins_(x,y){x.sum-=y.sum;let p1=0;let p2=0;while(p2<y.bins.length){while(p1<x.bins.length&&x.bins[p1].min!==y.bins[p2].min){p1++;}
-if(p1===x.bins.length)throw new Error('Cannot subtract');if(x.bins[p1].max!==y.bins[p2].max){throw new Error('Incompatible bins');}
-if(x.bins[p1].count<y.bins[p2].count){throw new Error('Cannot subtract');}
-x.bins[p1].count-=y.bins[p2].count;for(const event of y.bins[p2].events){x.bins[p1].events.add(event);}
-const processName=tr.b.getOnlyElement(x.bins[p1].processes)[0];x.bins[p1].processes.set(processName,x.bins[p1].count);p2++;}}
function getHistogramUnit_(name){return tr.b.Unit.byName.unitlessNumber_smallerIsBetter;}
+function getIsHistogramBinsLinear_(histogramName){return histogramName.startsWith('Graphics.Smoothness.Throughput')||histogramName.startsWith('Memory.Memory.GPU.PeakMemoryUsage');}
function getHistogramBoundaries_(name){if(name.startsWith('Event.Latency.Scroll')){return tr.v.HistogramBinBoundaries.createExponential(1e3,1e5,50);}
if(name.startsWith('Graphics.Smoothness.Throughput')){return tr.v.HistogramBinBoundaries.createLinear(0,100,101);}
if(name.startsWith('Memory.Memory.GPU.PeakMemoryUsage')){return tr.v.HistogramBinBoundaries.createLinear(0,1e6,100);}
return tr.v.HistogramBinBoundaries.createExponential(1e-3,1e3,50);}
function umaMetric(histograms,model){const histogramValues=new Map();const nameCounts=new Map();for(const process of model.getAllProcesses()){const histogramEvents=new Map();for(const event of process.instantEvents){if(event.title!=='UMAHistogramSamples')continue;const name=event.args.name;const events=histogramEvents.get(name)||[];if(!histogramEvents.has(name))histogramEvents.set(name,events);events.push(event);}
-let processName=tr.e.chrome.chrome_processes.canonicalizeProcessName(process.name);nameCounts.set(processName,(nameCounts.get(processName)||0)+1);processName=`${processName}_${nameCounts.get(processName)}`;for(const[name,events]of histogramEvents){const values=histogramValues.get(name)||{sum:0,bins:[]};if(!histogramValues.has(name))histogramValues.set(name,values);const endValues=parseBuckets_(events[events.length-1],processName);if(events.length===1){mergeBins_(values,endValues);}else if(events.length===2){subtractBins_(endValues,parseBuckets_(events[0],processName));mergeBins_(values,endValues);}else{throw new Error('There should be at most two snapshots of an UMA '+'histogram in each process');}}}
-for(const[name,values]of histogramValues){const histogram=new tr.v.Histogram(name,getHistogramUnit_(name),getHistogramBoundaries_(name));let sumOfMiddles=0;let sumOfBinLengths=0;for(const bin of values.bins){sumOfMiddles+=bin.count*(bin.min+bin.max)/2;sumOfBinLengths+=bin.count*(bin.max-bin.min);}
-const shift=(values.sum-sumOfMiddles)/sumOfBinLengths;if(Math.abs(shift)>0.5)throw new Error('Samples sum is wrong');for(const bin of values.bins){if(bin.count===0)continue;const shiftedValue=(bin.min+bin.max)/2+shift*(bin.max-bin.min);for(const[processName,count]of bin.processes){bin.processes.set(processName,shiftedValue*count/bin.count);}
+let processName=tr.e.chrome.chrome_processes.canonicalizeProcessName(process.name);nameCounts.set(processName,(nameCounts.get(processName)||0)+1);processName=`${processName}_${nameCounts.get(processName)}`;for(const[name,events]of histogramEvents){const values=histogramValues.get(name)||{sum:0,bins:[]};if(!histogramValues.has(name))histogramValues.set(name,values);const endValues=parseBuckets_(events[events.length-1],processName);if(events.length===1){mergeBins_(values,endValues,name);}else{throw new Error('There should be at most one snapshot of UMA '+`histogram for ${name} in each process.`);}}}
+for(const[name,values]of histogramValues){const histogram=new tr.v.Histogram(name,getHistogramUnit_(name),getHistogramBoundaries_(name));const isLinear=getIsHistogramBinsLinear_(name);let sumOfMiddles=0;let sumOfBinLengths=0;for(const bin of values.bins){sumOfMiddles+=bin.count*(bin.min+bin.max)/2;sumOfBinLengths+=bin.count*(bin.max-bin.min);}
+const shift=(values.sum-sumOfMiddles)/sumOfBinLengths;if(isLinear&&Math.abs(shift)>0.5){throw new Error(`Samples sum is wrong for ${name}.`);}
+for(const bin of values.bins){if(bin.count===0)continue;const shiftedValue=(bin.min+bin.max)/2+shift*(bin.max-bin.min);for(const[processName,count]of bin.processes){bin.processes.set(processName,shiftedValue*count/bin.count);}
for(let i=0;i<bin.count;i++){histogram.addSample(shiftedValue,{processes:bin.processes,events:bin.events});}}
histograms.addHistogram(histogram);}}
tr.metrics.MetricRegistry.register(umaMetric,{requiredCategories:['benchmark'],});return{umaMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(4,200,100);function computeExecuteMetrics(histograms,model){const cpuTotalExecution=new tr.v.Histogram('v8_execution_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalExecution.description='cpu total time spent in script execution';const wallTotalExecution=new tr.v.Histogram('v8_execution_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalExecution.description='wall total time spent in script execution';const cpuSelfExecution=new tr.v.Histogram('v8_execution_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfExecution.description='cpu self time spent in script execution';const wallSelfExecution=new tr.v.Histogram('v8_execution_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfExecution.description='wall self time spent in script execution';for(const e of model.findTopmostSlicesNamed('V8.Execute')){cpuTotalExecution.addSample(e.cpuDuration);wallTotalExecution.addSample(e.duration);cpuSelfExecution.addSample(e.cpuSelfTime);wallSelfExecution.addSample(e.selfTime);}
@@ -8981,7 +9008,52 @@ histograms.addHistogram(cpuTotalOptimizeCode);histograms.addHistogram(wallTotalO
function computeDeoptimizeCodeMetrics(histograms,model){const cpuTotalDeoptimizeCode=new tr.v.Histogram('v8_deoptimize_code_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalDeoptimizeCode.description='cpu total time spent in code deoptimization';const wallTotalDeoptimizeCode=new tr.v.Histogram('v8_deoptimize_code_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalDeoptimizeCode.description='wall total time spent in code deoptimization';for(const e of model.findTopmostSlicesNamed('V8.DeoptimizeCode')){cpuTotalDeoptimizeCode.addSample(e.cpuDuration);wallTotalDeoptimizeCode.addSample(e.duration);}
histograms.addHistogram(cpuTotalDeoptimizeCode);histograms.addHistogram(wallTotalDeoptimizeCode);}
function executionMetric(histograms,model){computeExecuteMetrics(histograms,model);computeParseLazyMetrics(histograms,model);computeCompileIgnitionMetrics(histograms,model);computeCompileFullCodeMetrics(histograms,model);computeRecompileMetrics(histograms,model);computeOptimizeCodeMetrics(histograms,model);computeDeoptimizeCodeMetrics(histograms,model);}
-tr.metrics.MetricRegistry.register(executionMetric);return{executionMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const TARGET_FPS=60;const MS_PER_SECOND=1000;const WINDOW_SIZE_MS=MS_PER_SECOND/TARGET_FPS;function gcMetric(histograms,model,options){options=options||{};addDurationOfTopEvents(histograms,model);addTotalDurationOfTopEvents(histograms,model);if(options.include_sub_events){addDurationOfSubEvents(histograms,model);}
+tr.metrics.MetricRegistry.register(executionMetric);return{executionMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const TARGET_FPS=60;const MS_PER_SECOND=1000;const WINDOW_SIZE_MS=MS_PER_SECOND/TARGET_FPS;const EPSILON=1e-6;const METRICS=['v8:gc:cycle:full','v8:gc:cycle:full:cpp','v8:gc:cycle:full:mark','v8:gc:cycle:full:mark:cpp','v8:gc:cycle:full:weak','v8:gc:cycle:full:weak:cpp','v8:gc:cycle:full:sweep','v8:gc:cycle:full:sweep:cpp','v8:gc:cycle:full:compact','v8:gc:cycle:full:compact:cpp','v8:gc:cycle:main_thread:full','v8:gc:cycle:main_thread:full:cpp','v8:gc:cycle:main_thread:full:mark','v8:gc:cycle:main_thread:full:mark:cpp','v8:gc:cycle:main_thread:full:weak','v8:gc:cycle:main_thread:full:weak:cpp','v8:gc:cycle:main_thread:full:sweep','v8:gc:cycle:main_thread:full:sweep:cpp','v8:gc:cycle:main_thread:full:compact','v8:gc:cycle:main_thread:full:compact:cpp','v8:gc:event:main_thread:full:atomic','v8:gc:event:main_thread:full:atomic:cpp','v8:gc:event:main_thread:full:atomic:mark','v8:gc:event:main_thread:full:atomic:mark:cpp','v8:gc:event:main_thread:full:atomic:weak','v8:gc:event:main_thread:full:atomic:weak:cpp','v8:gc:event:main_thread:full:atomic:sweep','v8:gc:event:main_thread:full:atomic:sweep:cpp','v8:gc:event:main_thread:full:atomic:compact','v8:gc:event:main_thread:full:atomic:compact:cpp','v8:gc:event:main_thread:full:incremental','v8:gc:event:main_thread:full:incremental:cpp','v8:gc:event:main_thread:full:incremental:mark','v8:gc:event:main_thread:full:incremental:mark:cpp','v8:gc:event:main_thread:full:incremental:sweep','v8:gc:event:main_thread:full:incremental:sweep:cpp','v8:gc:cycle:young','v8:gc:cycle:main_thread:young',];const V8_FULL_ATOMIC_EVENTS=['V8.GCCompactor','V8.GCFinalizeMC','V8.GCFinalizeMCReduceMemory',];const V8_FULL_MARK_EVENTS=['V8.GC_MC_BACKGROUND_MARKING','V8.GC_MC_MARK','V8.GCIncrementalMarking','V8.GCIncrementalMarkingFinalize','V8.GCIncrementalMarkingStart',];const V8_FULL_COMPACT_EVENTS=['V8.GC_MC_BACKGROUND_EVACUATE_COPY','V8.GC_MC_BACKGROUND_EVACUATE_UPDATE_POINTERS','V8.GC_MC_EVACUATE',];const V8_FULL_SWEEP_EVENTS=['V8.GC_MC_BACKGROUND_SWEEPING','V8.GC_MC_SWEEP',];const V8_FULL_WEAK_EVENTS=['V8.GC_MC_CLEAR',];const V8_YOUNG_EVENTS=['V8.GC_SCAVENGER_BACKGROUND_SCAVENGE_PARALLEL','V8.GCScavenger',];const CPP_GC_FULL_MARK_EVENTS=['BlinkGC.AtomicPauseMarkEpilogue','BlinkGC.AtomicPauseMarkPrologue','BlinkGC.AtomicPauseMarkRoots','BlinkGC.AtomicPauseMarkTransitiveClosure','BlinkGC.ConcurrentMarkingStep','BlinkGC.IncrementalMarkingStartMarking','BlinkGC.IncrementalMarkingStep','BlinkGC.MarkBailOutObjects','BlinkGC.MarkFlushEphemeronPairs','BlinkGC.MarkFlushV8References','BlinkGC.UnifiedMarkingStep','CppGC.AtomicMark','CppGC.IncrementalMark','CppGC.ConcurrentMark',];const CPP_GC_FULL_COMPACT_EVENTS=['BlinkGC.AtomicPauseSweepAndCompact','CppGC.AtomicCompact',];const CPP_GC_FULL_SWEEP_EVENTS=['BlinkGC.CompleteSweep','BlinkGC.ConcurrentSweepingStep','BlinkGC.LazySweepInIdle','BlinkGC.LazySweepOnAllocation','CppGC.AtomicSweep','CppGC.IncrementalSweep','CppGC.ConcurrentSweep',];const CPP_GC_FULL_WEAK_EVENTS=['BlinkGC.MarkWeakProcessing','CppGC.AtomicWeak',];const RULES=[{events:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:atomic',},{events:V8_FULL_MARK_EVENTS,inside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:atomic:mark',},{events:CPP_GC_FULL_MARK_EVENTS,inside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:atomic:mark:cpp',},{events:V8_FULL_MARK_EVENTS,outside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:incremental:mark',},{events:CPP_GC_FULL_MARK_EVENTS,outside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:incremental:mark:cpp',},{events:V8_FULL_COMPACT_EVENTS,inside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:atomic:compact',},{events:CPP_GC_FULL_COMPACT_EVENTS,inside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:atomic:compact:cpp',},{events:V8_FULL_SWEEP_EVENTS,inside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:atomic:sweep',},{events:CPP_GC_FULL_SWEEP_EVENTS,inside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:atomic:sweep:cpp',},{events:V8_FULL_WEAK_EVENTS,inside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:atomic:weak',},{events:CPP_GC_FULL_WEAK_EVENTS,inside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:atomic:weak:cpp',},{events:V8_FULL_SWEEP_EVENTS,outside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:incremental:sweep',},{events:CPP_GC_FULL_SWEEP_EVENTS,outside:V8_FULL_ATOMIC_EVENTS,contribute_to:'full:incremental:sweep:cpp',},{events:V8_YOUNG_EVENTS,contribute_to:'young:atomic',},];const Granularity={CYCLE:'cycle',EVENT:'event',};const ThreadType={MAIN:'main',BACKGROUND:'background',ALL_THREADS:'all_threads',};class Metric{constructor(name){const parts=name.split(':');this.granularity_=parts[2];assert(this.granularity_===Granularity.CYCLE||this.granularity_===Granularity.EVENT);this.thread_=ThreadType.ALL_THREADS;let phasesIndex=3;if(parts[3]==='main_thread'){this.thread_=ThreadType.MAIN;phasesIndex=4;}
+if(parts[3]==='background_threads'){this.thread_=ThreadType.BACKGROUND;phasesIndex=4;}
+this.phases_=parts.slice(phasesIndex);const maxValue=this.isPerCycleMetric()?10000:1000;const boundaries=tr.v.HistogramBinBoundaries.createExponential(0.1,maxValue,100);this.histogram=new tr.v.Histogram(name,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,boundaries);this.histogram.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:false,sum:this.isPerCycleMetric(),});}
+isPerCycleMetric(){return this.granularity_===Granularity.CYCLE;}
+isMoreGeneralThanOrEqualTo(phases){const phasesSet=new Set(phases.split(':'));return this.phases_.every(phase=>phasesSet.has(phase));}
+contributingEvents(rules,events){const eventsByName=groupBy(events,e=>e.title);function matches(rule,event){function isEnclosing(name){if(!eventsByName.has(name))return false;return eventsByName.get(name).some(e=>encloses(e,event));}
+if(!rule.events.includes(event.title)){return false;}
+if(rule.inside&&!rule.inside.some(isEnclosing)){return false;}
+if(rule.outside&&rule.outside.some(isEnclosing)){return false;}
+return true;}
+const result=[];for(const event of events){const matching=rules.filter(r=>matches(r,event));if(matching.length===0){continue;}
+assert(matching.length===1,`${event.userFriendlyName} matches more than one rule: `+
+JSON.stringify(matching));if(this.isMoreGeneralThanOrEqualTo(matching[0].contribute_to)){result.push(event);}}
+return result;}
+apply(rules,events,threadTypes){const filtered=this.contributingEvents(rules,events);const eventsByThread=groupBy(filtered,e=>e.parentContainer.tid);let flattened=[];for(const[tid,threadEvents]of eventsByThread){if(this.thread_===ThreadType.ALL_THREADS||this.thread_===threadTypes.get(tid)){flattened=flattened.concat(flatten(threadEvents));}}
+if(this.isPerCycleMetric()){let sum=0;for(const event of flattened){sum+=event.cpuDuration;}
+if(flattened.length>0){this.histogram.addSample(sum);}}else{for(const event of flattened){this.histogram.addSample(event.cpuDuration);}}}}
+function assert(condition,message){if(!condition){throw new Error(message);}}
+function groupBy(objects,keyCallback){const result=new Map();for(const object of objects){const group=keyCallback(object);if(result.has(group)){result.get(group).push(object);}else{result.set(group,[object]);}}
+return result;}
+function eventsMentionedIn(rules){let result=[];for(const rule of rules){result=result.concat(rule.events);if(rule.inside){result=result.concat(rule.inside);}
+if(rule.outside){result=result.concat(rule.outside);}}
+return result;}
+function encloses(event1,event2){return(event1.start-EPSILON<=event2.start&&event2.end<=event1.end+EPSILON);}
+function jsExecutionThreadsWithTypes(rendererHelper){const mainThreads=([rendererHelper.mainThread].concat(rendererHelper.dedicatedWorkerThreads).concat(rendererHelper.serviceWorkerThreads));const backgroundThreads=rendererHelper.foregroundWorkerThreads;const threadTypes=new Map();for(const thread of mainThreads){threadTypes.set(thread.tid,ThreadType.MAIN);}
+for(const thread of backgroundThreads){threadTypes.set(thread.tid,ThreadType.BACKGROUND);}
+return[mainThreads.concat(backgroundThreads),threadTypes];}
+function flatten(events){function compareWithEpsilon(a,b){if(a.start<b.start-EPSILON)return-1;if(a.start>b.start+EPSILON)return 1;return b.end-a.end;}
+events.sort(compareWithEpsilon);let last=events[0];const result=[last];for(const e of events){if(e.end>last.end+EPSILON){assert(e.start>=last.end-EPSILON,'Overlapping events: '+
+e.userFriendlyName+' '+
+last.userFriendlyName);result.push(e);last=e;}}
+return result;}
+function groupByEpoch(events){function isV8Event(event){return event.category&&event.category.includes('v8');}
+function getEpoch(event){function checkEpochConsistency(epoch,event){if(epoch===null)return;assert(epoch===event.args.epoch,`${event.userFriendlyName} has epoch ${event.args.epoch} `+`which contradicts the epoch of nested events ${epoch}`);}
+const result={v8:null,cpp:null};while(event){if('epoch'in event.args){if(isV8Event(event)){checkEpochConsistency(result.v8,event);result.v8=event.args.epoch;}else{checkEpochConsistency(result.cpp,event);result.cpp=event.args.epoch;}}
+event=event.parentSlice;}
+return result;}
+const cppToV8=new Map();for(const event of events){const epoch=getEpoch(event);if(epoch.cpp!==null&&epoch.v8!==null){assert(!cppToV8.has(epoch.cpp)||cppToV8.get(epoch.cpp)===epoch.v8,`CppGC epoch ${epoch.cpp} corresponds to two v8 epochs `+`${cppToV8.get(epoch.cpp)} and ${epoch.v8}. `+`Detected at ${event.userFriendlyName}.`);cppToV8.set(epoch.cpp,epoch.v8);}}
+const result=new Map();for(const event of events){const epoch=getEpoch(event);if(epoch.cpp===null&&epoch.v8===null){continue;}
+assert(epoch.cpp===null||cppToV8.has(epoch.cpp),`CppGC epoch ${epoch.cpp} doesn't have the corresponding V8 epoch. `+`Detected at ${event.userFriendlyName}`);const key=epoch.v8===null?cppToV8.get(epoch.cpp):epoch.v8;if(result.has(key)){result.get(key).push(event);}else{result.set(key,[event]);}}
+return result;}
+function addGarbageCollectionMetrics(metricNames,histograms,model){const metrics=metricNames.map(name=>new Metric(name));const gcEventNames=new Set(eventsMentionedIn(RULES));const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){if(rendererHelper.isChromeTracingUI)continue;const[threads,threadTypes]=jsExecutionThreadsWithTypes(rendererHelper);const events=[];for(const thread of threads){for(const event of thread.sliceGroup.childEvents()){if(gcEventNames.has(event.title)){events.push(event);}}}
+for(const cycleEvents of groupByEpoch(events).values()){if(cycleEvents.some(tr.metrics.v8.utils.isForcedGarbageCollectionEvent)){continue;}
+for(const metric of metrics){metric.apply(RULES,cycleEvents,threadTypes);}}}
+for(const metric of metrics){histograms.addHistogram(metric.histogram);}}
+function gcMetric(histograms,model,options){options=options||{};addDurationOfTopEvents(histograms,model);addTotalDurationOfTopEvents(histograms,model);if(options.include_sub_events){addDurationOfSubEvents(histograms,model);}
addPercentageInV8ExecuteOfTopEvents(histograms,model);addTotalPercentageInV8Execute(histograms,model);addMarkCompactorMutatorUtilization(histograms,model);addTotalMarkCompactorTime(histograms,model);addTotalMarkCompactorMarkingTime(histograms,model);addScavengerSurvivedFromStackEvents(histograms,model);}
tr.metrics.MetricRegistry.register(gcMetric);const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;const percentage_smallerIsBetter=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const bytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
function createNumericForSubEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:false,percentile:[0.90]});return n;}
@@ -9005,7 +9077,7 @@ function addTotalPercentageInV8Execute(histograms,model){tr.metrics.v8.utils.gro
function addPercentageInV8Execute(histograms,model,name,events){let cpuDurationInV8Execute=0;let cpuDurationTotal=0;events.forEach(function(event){const v8Execute=tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isV8ExecuteEvent);if(v8Execute){cpuDurationInV8Execute+=event.cpuDuration;}
cpuDurationTotal+=event.cpuDuration;});const percentage=createPercentage(name+'_percentage_in_v8_execute',cpuDurationInV8Execute,cpuDurationTotal,percentage_smallerIsBetter);histograms.addHistogram(percentage);}
function addMarkCompactorMutatorUtilization(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const rendererHelpers=Object.values(chromeHelper.rendererHelpers);tr.metrics.v8.utils.addMutatorUtilization('v8-gc-mark-compactor-mmu',tr.metrics.v8.utils.isNotForcedMarkCompactorEvent,[100],rendererHelpers,histograms);}
-return{gcMetric,WINDOW_SIZE_MS,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const COUNT_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1000000,50);const DURATION_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.1,10000,50);const SUMMARY_OPTIONS={std:false,count:false,sum:false,min:false,max:false,};function convertMicroToMilli_(time){return tr.b.convertUnit(time,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);}
+return{gcMetric,WINDOW_SIZE_MS,addGarbageCollectionMetrics,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const COUNT_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1000000,50);const DURATION_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.1,10000,50);const SUMMARY_OPTIONS={std:false,count:false,sum:false,min:false,max:false,};function convertMicroToMilli_(time){return tr.b.convertUnit(time,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);}
function addDurationHistogram(histogramName,time,histograms){const value=convertMicroToMilli_(time);histograms.createHistogram(`${histogramName}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,{value},{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});}
function addCountHistogram(histogramName,value,histograms){histograms.createHistogram(`${histogramName}:count`,tr.b.Unit.byName.count_smallerIsBetter,{value},{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS});}
function runtimeStatsTotalMetric(histograms,model){const v8Slices=tr.metrics.v8.utils.filterEvents(model,ev=>ev instanceof tr.e.v8.V8ThreadSlice);const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(v8Slices);let overallV8Time=runtimeGroupCollection.totalTime;let overallV8Count=runtimeGroupCollection.totalCount;let mainThreadTime=runtimeGroupCollection.totalTime;let mainThreadCount=runtimeGroupCollection.totalCount;let mainThreadV8Time=runtimeGroupCollection.totalTime;let mainThreadV8Count=runtimeGroupCollection.totalCount;for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){addDurationHistogram(runtimeGroup.name,runtimeGroup.time,histograms);if(runtimeGroup.name==='Blink C++'){overallV8Time-=runtimeGroup.time;mainThreadV8Time-=runtimeGroup.time;}else if(runtimeGroup.name.includes('Background')){mainThreadTime-=runtimeGroup.time;mainThreadV8Time-=runtimeGroup.time;}
@@ -9015,12 +9087,16 @@ addDurationHistogram('V8-Only',overallV8Time,histograms);addCountHistogram('V8-O
tr.metrics.MetricRegistry.register(runtimeStatsTotalMetric);return{runtimeStatsTotalMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){function v8AndMemoryMetrics(histograms,model){tr.metrics.v8.executionMetric(histograms,model);tr.metrics.v8.gcMetric(histograms,model);tr.metrics.sh.memoryMetric(histograms,model,{rangeOfInterest:tr.metrics.v8.utils.rangeForMemoryDumps(model)});}
tr.metrics.MetricRegistry.register(v8AndMemoryMetrics);return{v8AndMemoryMetrics,};});'use strict';tr.exportTo('tr.metrics.v8',function(){function computeSyncInstantiationTimeMetric(histograms,wasmEvents){if(!wasmEvents.hasOwnProperty('wasm.SyncInstantiate'))return;const wasmSyncInstantiationTimeCPU=new tr.v.Histogram('v8:wasm:sync_instantiate:cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);wasmSyncInstantiationTimeCPU.description='cpu time spent instantiating a WebAssembly module';const wasmSyncInstantiationTimeWall=new tr.v.Histogram('v8:wasm:sync_instantiate:wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);wasmSyncInstantiationTimeWall.description='wall time spent instantiating a WebAssembly module';for(const e of wasmEvents['wasm.SyncInstantiate']){wasmSyncInstantiationTimeCPU.addSample(e.cpuDuration);wasmSyncInstantiationTimeWall.addSample(e.duration);}
histograms.addHistogram(wasmSyncInstantiationTimeCPU);histograms.addHistogram(wasmSyncInstantiationTimeWall);}
+function computeSyncCompileTimeMetric(histograms,wasmEvents){if(!wasmEvents.hasOwnProperty('wasm.SyncCompile'))return;const wasmSyncCompileTimeCPU=new tr.v.Histogram('v8:wasm:sync_compile:cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);wasmSyncCompileTimeCPU.description='cpu time spent compiling a WebAssembly module synchronously';const wasmSyncCompileTimeWall=new tr.v.Histogram('v8:wasm:sync_compile:wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);wasmSyncCompileTimeWall.description='wall time spent compiling a WebAssembly module synchronously';for(const e of wasmEvents['wasm.SyncCompile']){wasmSyncCompileTimeCPU.addSample(e.cpuDuration);wasmSyncCompileTimeWall.addSample(e.duration);}
+histograms.addHistogram(wasmSyncCompileTimeCPU);histograms.addHistogram(wasmSyncCompileTimeWall);}
function computeStreamingBaselineCompileTimeMetric(histograms,wasmEvents){if(!wasmEvents.hasOwnProperty('wasm.StartStreamingCompilation')||!wasmEvents.hasOwnProperty('wasm.BaselineFinished')){return;}
-const histogram=new tr.v.Histogram('v8:wasm:streaming_baseline_compilation:wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);const compilationStart=wasmEvents['wasm.StartStreamingCompilation'][0].start;const compilationEnd=wasmEvents['wasm.BaselineFinished'][0].end;histogram.addSample(compilationEnd-compilationStart);histograms.addHistogram(histogram);}
+const histogram=new tr.v.Histogram('v8:wasm:streaming_baseline_compilation:wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);for(const endEvent of wasmEvents['wasm.BaselineFinished']){const compilationEnd=endEvent.end;const startEvent=wasmEvents['wasm.StartStreamingCompilation'].find(e=>e.args.id===endEvent.args.id);if(!startEvent)continue;const compilationStart=startEvent.start;histogram.addSample(compilationEnd-compilationStart);}
+histograms.addHistogram(histogram);}
function computeCompilationTierupWallTimeMetric(histograms,wasmEvents){if(!wasmEvents.hasOwnProperty('wasm.BaselineFinished')||!wasmEvents.hasOwnProperty('wasm.TopTierFinished')){return;}
-const histogram=new tr.v.Histogram('v8:wasm:compilation_tierup:wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);const tierupStart=wasmEvents['wasm.BaselineFinished'][0].start;const tierupEnd=wasmEvents['wasm.TopTierFinished'][0].end;histogram.addSample(tierupEnd-tierupStart);histograms.addHistogram(histogram);}
+const histogram=new tr.v.Histogram('v8:wasm:compilation_tierup:wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);for(const endEvent of wasmEvents['wasm.TopTierFinished']){const tierupEnd=endEvent.end;const startEvent=wasmEvents['wasm.BaselineFinished'].find(e=>e.args.id===endEvent.args.id);if(!startEvent)continue;const tierupStart=startEvent.start;histogram.addSample(tierupEnd-tierupStart);}
+histograms.addHistogram(histogram);}
function collectWasmEvents(model){const wasmEvents=tr.metrics.v8.utils.filterAndOrderEvents(model,event=>event.title.startsWith('wasm.'),event=>event.title);return wasmEvents;}
-function wasmMetric(histograms,model){const wasmEvents=collectWasmEvents(model);computeSyncInstantiationTimeMetric(histograms,wasmEvents);computeStreamingBaselineCompileTimeMetric(histograms,wasmEvents);computeCompilationTierupWallTimeMetric(histograms,wasmEvents);}
+function wasmMetric(histograms,model){const wasmEvents=collectWasmEvents(model);computeSyncInstantiationTimeMetric(histograms,wasmEvents);computeSyncCompileTimeMetric(histograms,wasmEvents);computeStreamingBaselineCompileTimeMetric(histograms,wasmEvents);computeCompilationTierupWallTimeMetric(histograms,wasmEvents);}
tr.metrics.MetricRegistry.register(wasmMetric);return{wasmMetric,};});'use strict';tr.exportTo('tr.metrics.vr',function(){const VR_GL_THREAD_NAME='VrShellGL';function createHistograms(histograms,name,options,hasCpuTime){const createdHistograms={wall:histograms.createHistogram(name+'_wall',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],options)};if(hasCpuTime){createdHistograms.cpu=histograms.createHistogram(name+'_cpu',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,[],options);}
return createdHistograms;}
function frameCycleDurationMetric(histograms,model,opt_options){const histogramsByEventTitle=new Map();const expectationEvents=tr.importer.VR_EXPECTATION_EVENTS;for(const eventName in expectationEvents){const extraInfo=expectationEvents[eventName];histogramsByEventTitle.set(eventName,createHistograms(histograms,extraInfo.histogramName,{description:extraInfo.description},extraInfo.hasCpuTime));}
@@ -9399,9 +9475,9 @@ const linkEl=tr.ui.b.createLink(link);if(link.href){linkEl.target='_blank';linkE
this.$.links.appendChild(linkEl);}}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-related-event-set-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){Polymer.dom(this).textContent='';const events=new tr.model.EventSet([...this.diagnostic]);const link=document.createElement('tr-ui-a-analysis-link');let label=events.length+' events';if(events.length===1){const event=tr.b.getOnlyElement(events);label=event.title+' ';label+=tr.b.Unit.byName.timeDurationInMs.format(event.duration);}
link.setSelectionAndContent(events,label);Polymer.dom(this).appendChild(link);}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-scalar-diagnostic-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){this.$.scalar.setValueAndUnit(this.diagnostic.value.value,this.diagnostic.value.unit);}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-unmergeable-diagnostic-set-span',behaviors:[tr.v.ui.DIAGNOSTIC_SPAN_BEHAVIOR],updateContents_(){Polymer.dom(this).textContent='';for(const diagnostic of this.diagnostic){if(diagnostic instanceof tr.v.d.RelatedNameMap)continue;const div=document.createElement('div');div.appendChild(tr.v.ui.createDiagnosticSpan(diagnostic,this.name_,this.histogram_));Polymer.dom(this).appendChild(div);}}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){function findElementNameForDiagnostic(diagnostic){let typeInfo=undefined;let curProto=diagnostic.constructor.prototype;while(curProto){typeInfo=tr.v.d.Diagnostic.findTypeInfo(curProto.constructor);if(typeInfo&&typeInfo.metadata.elementName)break;typeInfo=undefined;curProto=curProto.__proto__;}
if(typeInfo===undefined){throw new Error(diagnostic.constructor.name+' or a base class must have a registered elementName');}
-const tagName=typeInfo.metadata.elementName;if(tr.ui.b.isUnknownElementName(tagName)){throw new Error('Element not registered: '+tagName);}
-return tagName;}
-function createDiagnosticSpan(diagnostic,name,histogram){const tagName=findElementNameForDiagnostic(diagnostic);const span=document.createElement(tagName);if(span.build===undefined)throw new Error(tagName);span.build(diagnostic,name,histogram);return span;}
+return typeInfo.metadata.elementName;}
+function createDiagnosticSpan(diagnostic,name,histogram){const tagName=findElementNameForDiagnostic(diagnostic);const span=document.createElement(tagName);if(span instanceof HTMLUnknownElement){throw new Error('Element not registered: '+tagName);}
+if(span.build===undefined)throw new Error(tagName);span.build(diagnostic,name,histogram);return span;}
return{createDiagnosticSpan,};});'use strict';tr.exportTo('tr.v.ui',function(){function makeColumn(title,histogram){return{title,value(map){const diagnostic=map.get(title);if(!diagnostic)return'';return tr.v.ui.createDiagnosticSpan(diagnostic,title,histogram);}};}
Polymer({is:'tr-v-ui-diagnostic-map-table',created(){this.diagnosticMaps_=undefined;this.histogram_=undefined;this.isMetadata_=false;},set histogram(h){this.histogram_=h;},set isMetadata(m){this.isMetadata_=m;this.$.table.showHeader=!this.isMetadata_;},set diagnosticMaps(maps){this.diagnosticMaps_=maps;this.updateContents_();},get diagnosticMaps(){return this.diagnosticMaps_;},updateContents_(){if(this.isMetadata_&&this.diagnosticMaps_.length!==1){throw new Error('Metadata diagnostic-map-tables require exactly 1 DiagnosticMap');}
if(this.diagnosticMaps_===undefined||this.diagnosticMaps_.length===0){this.$.table.tableRows=[];this.$.table.tableColumns=[];return;}
@@ -9730,7 +9806,8 @@ const rowsWithHeadings=[];for(const subGroup of this.group_.viewSubGroups){const
for(let i=0;i<subGroupRows.length;i++){rowsWithHeadings.push({row:subGroupRows[i],heading:(i===0?subGroup.title:'')});}}
this.setPrebuiltSubRows(this.group_,rowsWithHeadings);}};function stripSlice_(slice){if(slice.subSlices!==undefined&&slice.subSlices.length===1){const subSlice=slice.subSlices[0];if(tr.b.math.approximately(subSlice.start,slice.start,1)&&tr.b.math.approximately(subSlice.duration,slice.duration,1)){return subSlice;}}
return slice;}
-function makeLevelSubRows_(slices){const rows=[];const putSlice=(slice,level)=>{while(rows.length<=level){rows.push([]);}
+function makeLevelSubRows_(slices){const rows=[];const putSlice=(slice,level)=>{if(slice.hidden){return;}
+while(rows.length<=level){rows.push([]);}
rows[level].push(slice);};const putSliceRecursively=(slice,level)=>{putSlice(slice,level);if(slice.subSlices!==undefined){for(const subSlice of slice.subSlices){putSliceRecursively(subSlice,level+1);}}};for(const slice of slices){putSliceRecursively(stripSlice_(slice),0);}
return rows;}
function groupAsyncSlicesIntoSubRows(slices,opt_skipSort){if(!opt_skipSort){slices.sort((x,y)=>x.start-y.start);}
@@ -9873,9 +9950,9 @@ this.removeAttribute('expanded');unsupportedLabelEls.push(labelEl);}}
for(const labelEl of unsupportedLabelEls){Polymer.dom(this.tabStrip_).appendChild(labelEl);}
if(previouslyActivePanelType&&supportedPanelTypes.includes(previouslyActivePanelType)){this.activePanelType=previouslyActivePanelType;Polymer.dom(this).setAttribute('expanded',true);}else{if(this.activePanel){Polymer.dom(this.activePanelContainer_).removeChild(this.activePanel);}
Polymer.dom(this).removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range===undefined){throw new Error('Must not be undefined');}
-this.rangeOfInterest_=range;if(this.activePanel){this.activePanel.rangeOfInterest=range;}}});'use strict';Polymer({is:'tr-ui-timeline-view-help-overlay',ready(){const mod=tr.isMac?'cmd ':'ctrl';const spans=Polymer.dom(this.root).querySelectorAll('span.mod');for(let i=0;i<spans.length;i++){Polymer.dom(spans[i]).textContent=mod;}}});'use strict';Polymer({is:'tr-ui-timeline-view-metadata-overlay',created(){this.metadata_=undefined;},ready(){this.$.table.tableColumns=[{title:'name',value:d=>d.name,},{title:'value',value:d=>{const gov=document.createElement('tr-ui-a-generic-object-view');gov.object=d.value;return gov;},}];},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.table.tableRows=this.metadata_;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-v-ui-preferred-display-unit',ready(){this.preferredTimeDisplayMode_=undefined;},attached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},detached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)return;this.preferredTimeDisplayMode_=v;tr.b.Unit.didPreferredTimeDisplayUnitChange();}});'use strict';const POLYFILL_WARNING_MESSAGE='Trace Viewer is running with WebComponentsV0 polyfill, and some '+'features may be broken. As a workaround, you may try running chrome '+'with "--enable-blink-features=ShadowDOMV0,CustomElementsV0,HTMLImports" '+'flag. See crbug.com/1036492.';Polymer({is:'tr-ui-timeline-view',created(){this.trackViewContainer_=undefined;this.queuedModel_=undefined;this.builtPromise_=undefined;this.doneBuilding_=undefined;},attached(){this.async(function(){this.trackViewContainer_=Polymer.dom(this).querySelector('#track_view_container');if(!this.trackViewContainer_){throw new Error('missing trackviewContainer');}
+this.rangeOfInterest_=range;if(this.activePanel){this.activePanel.rangeOfInterest=range;}}});'use strict';Polymer({is:'tr-ui-timeline-view-help-overlay',ready(){const mod=tr.isMac?'cmd ':'ctrl';const spans=Polymer.dom(this.root).querySelectorAll('span.mod');for(let i=0;i<spans.length;i++){Polymer.dom(spans[i]).textContent=mod;}}});'use strict';Polymer({is:'tr-ui-timeline-view-metadata-overlay',created(){this.metadata_=undefined;},ready(){this.$.table.tableColumns=[{title:'name',value:d=>d.name,},{title:'value',value:d=>{const gov=document.createElement('tr-ui-a-generic-object-view');gov.object=d.value;return gov;},}];},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.table.tableRows=this.metadata_;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-v-ui-preferred-display-unit',ready(){this.preferredTimeDisplayMode_=undefined;},attached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},detached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)return;this.preferredTimeDisplayMode_=v;tr.b.Unit.didPreferredTimeDisplayUnitChange();}});'use strict';const POLYFILL_WARNING_MESSAGE='Trace Viewer is running with WebComponentsV0 polyfill, and some '+'features may be broken. See crbug.com/1036492.';Polymer({is:'tr-ui-timeline-view',created(){this.trackViewContainer_=undefined;this.queuedModel_=undefined;this.builtPromise_=undefined;this.doneBuilding_=undefined;},attached(){this.async(function(){this.trackViewContainer_=Polymer.dom(this).querySelector('#track_view_container');if(!this.trackViewContainer_){throw new Error('missing trackviewContainer');}
if(this.queuedModel_)this.updateContents_();});},ready(){this.tabIndex=0;this.polyfillWarnedOnce_=false;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.metrics&&window.tr.metrics.sh&&window.tr.metrics.sh.SystemHealthMetric){this.railScoreSpan_=document.createElement('tr-metrics-ui-sh-system-health-span');Polymer.dom(this.rightControls).appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
-this.flowEventFilter_=this.$.flow_event_filter_dropdown;this.processFilter_=this.$.process_filter_dropdown;this.optionsDropdown_=this.$.view_options_dropdown;this.selectedFlowEvents_=new Set();this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');Polymer.dom(this.optionsDropdown_).appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();Polymer.dom(this.collapsingControls).appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){const sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},warnPolyfill(){if(this.polyfillWarnedOnce_)return;console.warn(POLYFILL_WARNING_MESSAGE);this.polyfillWarnedOnce_=true;if(!window.__hideTraceViewerPolyfillWarning){const polyfillWarningsEl=Polymer.dom(this.root).querySelector('#polyfill-warning');polyfillWarningsEl.addMessage(POLYFILL_WARNING_MESSAGE,[{buttonText:'Hide',onClick:()=>polyfillWarningsEl.clearMessages()}]);}},updateDocumentFavicon(){let hue;if(!this.model){hue='blue';}else{hue=this.model.faviconHue;}
+this.flowEventFilter_=this.$.flow_event_filter_dropdown;this.processFilter_=this.$.process_filter_dropdown;this.optionsDropdown_=this.$.view_options_dropdown;this.selectedFlowEvents_=new Set();this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');Polymer.dom(this.optionsDropdown_).appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();Polymer.dom(this.collapsingControls).appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){const sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},warnPolyfill(){if(this.polyfillWarnedOnce_)return;console.warn(POLYFILL_WARNING_MESSAGE);this.polyfillWarnedOnce_=true;},updateDocumentFavicon(){let hue;if(!this.model){hue='blue';}else{hue=this.model.faviconHue;}
let faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined){faviconData=tr.ui.b.FaviconsByHue.blue;}
let link=Polymer.dom(document.head).querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';Polymer.dom(document.head).appendChild(link);}
link.href=faviconData;},get selectedFlowEvents(){return this.selectedFlowEvents_;},set selectedFlowEvents(selectedFlowEvents){this.selectedFlowEvents_=selectedFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_(){const helpButtonEl=this.$.view_help_button;const dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.visible=false;dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));function onClick(e){dlg.visible=!dlg.visible;e.stopPropagation();}
@@ -9954,7 +10031,8 @@ if(metadata.name==='metadata'&&metadata.value&&metadata.value['trace-config']&&m
if(config){return{excluded:config.excluded_categories||[],included:config.included_categories||[],};}}}
function validateTraceCategories(requiredCategories,categories){if(!requiredCategories)return;if(!categories)throw new Error('Missing trace config metadata');for(const cat of requiredCategories){const isDisabledByDefault=(cat.indexOf('disabled-by-default')===0);let missing=false;if(isDisabledByDefault){if(!categories.included.includes(cat)){missing=true;}}else if(categories.excluded.includes(cat)){missing=true;}
if(missing){throw new Error(`Trace is missing required category "${cat}"`);}}}
-function validateDiagnosticNames(histograms){for(const hist of histograms){for(const name of hist.diagnostics.keys()){if(tr.v.d.RESERVED_NAMES_SET.has(name)){throw new Error(`Illegal diagnostic name "${name}" on Histogram "${hist.name}"`);}}}}
+function validateDiagnosticNames(histograms){for(const hist of histograms){for(const name of hist.diagnostics.keys()){if(name===tr.v.d.RESERVED_NAMES.ALERT_GROUPING){continue;}
+if(tr.v.d.RESERVED_NAMES_SET.has(name)){throw new Error(`Illegal diagnostic name "${name}" on Histogram "${hist.name}"`);}}}}
function addTelemetryInfo(histograms,model){for(const metadata of model.metadata){if(!metadata.value||!metadata.value.telemetry)continue;for(const[name,value]of Object.entries(metadata.value.telemetry)){const type=tr.v.d.RESERVED_NAMES_TO_TYPES.get(name);if(type===undefined){throw new Error(`Unexpected telemetry.${name}`);}
histograms.addSharedDiagnosticToAllHistograms(name,new type(value));}}}
function metricMapFunction(result,model,options){const histograms=runMetrics(model,options,result.addFailure.bind(result));addTelemetryInfo(histograms,model);if(model.canonicalUrl!==undefined){const info=tr.v.d.RESERVED_INFOS.TRACE_URLS;histograms.addSharedDiagnosticToAllHistograms(info.name,new info.type([model.canonicalUrl]));}
diff --git a/catapult/systrace/systrace/tracing_agents/atrace_agent.py b/catapult/systrace/systrace/tracing_agents/atrace_agent.py
index 95046850..05c4330d 100644
--- a/catapult/systrace/systrace/tracing_agents/atrace_agent.py
+++ b/catapult/systrace/systrace/tracing_agents/atrace_agent.py
@@ -104,7 +104,8 @@ def try_create_agent(config):
'Your device SDK version is %d.' % device_sdk_version)
return None
- return AtraceAgent(device_sdk_version, util.get_tracing_path())
+ return AtraceAgent(device_sdk_version,
+ util.get_tracing_path(config.device_serial_number))
def _construct_extra_atrace_args(config, categories):
"""Construct extra arguments (-a, -k, categories) for atrace command.
diff --git a/catapult/systrace/systrace/util.py b/catapult/systrace/systrace/util.py
index 02981458..063f9ed9 100644
--- a/catapult/systrace/systrace/util.py
+++ b/catapult/systrace/systrace/util.py
@@ -52,7 +52,7 @@ def run_adb_shell(shell_args, device_serial):
return (adb_output, adb_return_code)
-def get_tracing_path():
+def get_tracing_path(device_serial=None):
"""Uses adb to attempt to determine tracing path. The newest kernel doesn't
support mounting debugfs, so the Android master uses tracefs to replace it.
@@ -62,12 +62,14 @@ def get_tracing_path():
/sys/kernel/debug/tracing if support can't be determined.
"""
mount_info_args = ['mount']
- parser = OptionParserIgnoreErrors()
- parser.add_option('-e', '--serial', dest='device_serial', type='string')
- options, _ = parser.parse_args()
- adb_output, adb_return_code = run_adb_shell(mount_info_args,
- options.device_serial)
+ if device_serial is None:
+ parser = OptionParserIgnoreErrors()
+ parser.add_option('-e', '--serial', dest='device_serial', type='string')
+ options, _ = parser.parse_args()
+ device_serial = options.device_serial
+
+ adb_output, adb_return_code = run_adb_shell(mount_info_args, device_serial)
if adb_return_code == 0 and 'debugfs' not in adb_output:
return '/sys/kernel/tracing'
return '/sys/kernel/debug/tracing'