diff --git a/DEPS b/DEPS index a343726..03d7e5e 100644 --- a/DEPS +++ b/DEPS
@@ -299,15 +299,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '504ccf45fba464bf74b396cc686494629f37b718', + 'skia_revision': 'c1407387eeaf31674891a4d12505970d3237e86f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '5532a667175e9b1a2597111ab674e8ba09c8d505', + 'v8_revision': 'a6505e5f6d22a63788a3ee59f44ca539774fbe4c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'f5f6704c1cf00faa87a8b55eec0988600a8128e6', + 'angle_revision': '8d75490aa47bc2be90e8b1bbeaae495bdf0a37e9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -319,7 +319,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. - 'boringssl_revision': '62956948e445c5bc67d3f299e0003c34a3030523', + 'boringssl_revision': '02bc0949e5cac0e1ee82c6f365f5a6c3cfd0cfa9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. @@ -371,7 +371,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'bbb14e46563c14a055b394f18b117e504e98d4ab', + 'catapult_revision': '2fa93b2332b7a27c3066bef8d7ba9de2a5e1ab2e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. @@ -415,7 +415,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '3ae10bb874bd495b9334b42a1c1bddec00ec53cb', + 'dawn_revision': 'e9424a009a62bacb7ba8e027bf7c8c3de4fb19d9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -451,7 +451,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling crabbyavif # and whatever else without interference from each other. - 'crabbyavif_revision': '02d0fad2c512380b7270d6e704c86521075d7d54', + 'crabbyavif_revision': 'b097e11df62db2a6b8561f60aeae0718901122cb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Speedometer main # and whatever else without interference from each other. @@ -519,7 +519,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling llvm-libc # and whatever else without interference from each other. - 'llvm_libc_revision': '27ee0730164e6f101985f057c6ad23a9ba7710f6', + 'llvm_libc_revision': '9aefa1cede964571c0b0ef41460cc5c3bbc6b4b8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling llvm-libc # and whatever else without interference from each other. @@ -837,143 +837,143 @@ 'objects': [ { # The Android libclang_rt.builtins libraries are currently only included in the Linux clang package. - 'object_name': 'Linux_x64/clang-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': 'dee83e0a8b35564c277a7902a7872a77f4170b4380f9053acd3e1cb9a502a69c', - 'size_bytes': 55555048, - 'generation': 1746105739973602, + 'object_name': 'Linux_x64/clang-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '5f69279b3697166facfc354634157e0a8a32fa6e36864200ad8a8f85add3f3f6', + 'size_bytes': 55654416, + 'generation': 1747138963230938, 'condition': '(host_os == "linux" or checkout_android) and non_git_source', }, { - 'object_name': 'Linux_x64/clang-tidy-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': 'bb8684fb985a35cc680bda9161735c409e6409106497f4ec0253ff9e07dd6912', - 'size_bytes': 13555996, - 'generation': 1746105739988254, + 'object_name': 'Linux_x64/clang-tidy-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '9c9cd089b46f36232d7553d03a0b30cf509f5e42b2113fe8172ba14f905b91df', + 'size_bytes': 13597708, + 'generation': 1747138963497696, 'condition': 'host_os == "linux" and checkout_clang_tidy and non_git_source', }, { - 'object_name': 'Linux_x64/clangd-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '5074d634984fa526b868126ead41c013de337edf36b369422005cb4a0edb95dc', - 'size_bytes': 13762680, - 'generation': 1746105740081588, + 'object_name': 'Linux_x64/clangd-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': 'cf580450a46e262d899c2d48fff2b6ea8f6691a6bcfc0c280f87d8b6da088e5f', + 'size_bytes': 13854788, + 'generation': 1747138963598582, 'condition': 'host_os == "linux" and checkout_clangd and non_git_source', }, { - 'object_name': 'Linux_x64/llvm-code-coverage-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': 'fa46a9d107f515d0a16c41ae5751a2a4be7be34a550f315a1506fcfb17327936', - 'size_bytes': 2294512, - 'generation': 1746105740273331, + 'object_name': 'Linux_x64/llvm-code-coverage-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '1a3488e55d62bda48d09b69fb4e5267ac64247258dc51fd9dabdb7fe5d66da4c', + 'size_bytes': 2297996, + 'generation': 1747138964068040, 'condition': 'host_os == "linux" and checkout_clang_coverage_tools and non_git_source', }, { - 'object_name': 'Linux_x64/llvmobjdump-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '4041ca56834653e78338f50aa6590c8160bc6b522bdcddbd533027d9116e4994', - 'size_bytes': 5694452, - 'generation': 1746105740224915, + 'object_name': 'Linux_x64/llvmobjdump-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': 'efb127c69ac198284ff3622cd173e9dc4839d0bed33dbcaa96501db169607a2e', + 'size_bytes': 5701128, + 'generation': 1747138963789285, 'condition': '((checkout_linux or checkout_mac or checkout_android) and host_os == "linux") and non_git_source', }, { - 'object_name': 'Mac/clang-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '5ee059eddd55064d3e638b83db4c7843f5448bb74c62c474b5f5652a5631cb85', - 'size_bytes': 51962684, - 'generation': 1746105741728605, + 'object_name': 'Mac/clang-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '3d83bd33ae0a0331ba8e23340023ae05174128503d94116cd8a855913fca88c7', + 'size_bytes': 52212572, + 'generation': 1747138966013176, 'condition': 'host_os == "mac" and host_cpu == "x64"', }, { - 'object_name': 'Mac/clang-mac-runtime-library-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '8482f9c688466057de438a15ff01d62ea1f0e2b709f3e7a470cdd452c81da731', - 'size_bytes': 989704, - 'generation': 1746105749642530, + 'object_name': 'Mac/clang-mac-runtime-library-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '809b6f72718d9bcbf25ad6ab80517f215ed2526435a095ee9bceb5ed40f989a2', + 'size_bytes': 993800, + 'generation': 1747138984414942, 'condition': 'checkout_mac and not host_os == "mac"', }, { - 'object_name': 'Mac/clang-tidy-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': 'e23d1a41409e2637f662cb9306d3269ea1c4f41ae1aa70f14369b6463de95c03', - 'size_bytes': 13610744, - 'generation': 1746105741733748, + 'object_name': 'Mac/clang-tidy-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': 'c1fd7930eadede03470cbc8d38697669c6254069da2f6bd58328a8654d68f70d', + 'size_bytes': 13699584, + 'generation': 1747138966324770, 'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clang_tidy', }, { - 'object_name': 'Mac/clangd-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '6921b4b53cdf8bc80fcad184e229c4f38a49463390016eed65f12fa547f24950', - 'size_bytes': 14998636, - 'generation': 1746105741782145, + 'object_name': 'Mac/clangd-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '3aa82177f6e03da693d93aa9f8052fa669af1bd897359a20eaf01379db0924b8', + 'size_bytes': 15136432, + 'generation': 1747138966446697, 'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clangd', }, { - 'object_name': 'Mac/llvm-code-coverage-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '0b41a82139b4a107f1a2a149d438b600685cbab5c0f81c8d0459f2711503460b', - 'size_bytes': 2263096, - 'generation': 1746105741945685, + 'object_name': 'Mac/llvm-code-coverage-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '1f8d0d65f9d027707890c28433b0bfe29e32551008e9f3c1b9803318ede2bfc6', + 'size_bytes': 2272500, + 'generation': 1747138966854415, 'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clang_coverage_tools', }, { - 'object_name': 'Mac_arm64/clang-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '99c31f2e700274ade6b25205597510a5c665f17dd9ddaa03b89c9659ec387fd4', - 'size_bytes': 43999184, - 'generation': 1746105751053626, + 'object_name': 'Mac_arm64/clang-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '2d5660c50637a7ee6e5501525e7588bb255cdfd48e792b12b86ae7113c31b8ae', + 'size_bytes': 44214476, + 'generation': 1747138986010150, 'condition': 'host_os == "mac" and host_cpu == "arm64"', }, { - 'object_name': 'Mac_arm64/clang-tidy-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '78280eb8dceeaa330fb53ec8249c740db0f369f3b6d6857c65337dc5a21b3160', - 'size_bytes': 11773472, - 'generation': 1746105751166820, + 'object_name': 'Mac_arm64/clang-tidy-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': 'c17b6d7d112ff54699477d5fc7f5009e7b650d263d127cad4f8406f8df914996', + 'size_bytes': 11838956, + 'generation': 1747138986259606, 'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clang_tidy', }, { - 'object_name': 'Mac_arm64/clangd-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': 'f2de67c31e6ce01485b4cc0a76567809319021c4523609b93ab1804252f95ddc', - 'size_bytes': 12044048, - 'generation': 1746105751239361, + 'object_name': 'Mac_arm64/clangd-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': 'd6c134df8273fe9c4c2b5ff5786f2ceeb9ed5f251e223e55edbc0cd7aa772e83', + 'size_bytes': 12115024, + 'generation': 1747138986359326, 'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clangd', }, { - 'object_name': 'Mac_arm64/llvm-code-coverage-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': 'a2c44380d13276f1c3393abff82e8d397c893a912b157bea44b0006bd35fe618', - 'size_bytes': 1974668, - 'generation': 1746105751515503, + 'object_name': 'Mac_arm64/llvm-code-coverage-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '82ca9187d1fd5ed14266612339b921d560b1008f92e1719255b755ff882d23e3', + 'size_bytes': 1982036, + 'generation': 1747138986831545, 'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clang_coverage_tools', }, { - 'object_name': 'Win/clang-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '9362a0993354be586748f4148493e2b9cc63a898aa85fea301f2de0e60ecbd93', - 'size_bytes': 47049060, - 'generation': 1746105761436952, + 'object_name': 'Win/clang-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '39e17b8282b9f1e3cbc6b22d3144696728c867f3ae66694b0125c3ed60755401', + 'size_bytes': 47250032, + 'generation': 1747139012194774, 'condition': 'host_os == "win"', }, { - 'object_name': 'Win/clang-tidy-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': 'c55a73aa688dfa2e6195b1dc233079504f1ed9a95c8e8a92582add133bb8a240', - 'size_bytes': 13414380, - 'generation': 1746105761440911, + 'object_name': 'Win/clang-tidy-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '9dec82a917bd55947e39891137ba5c13663ca94d2c102d56eb52b9b176365910', + 'size_bytes': 13492960, + 'generation': 1747139012510054, 'condition': 'host_os == "win" and checkout_clang_tidy', }, { - 'object_name': 'Win/clang-win-runtime-library-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': 'c42cfa237dbd6841d61013051de739775fe0ae3187ff5fecc7ed243de2941da6', - 'size_bytes': 2484424, - 'generation': 1746105769629959, + 'object_name': 'Win/clang-win-runtime-library-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '220abd9ce9a85446a2e7879aab3c1f2f5393665f6b13b067f8cec565ae7d36eb', + 'size_bytes': 2486856, + 'generation': 1747139033547001, 'condition': 'checkout_win and not host_os == "win"', }, { - 'object_name': 'Win/clangd-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': 'fcf5bfeccbca8a2445d579093c9d7da87dff142b223f24f25d87f6e2e6e15c50', - 'size_bytes': 13840260, - 'generation': 1746105761501287, + 'object_name': 'Win/clangd-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '81fa230b6311e3e50147cae3acd6d2c83c1bef13ff46df3df3d580ca911e9d15', + 'size_bytes': 13918432, + 'generation': 1747139013351355, 'condition': 'host_os == "win" and checkout_clangd', }, { - 'object_name': 'Win/llvm-code-coverage-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '1a5e31c5e69ea7b84fdfbff27024670cf2eec538c68fc4213a5bcf576263b0ca', - 'size_bytes': 2370540, - 'generation': 1746105761636379, + 'object_name': 'Win/llvm-code-coverage-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '611b9689c3d3e80ab7485e698f6b67e0df328b5407f30f177c29fe394b81a13e', + 'size_bytes': 2378584, + 'generation': 1747139013764369, 'condition': 'host_os == "win" and checkout_clang_coverage_tools', }, { - 'object_name': 'Win/llvmobjdump-llvmorg-21-init-9266-g09006611-2.tar.xz', - 'sha256sum': '3ac42a8e816d1fa89594bfe882d033b6c351551b055b9d78867a2b3d24ac2451', - 'size_bytes': 5698696, - 'generation': 1746105761558030, + 'object_name': 'Win/llvmobjdump-llvmorg-21-init-11777-gfd3fecfc-1.tar.xz', + 'sha256sum': '67a05210ee38b2f575df3cc1feb04ed36b4186748c2d769e2201572b413305fe', + 'size_bytes': 5698204, + 'generation': 1747139013159526, 'condition': '(checkout_linux or checkout_mac or checkout_android) and host_os == "win"', }, ] @@ -984,31 +984,31 @@ 'bucket': 'chromium-browser-clang', 'objects': [ { - 'object_name': 'Linux_x64/rust-toolchain-c8f94230282a8e8c1148f3e657f0199aad909228-1-llvmorg-21-init-9266-g09006611.tar.xz', - 'sha256sum': '378c432f7739bb5da11aad7b3a2687f8252565eae5f0dcfc55c39a15382c519c', - 'size_bytes': 118598336, - 'generation': 1745271335898717, + 'object_name': 'Linux_x64/rust-toolchain-4a0969e06dbeaaa43914d2d00b2e843d49aa3886-1-llvmorg-21-init-11777-gfd3fecfc.tar.xz', + 'sha256sum': 'df1573701599cb7d00c1050b71636a436320b8ad47bb09cb46d6e96b3f8ac585', + 'size_bytes': 118529212, + 'generation': 1747160498430964, 'condition': 'host_os == "linux" and non_git_source', }, { - 'object_name': 'Mac/rust-toolchain-c8f94230282a8e8c1148f3e657f0199aad909228-1-llvmorg-21-init-9266-g09006611.tar.xz', - 'sha256sum': 'bf05c8b5e90d6904de02dca9b3e4cb5e45a1a56207e7af1fbb3a10707704a26a', - 'size_bytes': 111932536, - 'generation': 1745271337336068, + 'object_name': 'Mac/rust-toolchain-4a0969e06dbeaaa43914d2d00b2e843d49aa3886-1-llvmorg-21-init-11777-gfd3fecfc.tar.xz', + 'sha256sum': '83836493c8a81b212c20e16666c6b918bff28748f4d6685c5107eb7e9d16f6fe', + 'size_bytes': 111691772, + 'generation': 1747160500088595, 'condition': 'host_os == "mac" and host_cpu == "x64"', }, { - 'object_name': 'Mac_arm64/rust-toolchain-c8f94230282a8e8c1148f3e657f0199aad909228-1-llvmorg-21-init-9266-g09006611.tar.xz', - 'sha256sum': '1aec99f479ff28cefe44ed739844833e016a1da255cf3c17d79e59a273246615', - 'size_bytes': 101605468, - 'generation': 1745271339727037, + 'object_name': 'Mac_arm64/rust-toolchain-4a0969e06dbeaaa43914d2d00b2e843d49aa3886-1-llvmorg-21-init-11777-gfd3fecfc.tar.xz', + 'sha256sum': 'd975e322a2e5c680b54f27a6545c63c0de2c5367ca6ffefda04de491d6b76553', + 'size_bytes': 102206348, + 'generation': 1747160501743827, 'condition': 'host_os == "mac" and host_cpu == "arm64"', }, { - 'object_name': 'Win/rust-toolchain-c8f94230282a8e8c1148f3e657f0199aad909228-1-llvmorg-21-init-9266-g09006611.tar.xz', - 'sha256sum': 'b291520613a3ebc415e4576a7fa31d840a5ebf4ab9be6e9dc5d90062dc001c1e', - 'size_bytes': 193280372, - 'generation': 1745271341223097, + 'object_name': 'Win/rust-toolchain-4a0969e06dbeaaa43914d2d00b2e843d49aa3886-1-llvmorg-21-init-11777-gfd3fecfc.tar.xz', + 'sha256sum': '25c51b4c2e0e8b4e974973f0357b12ecb645a0a7a136f9e0a6604e87c21acc7a', + 'size_bytes': 193582440, + 'generation': 1747160503376785, 'condition': 'host_os == "win"', }, ], @@ -1486,7 +1486,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '2135957a97f443f1db1b70e4379f0d808684e977', + '458624d042c10f66119db1ede7220e141e4eda26', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1978,7 +1978,7 @@ 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a9cc320bf761323906c614f7040cb1dc22fcc858', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c273e3eb6202ef710a9cbf48fc99437a56a13631', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -4424,7 +4424,7 @@ 'src/chrome/browser/glic/resources/internal': { 'url': Var('chrome_git') + '/chrome/browser/glic/resources/internal.git' + '@' + - 'aeb59fb12f8363ded7b2f1052956e538808c5daf', + '3784a743ccebd82808a50e14e99db28643e95bac', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/test/data/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/android_webview/test/data/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index c8e9897..f598597 100644 --- a/android_webview/test/data/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/android_webview/test/data/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -1244,6 +1244,11 @@ getter highWaterMark getter size method constructor +interface CreateMonitor : EventTarget + attribute @@toStringTag + getter ondownloadprogress + method constructor + setter ondownloadprogress interface Credential attribute @@toStringTag getter id @@ -5129,6 +5134,16 @@ setter composite setter pseudoElement setter target +interface LanguageDetector + static method availability + static method create + attribute @@toStringTag + getter expectedInputLanguages + getter inputQuota + method constructor + method destroy + method detect + method measureInputUsage interface LargestContentfulPaint : PerformanceEntry attribute @@toStringTag getter element
diff --git a/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt b/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt index bffbfe5..2dc3cfb 100644 --- a/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt +++ b/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt
@@ -7292,6 +7292,11 @@ attribute @@toStringTag method constructor method queryFeatureSupport +interface QuotaExceededError : DOMException + attribute @@toStringTag + getter quota + getter requested + method constructor interface RTCCertificate attribute @@toStringTag getter expires
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc index 2ae8f4c8..3a6b791 100644 --- a/ash/capture_mode/capture_mode_controller.cc +++ b/ash/capture_mode/capture_mode_controller.cc
@@ -711,8 +711,7 @@ : nullptr; } -void CaptureModeController::ShowSearchResultsPanel( - const gfx::ImageSkia& image) { +void CaptureModeController::ShowSearchResultsPanel() { // We should not use `CanShowSunfishUi` here, as that could change between // sending the region and receiving a URL (for example, if the Sunfish policy // changes). @@ -759,13 +758,6 @@ } // Note at this point the session may no longer be active. - auto* search_results_panel = GetSearchResultsPanel(); - // The Lens Web API implementation has its own searchbox, so there's no need - // to set the thumbnail image. - if (!features::IsSunfishLensWebEnabled()) { - search_results_panel->SetSearchBoxImage(image); - } - if (should_end_session) { Stop(); } @@ -807,13 +799,6 @@ void CaptureModeController::OnLocatedEventDragged() { if (IsSearchResultsPanelVisible()) { - // Clear the search box text for the next time the panel is opened. Note we - // don't need to reset the image or URL since the panel will always be - // re-opened with those. Only necessary if the Lens Web API implementation - // is not enabled and we are still using the native search box. - if (!features::IsSunfishLensWebEnabled()) { - GetSearchResultsPanel()->SetSearchBoxText(std::u16string()); - } search_results_panel_widget_->Hide(); } } @@ -2070,8 +2055,6 @@ return; } - gfx::ImageSkia image_skia = gfx::ImageSkia(); - if (features::IsSunfishLensWebEnabled()) { const gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmap); const bool is_standalone_session = capture_mode_session_->active_behavior()->behavior_type() == @@ -2086,24 +2069,11 @@ base::BindRepeating(&CaptureModeController::OnLensWebError, weak_ptr_factory_.GetWeakPtr(), image_search_token)); - } else { - image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); - // `OnSearchUrlFetched()` will be invoked with `image` when the server - // response is fetched. - delegate_->SendRegionSearch( - bitmap, user_capture_region_, - base::BindRepeating(&CaptureModeController::OnSearchUrlFetched, - weak_ptr_factory_.GetWeakPtr(), - user_capture_region_, image_skia), - base::BindRepeating(&CaptureModeController::OnLensTextDetectionComplete, - weak_ptr_factory_.GetWeakPtr(), - image_search_token)); - } // Immediately show the search results panel, with a loading animation in // place of the web contents. We will replace it once we receive the URL from // the server. - ShowSearchResultsPanel(image_skia); + ShowSearchResultsPanel(); } void CaptureModeController::OnTextDetectionComplete(
diff --git a/ash/capture_mode/capture_mode_controller.h b/ash/capture_mode/capture_mode_controller.h index 06af9617..59cf270 100644 --- a/ash/capture_mode/capture_mode_controller.h +++ b/ash/capture_mode/capture_mode_controller.h
@@ -151,9 +151,8 @@ // Returns the search results panel, or nullptr if none exists. SearchResultsPanel* GetSearchResultsPanel() const; - // Shows the results panel. `image` is only needed for the thumbnail if the - // Lens Web feature flag is disabled. - void ShowSearchResultsPanel(const gfx::ImageSkia& image); + // Shows the results panel. + void ShowSearchResultsPanel(); // Navigates the Sunfish search results panel to the given URL, if the panel // is available.
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc index 2d686a49..21b334c8 100644 --- a/ash/capture_mode/capture_mode_session.cc +++ b/ash/capture_mode/capture_mode_session.cc
@@ -1801,16 +1801,14 @@ return; } - // If the search results panel is visible, and the textfield has - // pseudo focus or the panel is actually focused, we will let the search - // results panel handle key events (i.e., pressing Enter/Return to make a - // multimodal search) until it calls `TakeFocus` to return focus back to the - // focus cycler. As an exception, pressing ESC can still be used to exit the - // session. + // If the search results panel is visible, and the panel is actually focused, + // we will let the search results panel handle key events (i.e., pressing + // Enter/Return to make a multimodal search) until it calls `TakeFocus` to + // return focus back to the focus cycler. As an exception, pressing ESC can + // still be used to exit the session. ui::KeyboardCode key_code = event->key_code(); if (controller_->IsSearchResultsPanelVisible() && - (controller_->GetSearchResultsPanel()->IsTextfieldPseudoFocused() || - controller_->GetSearchResultsPanel()->HasFocus()) && + controller_->GetSearchResultsPanel()->HasFocus() && key_code != ui::VKEY_ESCAPE) { return; }
diff --git a/ash/capture_mode/search_results_panel.cc b/ash/capture_mode/search_results_panel.cc index 2d71f681..6626038 100644 --- a/ash/capture_mode/search_results_panel.cc +++ b/ash/capture_mode/search_results_panel.cc
@@ -34,8 +34,6 @@ #include "ui/views/controls/focus_ring.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" -#include "ui/views/controls/textfield/textfield.h" -#include "ui/views/controls/textfield/textfield_controller.h" #include "ui/views/focus/focus_manager.h" #include "ui/views/layout/flex_layout_view.h" #include "ui/views/widget/widget_delegate.h" @@ -50,16 +48,8 @@ const std::u16string kSearchBoxPlaceholderText = u"Add to your search"; inline constexpr gfx::Insets kPanelPadding = gfx::Insets(capture_mode::kPanelPaddingSize); -inline constexpr int kSearchBoxHeight = 48; -inline constexpr int kSearchBoxRadius = 24; -inline constexpr int kSearchBoxImageRadius = 8; -inline constexpr gfx::Insets kSearchBoxViewSpacing = gfx::Insets::VH(12, 0); inline constexpr gfx::Insets kSearchResultsViewSpacing = gfx::Insets::TLBR(12, 0, 0, 0); -inline constexpr gfx::Insets kSearchImageSpacing = - gfx::Insets::TLBR(8, 16, 8, 12); -inline constexpr gfx::Insets kSearchTextfieldSpacing = - gfx::Insets::TLBR(14, 0, 14, 16); // Returns the target container window for the panel widget. aura::Window* GetParentContainer(aura::Window* root, bool is_active) { @@ -75,104 +65,6 @@ } // namespace -// TODO: crbug.com/377764351 - Fix the textfield being too far to the left when -// the region is very narrow (height >> width). -// `SunfishSearchBoxView` contains an image thumbnail and a textfield. -class SunfishSearchBoxView : public views::View, - public views::TextfieldController { - METADATA_HEADER(SunfishSearchBoxView, views::View) - - public: - SunfishSearchBoxView() { - SetLayoutManager(std::make_unique<views::FlexLayout>()) - ->SetOrientation(views::LayoutOrientation::kHorizontal) - .SetMainAxisAlignment(views::LayoutAlignment::kStart) - .SetCrossAxisAlignment(views::LayoutAlignment::kStretch) - .SetCollapseMargins(true); - // TODO(b/356878705): Replace with the captured region screenshot when the - // backend is hooked up. Currently using the search icon as a placeholder. - AddChildView(views::Builder<views::ImageView>() - .CopyAddressTo(&image_view_) - .SetImage(ui::ImageModel::FromVectorIcon( - vector_icons::kGoogleColorIcon)) - .SetProperty(views::kMarginsKey, kSearchImageSpacing) - .Build()); - AddChildView( - views::Builder<views::Textfield>() - .CopyAddressTo(&textfield_) - .SetController(this) - .SetTextInputType(ui::TEXT_INPUT_TYPE_TEXT) - .SetPlaceholderText(kSearchBoxPlaceholderText) - .SetFontList(TypographyProvider::Get()->ResolveTypographyToken( - TypographyToken::kCrosBody2)) - .SetProperty(views::kMarginsKey, kSearchTextfieldSpacing) - .SetProperty(views::kFlexBehaviorKey, - views::FlexSpecification( - views::LayoutOrientation::kHorizontal, - views::MinimumFlexSizeRule::kPreferred, - views::MaximumFlexSizeRule::kUnbounded)) - .SetBackgroundEnabled(false) - .SetBorder(nullptr) - .Build()); - - SetBackground(views::CreateRoundedRectBackground( - cros_tokens::kCrosSysSystemOnBase1, kSearchBoxRadius)); - - SetPreferredSize(gfx::Size(capture_mode::kSearchResultsPanelWebViewWidth, - kSearchBoxHeight)); - - image_view_->SetPaintToLayer(); - image_view_->layer()->SetFillsBoundsOpaquely(false); - image_view_->layer()->SetRoundedCornerRadius( - gfx::RoundedCornersF(kSearchBoxImageRadius)); - } - SunfishSearchBoxView(const SunfishSearchBoxView&) = delete; - SunfishSearchBoxView& operator=(const SunfishSearchBoxView&) = delete; - ~SunfishSearchBoxView() override = default; - - void SetImage(const gfx::ImageSkia& image) { - if (image.isNull()) { - return; - } - // Resize the image to fit in the searchbox, keeping the same aspect ratio. - const int target_height = height(); - const int target_width = (image.width() * target_height) / image.height(); - image_view_->SetImage(ui::ImageModel::FromImageSkia(image)); - image_view_->SetImageSize(gfx::Size(target_width, target_height)); - } - - // views::TextfieldController: - bool HandleKeyEvent(views::Textfield* sender, - const ui::KeyEvent& event) override { - if (sender->GetText().empty()) { - return false; - } - - if (!textfield_->HasFocus()) { - return false; - } - - if (event.type() == ui::EventType::kKeyPressed && - event.key_code() == ui::VKEY_RETURN) { - CaptureModeController::Get()->SendMultimodalSearch( - image_view_->GetImage(), base::UTF16ToUTF8(sender->GetText())); - return true; - } - - return false; - } - - private: - friend class SearchResultsPanel; - - // Owned by the views hierarchy. - raw_ptr<views::ImageView> image_view_; - raw_ptr<views::Textfield> textfield_; -}; - -BEGIN_METADATA(SunfishSearchBoxView) -END_METADATA - SearchResultsPanel::SearchResultsPanel() { // We should not use `CanShowSunfishUi` here, as that could change between // sending the region and receiving a URL which will then create this view @@ -222,13 +114,6 @@ .WithAlignment(views::LayoutAlignment::kEnd))) .Build()); - // Lens Web API uses its own sticky search box, so there's no need to create a - // native one. - if (!features::IsSunfishLensWebEnabled()) { - search_box_view_ = AddChildView(std::make_unique<SunfishSearchBoxView>()); - search_box_view_->SetProperty(views::kMarginsKey, kSearchBoxViewSpacing); - } - SetBackground(views::CreateRoundedRectBackground( cros_tokens::kCrosSysSystemBaseElevated, kPanelCornerRadius)); SetPaintToLayer(); @@ -254,14 +139,6 @@ CaptureModeSessionFocusCycler::HighlightHelper::Install(animation_view); CaptureModeSessionFocusCycler::HighlightHelper::Get(animation_view) ->SetUpFocusPredicate(); - - if (!features::IsSunfishLensWebEnabled()) { - CaptureModeSessionFocusCycler::HighlightHelper::Install( - search_box_view_->textfield_); - CaptureModeSessionFocusCycler::HighlightHelper::Get( - search_box_view_->textfield_) - ->SetUpFocusPredicate(); - } } SearchResultsPanel::~SearchResultsPanel() = default; @@ -285,10 +162,6 @@ return widget; } -views::Textfield* SearchResultsPanel::GetSearchBoxTextfield() const { - return search_box_view_ ? search_box_view_->textfield_ : nullptr; -} - std::vector<CaptureModeSessionFocusCycler::HighlightableView*> SearchResultsPanel::GetHighlightableItems() const { std::vector<CaptureModeSessionFocusCycler::HighlightableView*> @@ -296,12 +169,6 @@ CHECK(close_button_); highlightable_items.push_back( CaptureModeSessionFocusCycler::HighlightHelper::Get(close_button_.get())); - if (!features::IsSunfishLensWebEnabled()) { - CHECK(search_box_view_); - highlightable_items.push_back( - CaptureModeSessionFocusCycler::HighlightHelper::Get( - search_box_view_->textfield_.get())); - } return highlightable_items; } @@ -337,16 +204,6 @@ search_results_view_->Navigate(url); } -void SearchResultsPanel::SetSearchBoxImage(const gfx::ImageSkia& image) { - CHECK(search_box_view_); - search_box_view_->SetImage(image); -} - -void SearchResultsPanel::SetSearchBoxText(const std::u16string& text) { - CHECK(search_box_view_); - search_box_view_->textfield_->SetText(text); -} - void SearchResultsPanel::RefreshStackingOrder(aura::Window* new_root) { aura::Window* native_window = GetWidget()->GetNativeWindow(); // While the capture mode session is active, we parent the panel to its own @@ -356,17 +213,6 @@ views::Widget::ReparentNativeView(native_window, new_parent); } -bool SearchResultsPanel::IsTextfieldPseudoFocused() const { - if (features::IsSunfishLensWebEnabled()) { - return false; - } - - CHECK(search_box_view_); - return CaptureModeSessionFocusCycler::HighlightHelper::Get( - search_box_view_->textfield_) - ->has_focus(); -} - void SearchResultsPanel::ShowLoadingAnimation() { if (GetViewByID(capture_mode::kLoadingAnimationViewId)) { return;
diff --git a/ash/capture_mode/search_results_panel.h b/ash/capture_mode/search_results_panel.h index 30aa235..53e70f4 100644 --- a/ash/capture_mode/search_results_panel.h +++ b/ash/capture_mode/search_results_panel.h
@@ -19,13 +19,11 @@ namespace views { class Button; -class Textfield; } // namespace views namespace ash { class AshWebView; -class SunfishSearchBoxView; // Container for the search results view and other UI such as the search box, // close button, etc. @@ -49,8 +47,6 @@ return GetViewByID(capture_mode::kLoadingAnimationViewId); } - views::Textfield* GetSearchBoxTextfield() const; - // Gets the highlightable views for the search results panel, which may // include the close button and the search box textfield. Does not include // the web contents or animation as they need to be handled separately. @@ -68,18 +64,12 @@ // Sets the search box URL, image thumbnail, and text. virtual void Navigate(const GURL& url); - virtual void SetSearchBoxImage(const gfx::ImageSkia& image); - void SetSearchBoxText(const std::u16string& text); // Refreshes the panel z-order. If `new_root` is not null, capture mode // session is active and will be used to determine the panel root. Else the // panel will be re-stacked on its native window's root window. void RefreshStackingOrder(aura::Window* new_root); - // Returns true if the `CaptureModeSessionFocusCycler::HighlightHelper` for - // this view has focus, otherwise returns false. - bool IsTextfieldPseudoFocused() const; - // Shows and plays a loading animation in place of the web contents. void ShowLoadingAnimation(); @@ -106,7 +96,6 @@ void RefreshPanelBounds(); // Owned by the views hierarchy. - raw_ptr<SunfishSearchBoxView> search_box_view_ = nullptr; raw_ptr<AshWebView> search_results_view_ = nullptr; raw_ptr<views::Button> close_button_;
diff --git a/ash/capture_mode/sunfish_unittest.cc b/ash/capture_mode/sunfish_unittest.cc index 709f8d7b..82b0d4f1 100644 --- a/ash/capture_mode/sunfish_unittest.cc +++ b/ash/capture_mode/sunfish_unittest.cc
@@ -1664,7 +1664,7 @@ // Mock getting a new response from the server. Test the panel is updated. EXPECT_CALL(*search_results_panel, Navigate(testing::_)); - controller->ShowSearchResultsPanel(gfx::ImageSkia()); + controller->ShowSearchResultsPanel(); controller->NavigateSearchResultsPanel(GURL("kTestUrl2")); } @@ -2745,41 +2745,6 @@ LeftClickOn(search_button); } -// TODO: crbug.com/398259275 - Remove this class and remove or integrate each -// test when the Lens Web API implementation is enabled by default. -class SunfishLensWebTest : public SunfishTestBase { - public: - SunfishLensWebTest() { - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kSunfishFeature, - features::kSunfishLensWeb}, - /*disabled_features=*/{{}}); - } - SunfishLensWebTest(const SunfishLensWebTest&) = delete; - SunfishLensWebTest& operator=(const SunfishLensWebTest&) = delete; - ~SunfishLensWebTest() override = default; - - private: - base::test::ScopedFeatureList scoped_feature_list_; -}; - -// Tests that the native search box is removed from the search results panel -// when the Lens Web API implementation is enabled. -TEST_F(SunfishLensWebTest, NoNativeSearchBox) { - views::Widget::InitParams params( - views::Widget::InitParams::CLIENT_OWNS_WIDGET, - views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); - params.bounds = gfx::Rect{capture_mode::kSearchResultsPanelTotalWidth, - capture_mode::kSearchResultsPanelTotalHeight}; - params.parent = - Shell::GetContainer(Shell::GetPrimaryRootWindow(), - kShellWindowId_CaptureModeSearchResultsPanel); - auto widget = std::make_unique<views::Widget>(std::move(params)); - auto* search_results_panel = - widget->SetContentsView(std::make_unique<SearchResultsPanel>()); - EXPECT_FALSE(search_results_panel->GetSearchBoxTextfield()); -} - using SunfishDisplayMetricsTest = SunfishTest; // TODO(crbug.com/388564694): Enable after resolving flakiness.
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 42f2960..93bfc1cd 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -2095,7 +2095,7 @@ // go/ongoing-ui BASE_FEATURE(kOngoingProcesses, "OngoingProcesses", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // If enabled, enrollment screen will allow for automatically adding the // authenticated user to the device. @@ -2829,18 +2829,6 @@ "SunfishFeature", base::FEATURE_DISABLED_BY_DEFAULT); -// Changes the Sunfish feature to use the Lens Web API instead of the -// Chromnient-like query. -BASE_FEATURE(kSunfishLensWeb, - "SunfishLensWeb", - base::FEATURE_ENABLED_BY_DEFAULT); - -// Changes the Sunfish copy text functionality to use the Lens Web API instead -// of the Chromnient-like query. -BASE_FEATURE(kSunfishLensWebCopyText, - "SunfishLensWebCopyText", - base::FEATURE_ENABLED_BY_DEFAULT); - // Enable the suspend state machine to better handle suspend accelerators. BASE_FEATURE(kSuspendStateMachine, "SuspendStateMachine", @@ -4610,16 +4598,6 @@ return base::FeatureList::IsEnabled(kSunfishFeature); } -bool IsSunfishLensWebEnabled() { - return IsSunfishFeatureEnabled() && - base::FeatureList::IsEnabled(kSunfishLensWeb); -} - -bool IsSunfishLensWebCopyTextEnabled() { - return IsSunfishLensWebEnabled() && - base::FeatureList::IsEnabled(kSunfishLensWebCopyText); -} - bool IsSuspendStateMachineEnabled() { return base::FeatureList::IsEnabled(kSuspendStateMachine); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 20216dc..d25b1ec 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -934,8 +934,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSnoopingProtection); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSplitKeyboardRefactor); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSunfishFeature); -COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSunfishLensWeb); -COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSunfishLensWebCopyText); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSuspendStateMachine); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSystemJapanesePhysicalTyping);
diff --git a/ash/frame/default_frame_header_unittest.cc b/ash/frame/default_frame_header_unittest.cc index 9639ce5e..c80b3a9 100644 --- a/ash/frame/default_frame_header_unittest.cc +++ b/ash/frame/default_frame_header_unittest.cc
@@ -14,8 +14,6 @@ #include "base/i18n/rtl.h" #include "base/memory/raw_ptr.h" #include "base/test/icu_test_util.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/time/time.h" #include "chromeos/ui/base/window_properties.h" #include "chromeos/ui/frame/caption_buttons/frame_back_button.h" #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" @@ -45,19 +43,7 @@ namespace ash { -class DefaultFrameHeaderTest : public AshTestBase { - public: - DefaultFrameHeaderTest() - : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} - DefaultFrameHeaderTest(const DefaultFrameHeaderTest&) = delete; - DefaultFrameHeaderTest& operator=(const DefaultFrameHeaderTest&) = delete; - ~DefaultFrameHeaderTest() override = default; - - void AdvanceClock(base::TimeDelta delay) { - task_environment()->AdvanceClock(delay); - task_environment()->RunUntilIdle(); - } -}; +using DefaultFrameHeaderTest = AshTestBase; // Ensure the title text is vertically aligned with the window icon. TEST_F(DefaultFrameHeaderTest, TitleIconAlignment) { @@ -335,33 +321,4 @@ EXPECT_TRUE(win_0->layer()->damaged_region().Contains(layer_bounds)); } -// Ensure that the number of frame color changes is recorded as metrics. -TEST_F(DefaultFrameHeaderTest, FrameColorChangeMetrics) { - const auto app_type = chromeos::AppType::ARC_APP; - auto win0 = CreateAppWindow(gfx::Rect(300, 300), app_type); - Widget* widget = Widget::GetWidgetForNativeWindow(win0.get()); - DefaultFrameHeader* frame_header = - static_cast<DefaultFrameHeader*>(FrameHeader::Get(widget)); - - const auto frame_color_change_histogram = - chromeos::FrameColorMetricsHelper::GetFrameColorChangeHistogramName( - app_type); - base::HistogramTester histogram_tester; - - win0->SetProperty(kFrameActiveColorKey, SkColorSetRGB(70, 70, 70)); - win0->SetProperty(kFrameInactiveColorKey, SkColorSetRGB(70, 70, 70)); - frame_header->UpdateFrameColors(); - - constexpr base::TimeDelta kFrameColorTracingTime = base::Seconds(3); - // Advances the mock clock in the task environment because the metrics is - // recorded `kFrameColorTracingTime` after the `frame_header` is instantiated. - AdvanceClock(kFrameColorTracingTime); - - histogram_tester.ExpectTotalCount(frame_color_change_histogram, 1); - - // The recorded number of frame color changes should be at least 1. - EXPECT_GE(histogram_tester.GetAllSamples(frame_color_change_histogram)[0].min, - 1); -} - } // namespace ash
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 64c39c9..b5f88ad 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -1186,7 +1186,8 @@ const bool has_visible_snap_group = snap_group_controller && snap_group_controller->GetTopmostVisibleSnapGroup( - shelf_native_window->GetRootWindow()); + shelf_native_window->GetRootWindow(), + /*topwindow_only=*/false); const bool maximized = in_split_view_mode || has_visible_snap_group || state_.window_state == WorkspaceWindowState::kFullscreen ||
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index 500c580..d6cea7f 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -655,9 +655,9 @@ SplitViewController::Get(root_window_)->InSplitViewMode(); SnapGroupController* snap_group_controller = SnapGroupController::Get(); const bool should_report_split_view_metrics = - in_split_view || - (snap_group_controller && - snap_group_controller->GetTopmostVisibleSnapGroup(root_window_)); + in_split_view || (snap_group_controller && + snap_group_controller->GetTopmostVisibleSnapGroup( + root_window_, /*topwindow_only=*/true)); // OverviewGrid in splitscreen does not include the window to be activated. if (!item_list_.empty() || should_report_split_view_metrics) { const bool minimized_in_tablet = @@ -2663,7 +2663,8 @@ const bool both_snapped_windows = state == SplitViewController::State::kBothSnapped || (snap_group_controller && - snap_group_controller->GetTopmostVisibleSnapGroup(root_window_)); + snap_group_controller->GetTopmostVisibleSnapGroup( + root_window_, /*topwindow_only=*/true)); if (both_snapped_windows || unsnappable_window_activated || (split_view_controller->InClamshellSplitViewMode() && overview_session_->IsEmpty())) {
diff --git a/ash/wm/snap_group/snap_group_controller.cc b/ash/wm/snap_group/snap_group_controller.cc index a7a1530..e2f728bb 100644 --- a/ash/wm/snap_group/snap_group_controller.cc +++ b/ash/wm/snap_group/snap_group_controller.cc
@@ -287,7 +287,8 @@ } SnapGroup* SnapGroupController::GetTopmostVisibleSnapGroup( - const aura::Window* target_root) const { + const aura::Window* target_root, + bool topwindow_only) const { for (const aura::Window* top_window : GetActiveDeskAppWindowsInZOrder( const_cast<aura::Window*>(target_root))) { // Skip to the topmost window on `target_root`, ignoring occlusion-exempt @@ -302,7 +303,9 @@ return snap_group; } // Else if `top_window` does not belong to a snap group, we are done. - break; + if (topwindow_only) { + break; + } } return nullptr; }
diff --git a/ash/wm/snap_group/snap_group_controller.h b/ash/wm/snap_group/snap_group_controller.h index 278281c..cb9c989 100644 --- a/ash/wm/snap_group/snap_group_controller.h +++ b/ash/wm/snap_group/snap_group_controller.h
@@ -89,7 +89,10 @@ SnapGroup* GetSnapGroupForGivenWindow(const aura::Window* window) const; // Returns the topmost fully visible non-occluded snap group on `target_root`. - SnapGroup* GetTopmostVisibleSnapGroup(const aura::Window* target_root) const; + // If `topwindow_only` is true, it return null if the top window isn't in a + // snap group. If false, it will search until it finds a snap group. + SnapGroup* GetTopmostVisibleSnapGroup(const aura::Window* target_root, + bool topwindow_only) const; // Returns the topmost snap group in unminimized state. SnapGroup* GetTopmostSnapGroup() const;
diff --git a/ash/wm/snap_group/snap_group_unittest.cc b/ash/wm/snap_group/snap_group_unittest.cc index d9b71b08..e0b23ef 100644 --- a/ash/wm/snap_group/snap_group_unittest.cc +++ b/ash/wm/snap_group/snap_group_unittest.cc
@@ -2375,6 +2375,22 @@ EXPECT_EQ(ShelfBackgroundType::kMaximized, shelf_layout_manager->shelf_background_type()); + // Creating a window on top shouldn't affect the shelf background type. + std::unique_ptr<aura::Window> w3(CreateAppWindow()); + EXPECT_EQ(ShelfBackgroundType::kMaximized, + shelf_layout_manager->shelf_background_type()); + + // Enter & exit overview the background type should still be kMaximized. + ToggleOverview(); + ToggleOverview(); + EXPECT_EQ(ShelfBackgroundType::kMaximized, + shelf_layout_manager->shelf_background_type()); + + // The background type should still be kMaximized after closing it. + w3.reset(); + EXPECT_EQ(ShelfBackgroundType::kMaximized, + shelf_layout_manager->shelf_background_type()); + // Drag `w1` out to break the group. event_generator->MoveMouseTo(w1->GetBoundsInScreen().top_center()); aura::test::TestWindowDelegate().set_window_component(HTCAPTION); @@ -10490,8 +10506,8 @@ // At this point `w4` is active but a single snapped window. Recall the group // for `w1` and `w2` so we can start snap to replace. wm::ActivateWindow(w1.get()); - ASSERT_TRUE( - snap_group_controller->GetTopmostVisibleSnapGroup(w1->GetRootWindow())); + ASSERT_TRUE(snap_group_controller->GetTopmostVisibleSnapGroup( + w1->GetRootWindow(), /*topwindow_only=*/true)); // Snap to replace `w5` in the 1st snap group. Test we don't record. std::unique_ptr<aura::Window> w5(CreateAppWindow());
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/instance_tracer.h b/base/allocator/partition_allocator/src/partition_alloc/pointers/instance_tracer.h index 87190a63..c8e55d7b 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/pointers/instance_tracer.h +++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/instance_tracer.h
@@ -5,33 +5,25 @@ #ifndef PARTITION_ALLOC_POINTERS_INSTANCE_TRACER_H_ #define PARTITION_ALLOC_POINTERS_INSTANCE_TRACER_H_ +#include <stdint.h> + +#include "partition_alloc/buildflags.h" +#include "partition_alloc/partition_alloc_base/compiler_specific.h" + +#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_INSTANCE_TRACER) #include <array> #include <atomic> #include <cstdint> #include <utility> #include <vector> -#include "partition_alloc/buildflags.h" -#include "partition_alloc/partition_alloc_base/compiler_specific.h" #include "partition_alloc/partition_alloc_base/component_export.h" #include "partition_alloc/partition_alloc_base/cxx20_is_constant_evaluated.h" +#endif namespace base::internal { -#if !PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_INSTANCE_TRACER) - -// When the buildflag is disabled, use a minimal no-state implementation so -// sizeof(raw_ptr<T>) == sizeof(T*). -class InstanceTracer { - public: - constexpr uint64_t owner_id() const { return 0; } - - constexpr static void Trace([[maybe_unused]] uint64_t owner_id, - [[maybe_unused]] uintptr_t address) {} - constexpr static void Untrace([[maybe_unused]] uint64_t owner_id) {} -}; - -#else +#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_INSTANCE_TRACER) class PA_TRIVIAL_ABI InstanceTracer { public: @@ -93,7 +85,20 @@ uint64_t owner_id_ = 0; }; -#endif +#else + +// When the buildflag is disabled, use a minimal no-state implementation so +// sizeof(raw_ptr<T>) == sizeof(T*). +class InstanceTracer { + public: + constexpr uint64_t owner_id() const { return 0; } + + constexpr static void Trace([[maybe_unused]] uint64_t owner_id, + [[maybe_unused]] uintptr_t address) {} + constexpr static void Untrace([[maybe_unused]] uint64_t owner_id) {} +}; + +#endif // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_INSTANCE_TRACER) } // namespace base::internal
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py index 9f4927a..dbba2a2 100644 --- a/build/android/PRESUBMIT.py +++ b/build/android/PRESUBMIT.py
@@ -86,8 +86,9 @@ }) pytests = [ - J('.', 'list_class_verification_failures_test.py'), J('.', 'convert_dex_profile_tests.py'), + J('.', 'list_class_verification_failures_test.py'), + J('.', 'test_runner_test.py'), J('gyp', 'compile_java_tests.py'), J('gyp', 'create_unwind_table_tests.py'), J('gyp', 'dex_test.py'),
diff --git a/build/android/test_runner_test.py b/build/android/test_runner_test.py index b2a75a93..93794cc 100755 --- a/build/android/test_runner_test.py +++ b/build/android/test_runner_test.py
@@ -78,3 +78,8 @@ self.exc_recorder.clear_stacktrace.assert_called_once() self.exc_recorder.register.assert_called_once() self.mm_recorder.clear.assert_called_once() + + +if __name__ == '__main__': + # Suppress logging messages. + unittest.main(buffer=True)
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 94fc4b4..5a58de1 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -626,13 +626,6 @@ default_toolchain != "//build/toolchain/cros:target") { cflags += [ "-Wa,--crel,--allow-experimental-crel" ] } - - # TODO(crbug.com/413427035): Remove once - # https://github.com/llvm/llvm-project/pull/136867/ is landed. - if (!is_win && !llvm_android_mainline && - default_toolchain != "//build/toolchain/cros:target") { - cflags += [ "-fextend-variable-liveness=none" ] - } } # C11/C++11 compiler flags setup.
diff --git a/build/rust/std/gnrt_config.toml b/build/rust/std/gnrt_config.toml index d920be2..b394cca 100644 --- a/build/rust/std/gnrt_config.toml +++ b/build/rust/std/gnrt_config.toml
@@ -46,10 +46,6 @@ # The build script conditionally generates a file; it's simplest to just paste # raw GN into the output. (crbug.com/1470653) extra_kv = { include_coverage = false, raw_gn = 'if (current_cpu == "arm64") { build_script_outputs = ["outlined_atomics.rs"] }' } -extra_src_roots = [ - # compiler_builtins depends on libm on windows crbug.com/1472681 - '../libm', -] extra_build_script_src_roots = [ '../configure.rs', ]
diff --git a/build/rust/std/rules/BUILD.gn b/build/rust/std/rules/BUILD.gn index a3e6cec..8ae649d 100644 --- a/build/rust/std/rules/BUILD.gn +++ b/build/rust/std/rules/BUILD.gn
@@ -300,235 +300,236 @@ } cargo_crate("compiler_builtins") { crate_type = "rlib" - crate_root = "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/lib.rs" + crate_root = "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/lib.rs" sources = [ - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/aarch64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/aarch64_linux.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/arm.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/arm_linux.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/add.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/cmp.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/conv.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/div.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/extend.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/mul.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/pow.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/sub.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/traits.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/float/trunc.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/hexagon.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/addsub.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/big.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/bswap.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/leading_zeros.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/mul.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/sdiv.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/shift.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/specialized_div_rem/asymmetric.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/specialized_div_rem/binary_long.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/specialized_div_rem/delegate.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/specialized_div_rem/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/specialized_div_rem/norm_shift.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/specialized_div_rem/trifecta.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/trailing_zeros.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/traits.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/int/udiv.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/lib.miri.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/lib.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/macros.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/math.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/mem/impls.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/mem/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/mem/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/probestack.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/riscv.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/x86.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/aarch64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/aarch64_linux.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/arm.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/arm_linux.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/avr.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/add.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/cmp.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/conv.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/div.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/extend.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/mul.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/pow.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/sub.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/traits.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/float/trunc.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/hexagon.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/addsub.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/big.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/bswap.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/leading_zeros.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/mul.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/sdiv.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/shift.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/specialized_div_rem/asymmetric.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/specialized_div_rem/binary_long.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/specialized_div_rem/delegate.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/specialized_div_rem/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/specialized_div_rem/norm_shift.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/specialized_div_rem/trifecta.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/trailing_zeros.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/traits.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/int/udiv.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/lib.miri.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/lib.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/macros.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/acos.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/acosf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/acosh.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/acoshf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/arch/aarch64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/arch/i586.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/arch/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/arch/wasm32.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/arch/x86.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/arch/x86/detect.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/arch/x86/fma.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/asin.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/asinf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/asinh.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/asinhf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/atan.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/atan2.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/atan2f.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/atanf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/atanh.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/atanhf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/cbrt.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/cbrtf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/ceil.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/copysign.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/copysignf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/copysignf128.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/copysignf16.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/cos.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/cosf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/cosh.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/coshf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/erf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/erff.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/exp.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/exp10.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/exp10f.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/exp2.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/exp2f.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/expf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/expm1.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/expm1f.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/expo2.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fabs.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fabsf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fabsf128.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fabsf16.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fdim.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fdimf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fdimf128.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fdimf16.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/floor.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/floorf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/floorf128.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/floorf16.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fma.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fmin_fmax.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fminimum_fmaximum.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fminimum_fmaximum_num.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fmod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fmodf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fmodf128.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/fmodf16.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/frexp.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/frexpf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/ceil.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/copysign.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fabs.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fdim.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/floor.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fma.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fma_wide.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fmax.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fmaximum.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fmaximum_num.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fmin.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fminimum.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fminimum_num.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/fmod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/rint.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/round.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/scalbn.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/sqrt.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/generic/trunc.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/hypot.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/hypotf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/ilogb.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/ilogbf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/j0.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/j0f.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/j1.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/j1f.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/jn.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/jnf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/k_cos.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/k_cosf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/k_expo2.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/k_expo2f.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/k_sin.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/k_sinf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/k_tan.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/k_tanf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/ldexp.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/ldexpf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/ldexpf128.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/ldexpf16.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/lgamma.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/lgamma_r.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/lgammaf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/lgammaf_r.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/log.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/log10.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/log10f.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/log1p.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/log1pf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/log2.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/log2f.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/logf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/modf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/modff.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/nextafter.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/nextafterf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/pow.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/powf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/rem_pio2.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/rem_pio2_large.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/rem_pio2f.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/remainder.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/remainderf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/remquo.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/remquof.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/rint.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/round.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/roundeven.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/roundf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/roundf128.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/roundf16.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/scalbn.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/scalbnf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/scalbnf128.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/scalbnf16.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/sin.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/sincos.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/sincosf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/sinf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/sinh.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/sinhf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/sqrt.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/sqrtf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/sqrtf128.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/sqrtf16.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/support/big.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/support/big/tests.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/support/env.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/support/feature_detect.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/support/float_traits.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/support/hex_float.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/support/int_traits.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/support/macros.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/support/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/tan.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/tanf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/tanh.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/tanhf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/tgamma.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/tgammaf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/trunc.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/truncf.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/truncf128.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/libm_math/truncf16.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/math/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/mem/impls.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/mem/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/mem/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/probestack.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/riscv.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/x86.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/x86_64.rs", ] - inputs = [ - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/acos.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/acosf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/acosh.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/acoshf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/arch/aarch64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/arch/i586.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/arch/i686.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/arch/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/arch/wasm32.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/asin.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/asinf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/asinh.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/asinhf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/atan.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/atan2.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/atan2f.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/atanf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/atanh.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/atanhf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/cbrt.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/cbrtf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/ceil.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/ceilf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/ceilf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/ceilf16.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/copysign.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/copysignf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/copysignf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/copysignf16.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/cos.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/cosf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/cosh.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/coshf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/erf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/erff.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/exp.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/exp10.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/exp10f.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/exp2.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/exp2f.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/expf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/expm1.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/expm1f.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/expo2.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fabs.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fabsf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fabsf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fabsf16.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fdim.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fdimf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fdimf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fdimf16.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/floor.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/floorf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/floorf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/floorf16.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fma.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fma_wide.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fmin_fmax.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fminimum_fmaximum.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fminimum_fmaximum_num.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fmod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fmodf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fmodf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/fmodf16.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/frexp.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/frexpf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/ceil.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/copysign.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/fabs.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/fdim.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/floor.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/fmax.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/fmaximum.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/fmaximum_num.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/fmin.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/fminimum.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/fminimum_num.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/fmod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/rint.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/round.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/scalbn.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/sqrt.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/generic/trunc.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/hypot.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/hypotf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/ilogb.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/ilogbf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/j0.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/j0f.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/j1.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/j1f.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/jn.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/jnf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/k_cos.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/k_cosf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/k_expo2.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/k_expo2f.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/k_sin.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/k_sinf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/k_tan.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/k_tanf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/ldexp.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/ldexpf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/ldexpf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/ldexpf16.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/lgamma.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/lgamma_r.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/lgammaf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/lgammaf_r.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/log.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/log10.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/log10f.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/log1p.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/log1pf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/log2.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/log2f.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/logf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/modf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/modff.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/nextafter.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/nextafterf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/pow.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/powf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/rem_pio2.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/rem_pio2_large.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/rem_pio2f.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/remainder.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/remainderf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/remquo.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/remquof.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/rint.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/round.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/roundeven.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/roundf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/roundf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/roundf16.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/scalbn.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/scalbnf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/scalbnf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/scalbnf16.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/sin.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/sincos.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/sincosf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/sinf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/sinh.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/sinhf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/sqrt.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/sqrtf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/sqrtf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/sqrtf16.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/support/big/tests.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/support/big.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/support/env.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/support/float_traits.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/support/hex_float.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/support/int_traits.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/support/macros.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/support/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/tan.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/tanf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/tanh.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/tanhf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/tgamma.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/tgammaf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/trunc.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/truncf.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/truncf128.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../libm/src/math/truncf16.rs", - ] + inputs = [] no_std = true # Unit tests skipped. Generate with --with-tests to include them. build_native_rust_unit_tests = false edition = "2021" - cargo_pkg_version = "0.1.155" + cargo_pkg_version = "0.1.157" cargo_pkg_authors = "Jorge Aparicio <japaricious@gmail.com>" cargo_pkg_name = "compiler_builtins" - cargo_pkg_description = "Compiler intrinsics used by the Rust compiler. Also available for other targets if necessary!" + cargo_pkg_description = "Compiler intrinsics used by the Rust compiler." library_configs -= [ "//build/config/compiler:chromium_code", "//build/config/compiler:disallow_unstable_features", @@ -549,13 +550,12 @@ } features = [ "compiler-builtins", - "core", "default", "rustc-dep-of-std", ] - build_root = "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/build.rs" - build_sources = [ "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/build.rs" ] - build_script_inputs = [ "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.155/src/../configure.rs" ] + build_root = "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/build.rs" + build_sources = [ "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/build.rs" ] + build_script_inputs = [ "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/compiler_builtins-0.1.157/src/../configure.rs" ] rustenv = [ "CFG_DISABLE_UNSTABLE_FEATURES=0", "STD_ENV_ARCH=$rust_target_arch", @@ -1264,34 +1264,35 @@ } cargo_crate("hashbrown") { crate_type = "rlib" - crate_root = "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/lib.rs" + crate_root = "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/lib.rs" sources = [ - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/control/bitmask.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/control/group/generic.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/control/group/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/control/group/neon.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/control/group/sse2.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/control/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/control/tag.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/external_trait_impls/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/external_trait_impls/rayon/helpers.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/external_trait_impls/rayon/map.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/external_trait_impls/rayon/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/external_trait_impls/rayon/raw.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/external_trait_impls/rayon/set.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/external_trait_impls/rayon/table.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/external_trait_impls/serde.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/lib.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/macros.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/map.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/raw/alloc.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/raw/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/raw_entry.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/rustc_entry.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/scopeguard.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/set.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/table.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.2/src/util.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/control/bitmask.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/control/group/generic.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/control/group/lsx.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/control/group/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/control/group/neon.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/control/group/sse2.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/control/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/control/tag.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/external_trait_impls/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/external_trait_impls/rayon/helpers.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/external_trait_impls/rayon/map.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/external_trait_impls/rayon/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/external_trait_impls/rayon/raw.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/external_trait_impls/rayon/set.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/external_trait_impls/rayon/table.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/external_trait_impls/serde.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/lib.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/macros.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/map.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/raw/alloc.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/raw/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/raw_entry.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/rustc_entry.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/scopeguard.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/set.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/table.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/hashbrown-0.15.3/src/util.rs", ] inputs = [] no_std = true @@ -1299,7 +1300,7 @@ # Unit tests skipped. Generate with --with-tests to include them. build_native_rust_unit_tests = false edition = "2021" - cargo_pkg_version = "0.15.2" + cargo_pkg_version = "0.15.3" cargo_pkg_authors = "Amanieu d'Antras <amanieu@gmail.com>" cargo_pkg_name = "hashbrown" cargo_pkg_description = "A Rust port of Google's SwissTable hash map" @@ -1329,7 +1330,6 @@ "compiler_builtins", "core", "nightly", - "raw-entry", "rustc-dep-of-std", "rustc-internal-api", ] @@ -1348,188 +1348,188 @@ if (!is_win) { cargo_crate("libc") { crate_type = "rlib" - crate_root = "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/lib.rs" + crate_root = "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/lib.rs" sources = [ - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/fuchsia/aarch64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/fuchsia/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/fuchsia/riscv64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/fuchsia/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/hermit.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/lib.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/macros.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/primitives.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/psp.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/sgx.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/solid/aarch64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/solid/arm.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/solid/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/switch.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/teeos/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/trusty.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/aix/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/aix/powerpc64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/apple/b32/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/apple/b64/aarch64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/apple/b64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/apple/b64/x86_64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/apple/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/dragonfly/errno.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/dragonfly/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/aarch64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/arm.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd11/b32.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/powerpc.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/riscv64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/x86.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/freebsdlike/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/netbsd/aarch64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/netbsd/arm.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/netbsd/mips.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/netbsd/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/netbsd/powerpc.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/netbsd/riscv64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/netbsd/sparc64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/netbsd/x86.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/netbsd/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/openbsd/aarch64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/openbsd/arm.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/openbsd/mips64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/openbsd/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/openbsd/powerpc.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/openbsd/powerpc64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/openbsd/riscv64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/openbsd/sparc64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/openbsd/x86.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/bsd/netbsdlike/openbsd/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/cygwin/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/haiku/b32.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/haiku/b64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/haiku/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/haiku/native.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/haiku/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/hurd/b32.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/hurd/b64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/hurd/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/android/b32/arm.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/android/b32/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/android/b32/x86/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/android/b64/aarch64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/android/b64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/android/b64/riscv64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/android/b64/x86_64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/android/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/emscripten/lfs64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/emscripten/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/arch/generic/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/arch/mips/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/arch/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/arch/powerpc/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/arch/sparc/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b32/arm/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b32/csky/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b32/mips/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b32/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b32/powerpc.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b32/x86/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/s390x.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/gnu/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b32/arm/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b32/hexagon.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b32/mips/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b32/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b32/powerpc.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b32/x86/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b64/loongarch64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b64/mips64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b64/powerpc64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b64/s390x.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b64/wasm32/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b64/wasm32/wali.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/lfs64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/musl/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/uclibc/arm/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/uclibc/mips/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/uclibc/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/uclibc/x86_64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/linux/uclibc/x86_64/other.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/linux_like/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/newlib/aarch64/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/newlib/arm/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/newlib/espidf/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/newlib/generic.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/newlib/horizon/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/newlib/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/newlib/powerpc/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/newlib/rtems/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/newlib/vita/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/nto/aarch64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/nto/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/nto/neutrino.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/nto/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/nuttx/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/redox/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/solarish/compat.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/solarish/illumos.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/solarish/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/solarish/solaris.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/solarish/x86.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/solarish/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/unix/solarish/x86_common.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/vxworks/aarch64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/vxworks/arm.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/vxworks/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/vxworks/powerpc.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/vxworks/powerpc64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/vxworks/riscv32.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/vxworks/riscv64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/vxworks/x86.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/vxworks/x86_64.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/wasi/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/wasi/p2.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/windows/gnu/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/windows/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/windows/msvc/mod.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/src/xous.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/fuchsia/aarch64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/fuchsia/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/fuchsia/riscv64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/fuchsia/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/hermit.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/lib.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/macros.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/primitives.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/psp.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/sgx.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/solid/aarch64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/solid/arm.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/solid/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/switch.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/teeos/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/trusty.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/aix/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/aix/powerpc64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/apple/b32/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/apple/b64/aarch64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/apple/b64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/apple/b64/x86_64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/apple/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/dragonfly/errno.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/dragonfly/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/aarch64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/arm.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd11/b32.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd11/b64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd11/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd12/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd12/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd13/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd13/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd14/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd14/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd15/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/freebsd15/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/powerpc.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/powerpc64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/riscv64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/x86.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/freebsd/x86_64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/freebsdlike/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/netbsd/aarch64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/netbsd/arm.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/netbsd/mips.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/netbsd/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/netbsd/powerpc.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/netbsd/riscv64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/netbsd/sparc64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/netbsd/x86.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/netbsd/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/openbsd/aarch64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/openbsd/arm.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/openbsd/mips64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/openbsd/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/openbsd/powerpc.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/openbsd/powerpc64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/openbsd/riscv64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/openbsd/sparc64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/openbsd/x86.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/bsd/netbsdlike/openbsd/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/cygwin/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/haiku/b32.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/haiku/b64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/haiku/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/haiku/native.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/haiku/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/hurd/b32.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/hurd/b64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/hurd/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/android/b32/arm.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/android/b32/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/android/b32/x86/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/android/b64/aarch64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/android/b64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/android/b64/riscv64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/android/b64/x86_64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/android/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/emscripten/lfs64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/emscripten/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/arch/generic/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/arch/mips/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/arch/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/arch/powerpc/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/arch/sparc/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b32/arm/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b32/csky/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b32/m68k/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b32/mips/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b32/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b32/powerpc.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b32/riscv32/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b32/sparc/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b32/x86/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/aarch64/ilp32.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/aarch64/lp64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/aarch64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/loongarch64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/mips64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/powerpc64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/riscv64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/s390x.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/sparc64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/x86_64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/x86_64/not_x32.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/b64/x86_64/x32.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/gnu/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b32/arm/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b32/hexagon.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b32/mips/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b32/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b32/powerpc.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b32/x86/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b64/loongarch64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b64/mips64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b64/powerpc64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b64/s390x.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b64/wasm32/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b64/wasm32/wali.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/lfs64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/musl/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/uclibc/arm/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/uclibc/mips/mips32/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/uclibc/mips/mips64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/uclibc/mips/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/uclibc/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/uclibc/x86_64/l4re.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/uclibc/x86_64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/linux/uclibc/x86_64/other.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/linux_like/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/newlib/aarch64/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/newlib/arm/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/newlib/espidf/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/newlib/generic.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/newlib/horizon/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/newlib/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/newlib/powerpc/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/newlib/rtems/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/newlib/vita/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/nto/aarch64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/nto/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/nto/neutrino.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/nto/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/nuttx/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/redox/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/solarish/compat.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/solarish/illumos.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/solarish/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/solarish/solaris.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/solarish/x86.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/solarish/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/unix/solarish/x86_common.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/vxworks/aarch64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/vxworks/arm.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/vxworks/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/vxworks/powerpc.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/vxworks/powerpc64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/vxworks/riscv32.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/vxworks/riscv64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/vxworks/x86.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/vxworks/x86_64.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/wasi/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/wasi/p2.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/windows/gnu/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/windows/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/windows/msvc/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/src/xous.rs", ] inputs = [] no_std = true @@ -1537,7 +1537,7 @@ # Unit tests skipped. Generate with --with-tests to include them. build_native_rust_unit_tests = false edition = "2021" - cargo_pkg_version = "0.2.171" + cargo_pkg_version = "0.2.172" cargo_pkg_authors = "The Rust Project Developers" cargo_pkg_name = "libc" cargo_pkg_description = "Raw FFI bindings to platform libraries like libc." @@ -1561,8 +1561,8 @@ "rustc-dep-of-std", "rustc-std-workspace-core", ] - build_root = "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/build.rs" - build_sources = [ "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.171/build.rs" ] + build_root = "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/build.rs" + build_sources = [ "//third_party/rust-toolchain/lib/rustlib/src/rust/library/vendor/libc-0.2.172/build.rs" ] rustenv = [ "CFG_DISABLE_UNSTABLE_FEATURES=0", "STD_ENV_ARCH=$rust_target_arch", @@ -2598,7 +2598,6 @@ "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/anonymous_pipe/unsupported.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/anonymous_pipe/windows.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/args/common.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/args/hermit.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/args/mod.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/args/sgx.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/args/uefi.rs", @@ -2611,6 +2610,18 @@ "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/args/zkvm.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/backtrace.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/cmath.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/common.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/hermit.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/mod.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/sgx.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/solid.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/uefi.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/unix.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/unsupported.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/wasi.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/windows.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/xous.rs", + "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env/zkvm.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/env_consts.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/exit_guard.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/fd/hermit.rs", @@ -2777,7 +2788,6 @@ "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/pal/xous/thread.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/pal/xous/time.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/pal/zkvm/abi.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/pal/zkvm/env.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/pal/zkvm/mod.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/pal/zkvm/os.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/std/src/sys/path/mod.rs", @@ -3073,7 +3083,6 @@ "//third_party/rust-toolchain/lib/rustlib/src/rust/library/stdarch/crates/std_detect/src/detect/os/linux/aarch64.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/stdarch/crates/std_detect/src/detect/os/linux/arm.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/stdarch/crates/std_detect/src/detect/os/linux/auxvec.rs", - "//third_party/rust-toolchain/lib/rustlib/src/rust/library/stdarch/crates/std_detect/src/detect/os/linux/cpuinfo.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/stdarch/crates/std_detect/src/detect/os/linux/loongarch.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/stdarch/crates/std_detect/src/detect/os/linux/mips.rs", "//third_party/rust-toolchain/lib/rustlib/src/rust/library/stdarch/crates/std_detect/src/detect/os/linux/mod.rs",
diff --git a/chrome/VERSION b/chrome/VERSION index 75a23288..040574e 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=138 MINOR=0 -BUILD=7180 +BUILD=7181 PATCH=0
diff --git a/chrome/browser/actor/BUILD.gn b/chrome/browser/actor/BUILD.gn index db6fdf42..406ab8c 100644 --- a/chrome/browser/actor/BUILD.gn +++ b/chrome/browser/actor/BUILD.gn
@@ -104,6 +104,7 @@ "//chrome/browser/optimization_guide:test_support", "//chrome/browser/safe_browsing", "//chrome/browser/ui:ui", + "//chrome/browser/ui:ui_features", "//chrome/browser/ui/zoom:zoom", "//chrome/test:test_support", "//chrome/test:test_support_ui",
diff --git a/chrome/browser/actor/actor_coordinator_browsertest.cc b/chrome/browser/actor/actor_coordinator_browsertest.cc index 970c140..1aae0a9 100644 --- a/chrome/browser/actor/actor_coordinator_browsertest.cc +++ b/chrome/browser/actor/actor_coordinator_browsertest.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/glic/glic_keyed_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/actor.mojom-forward.h" #include "chrome/common/actor/action_result.h" #include "chrome/common/chrome_features.h"
diff --git a/chrome/browser/actor/tools/history_tool.cc b/chrome/browser/actor/tools/history_tool.cc index 09ba189..8876f58ab 100644 --- a/chrome/browser/actor/tools/history_tool.cc +++ b/chrome/browser/actor/tools/history_tool.cc
@@ -6,12 +6,14 @@ #include "base/time/time.h" #include "chrome/browser/actor/tools/tool_callbacks.h" +#include "chrome/common/actor.mojom.h" #include "chrome/common/actor/action_result.h" #include "components/tabs/public/tab_interface.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" +#include "net/base/net_errors.h" #include "third_party/abseil-cpp/absl/strings/str_format.h" namespace { @@ -36,18 +38,21 @@ HistoryTool::~HistoryTool() = default; void HistoryTool::Validate(ValidateCallback callback) { - // TODO(crbug.com/409558980): Add distinct error codes. NavigationController& controller = web_contents()->GetController(); - if ((direction_ == kBack && !controller.CanGoBack()) || - (direction_ == kForward && !controller.CanGoForward())) { - PostResponseTask(std::move(callback), MakeErrorResult()); - return; + mojom::ActionResultPtr result; + + if (direction_ == kBack && !controller.CanGoBack()) { + result = MakeResult(mojom::ActionResultCode::kHistoryNoBackEntries); + } else if (direction_ == kForward && !controller.CanGoForward()) { + result = MakeResult(mojom::ActionResultCode::kHistoryNoForwardEntries); + } else { + result = MakeOkResult(); } // TODO(crbug.com/402731599): Additional validation here (e.g. is URL in // allowlist). - PostResponseTask(std::move(callback), MakeOkResult()); + PostResponseTask(std::move(callback), std::move(result)); } void HistoryTool::Invoke(InvokeCallback callback) { @@ -120,12 +125,31 @@ return; } - // TODO(crbug.com/409558980): Add distinct error codes. if (in_flight_navigation_ids_.erase(navigation_handle->GetNavigationId())) { - auto result = - (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) - ? MakeOkResult() - : MakeErrorResult(); + mojom::ActionResultPtr result; + auto details_msg = [](NavigationHandle* handle) { + std::string msg; + if (handle->GetNavigationDiscardReason()) { + msg = absl::StrFormat("DiscardReason[%d] ", + handle->GetNavigationDiscardReason().value()); + } + if (handle->GetNetErrorCode() != net::OK) { + msg += + absl::StrFormat("ErrorCode[%s]", + net::ErrorToShortString(handle->GetNetErrorCode())); + } + return msg; + }; + + if (!navigation_handle->HasCommitted()) { + result = MakeResult(mojom::ActionResultCode::kHistoryFailedBeforeCommit, + details_msg(navigation_handle)); + } else if (navigation_handle->IsErrorPage()) { + result = MakeResult(mojom::ActionResultCode::kHistoryErrorPage, + details_msg(navigation_handle)); + } else { + result = MakeOkResult(); + } FinishToolInvocationIfNeeded(std::move(result)); } }
diff --git a/chrome/browser/actor/tools/tools_browsertest.cc b/chrome/browser/actor/tools/tools_browsertest.cc index f4caee5..f65505ac 100644 --- a/chrome/browser/actor/tools/tools_browsertest.cc +++ b/chrome/browser/actor/tools/tools_browsertest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/actor/actor_test_util.h" #include "chrome/browser/actor/tools/wait_tool.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" #include "chrome/common/actor.mojom.h" @@ -1125,7 +1126,8 @@ { TestFuture<mojom::ActionResultPtr> result; actor_coordinator().Act(MakeHistoryForward(), result.GetCallback()); - ExpectErrorResult(result, mojom::ActionResultCode::kError); + ExpectErrorResult(result, + mojom::ActionResultCode::kHistoryNoForwardEntries); EXPECT_EQ(web_contents()->GetURL(), url_second); } @@ -1138,7 +1140,7 @@ { TestFuture<mojom::ActionResultPtr> result; actor_coordinator().Act(MakeHistoryBack(), result.GetCallback()); - ExpectErrorResult(result, mojom::ActionResultCode::kError); + ExpectErrorResult(result, mojom::ActionResultCode::kHistoryNoBackEntries); EXPECT_EQ(web_contents()->GetURL(), url_second); } }
diff --git a/chrome/browser/ai/ai_language_model.cc b/chrome/browser/ai/ai_language_model.cc index 64c3414b..97ec35d 100644 --- a/chrome/browser/ai/ai_language_model.cc +++ b/chrome/browser/ai/ai_language_model.cc
@@ -580,26 +580,56 @@ mojo::PendingRemote<blink::mojom::AIManagerCreateLanguageModelClient> create_client, std::optional<uint32_t> token_count) { - mojo::Remote<blink::mojom::AIManagerCreateLanguageModelClient> client( - std::move(create_client)); if (!initial_session_ || !token_count) { - client->OnError( - blink::mojom::AIManagerCreateClientError::kUnableToCreateSession); + mojo::Remote<blink::mojom::AIManagerCreateLanguageModelClient>( + std::move(create_client)) + ->OnError( + blink::mojom::AIManagerCreateClientError::kUnableToCreateSession); return; } uint32_t max_tokens = context_->max_tokens(); if (*token_count > max_tokens) { - client->OnError( - blink::mojom::AIManagerCreateClientError::kInitialInputTooLarge); + mojo::Remote<blink::mojom::AIManagerCreateLanguageModelClient>( + std::move(create_client)) + ->OnError( + blink::mojom::AIManagerCreateClientError::kInitialInputTooLarge); return; } - if (input) { - // `context_` will track how many tokens are remaining after the initial - // prompts. The initial prompts cannot be evicted. - context_ = std::make_unique<Context>(max_tokens - *token_count); + // `context_` will track how many tokens are remaining after the initial + // prompts. The initial prompts cannot be evicted. + context_ = std::make_unique<Context>(max_tokens - *token_count); + if (input) { + auto safety_input = CreateStringMessage(*input); + safety_checker_->RunRequestChecks( + safety_input, + base::BindOnce(&AILanguageModel::InitializeSafetyChecksComplete, + weak_ptr_factory_.GetWeakPtr(), std::move(input), + std::move(create_client))); + } else { + InitializeSafetyChecksComplete(nullptr, std::move(create_client), + optimization_guide::SafetyChecker::Result()); + } +} + +void AILanguageModel::InitializeSafetyChecksComplete( + on_device_model::mojom::InputPtr input, + mojo::PendingRemote<blink::mojom::AIManagerCreateLanguageModelClient> + create_client, + optimization_guide::SafetyChecker::Result safety_result) { + mojo::Remote<blink::mojom::AIManagerCreateLanguageModelClient> client( + std::move(create_client)); + // TODO(crbug.com/415808003): Add more fine grained errors on safety check + // failure. + if (safety_result.failed_to_run || safety_result.is_unsafe || + safety_result.is_unsupported_language) { + client->OnError( + blink::mojom::AIManagerCreateClientError::kUnableToCreateSession); + return; + } + if (input) { // No ContextClient is passed here since this operation should never be // cancelled unless the session is destroyed. initial_session_->Append(MakeAppendOptions(std::move(input)), {});
diff --git a/chrome/browser/ai/ai_language_model.h b/chrome/browser/ai/ai_language_model.h index 26afc43..36f89e6 100644 --- a/chrome/browser/ai/ai_language_model.h +++ b/chrome/browser/ai/ai_language_model.h
@@ -155,6 +155,11 @@ mojo::PendingRemote<blink::mojom::AIManagerCreateLanguageModelClient> create_client, std::optional<uint32_t> token_count); + void InitializeSafetyChecksComplete( + on_device_model::mojom::InputPtr input, + mojo::PendingRemote<blink::mojom::AIManagerCreateLanguageModelClient> + create_client, + optimization_guide::SafetyChecker::Result safety_result); void ForkInternal( mojo::PendingRemote<blink::mojom::AIManagerCreateLanguageModelClient>
diff --git a/chrome/browser/ai/ai_language_model_unittest.cc b/chrome/browser/ai/ai_language_model_unittest.cc index 5258322..f4245c5 100644 --- a/chrome/browser/ai/ai_language_model_unittest.cc +++ b/chrome/browser/ai/ai_language_model_unittest.cc
@@ -821,6 +821,33 @@ EXPECT_EQ(measure_future.Get(), std::string("UfooEM").size()); } +TEST_F(AILanguageModelTest, TextSafetyInitialPrompts) { + auto config = CreateConfig(); + config.set_can_skip_text_safety(false); + fake_broker_.UpdateModelAdaptation( + optimization_guide::FakeAdaptationAsset({.config = config})); + auto safety_config = CreateSafetyConfig(); + auto* check = safety_config.add_request_check(); + check->mutable_input_template()->Add( + FieldSubstitution("%s", StringValueField())); + optimization_guide::FakeSafetyModelAsset safety_asset( + std::move(safety_config)); + fake_broker_.UpdateSafetyModel(safety_asset.model_info()); + + base::test::TestFuture<blink::mojom::AIManagerCreateClientError> future; + AITestUtils::MockCreateLanguageModelClient language_model_client; + EXPECT_CALL(language_model_client, OnError(_)).WillOnce([&](auto error) { + future.SetValue(error); + }); + + auto options = blink::mojom::AILanguageModelCreateOptions::New(); + options->initial_prompts.push_back(MakePrompt(Role::kSystem, "unsafe")); + GetAIManagerRemote()->CreateLanguageModel( + language_model_client.BindNewPipeAndPassRemote(), std::move(options)); + EXPECT_EQ(future.Take(), + blink::mojom::AIManagerCreateClientError::kUnableToCreateSession); +} + TEST_F(AILanguageModelTest, TextSafetyInput) { auto config = CreateConfig(); config.set_can_skip_text_safety(false);
diff --git a/chrome/browser/ash/boca/on_task/on_task_session_manager_browsertest.cc b/chrome/browser/ash/boca/on_task/on_task_session_manager_browsertest.cc index 20b99ae..e06d2f9 100644 --- a/chrome/browser/ash/boca/on_task/on_task_session_manager_browsertest.cc +++ b/chrome/browser/ash/boca/on_task/on_task_session_manager_browsertest.cc
@@ -445,6 +445,63 @@ } IN_PROC_BROWSER_TEST_F(OnTaskSessionManagerBrowserTest, + ShouldSkipCountdownWhenPauseDuringLockedModeCountdown) { + content::TestNavigationObserver navigation_observer((GURL(kTestUrl1))); + navigation_observer.StartWatchingNewWebContents(); + + // Start OnTask session and spawn one tab outside the homepage tab. + GetOnTaskSessionManager()->OnSessionStarted(kSessionId, + ::boca::UserIdentity()); + ::boca::Bundle bundle; + bundle.add_content_configs()->set_url(kTestUrl1); + GetOnTaskSessionManager()->OnBundleUpdated(bundle); + navigation_observer.Wait(); + + Browser* const boca_app_browser = FindBocaSystemWebAppBrowser(); + ASSERT_THAT(boca_app_browser, NotNull()); + ASSERT_TRUE(boca_app_browser->IsLockedForOnTask()); + auto* const tab_strip_model = boca_app_browser->tab_strip_model(); + ASSERT_EQ(tab_strip_model->count(), 2); + tab_strip_model->ActivateTabAt(1); + EXPECT_EQ(tab_strip_model->GetActiveWebContents()->GetVisibleURL(), + GURL(kTestUrl1)); + + // Lock the boca app. + bundle.set_locked(true); + GetOnTaskSessionManager()->OnBundleUpdated(bundle); + ASSERT_FALSE(platform_util::IsBrowserLockedFullscreen(boca_app_browser)); + + // Pause the boca app. + bundle.set_lock_to_app_home(true); + GetOnTaskSessionManager()->OnBundleUpdated(bundle); + ASSERT_TRUE(platform_util::IsBrowserLockedFullscreen(boca_app_browser)); + EXPECT_FALSE(chromeos::wm::CanFloatWindow( + boca_app_browser->window()->GetNativeWindow())); + const auto* const browser_view = + BrowserView::GetBrowserViewForBrowser(boca_app_browser); + // Wait until immersive mode is disabled in pause mode. + ASSERT_TRUE(base::test::RunUntil([&]() { + return !browser_view->immersive_mode_controller()->IsEnabled(); + })); + EXPECT_EQ(tab_strip_model->GetActiveWebContents()->GetVisibleURL(), + GURL(kChromeBocaAppUntrustedIndexURL)); + + // Unpause the boca app. + bundle.set_lock_to_app_home(false); + GetOnTaskSessionManager()->OnBundleUpdated(bundle); + ASSERT_TRUE(platform_util::IsBrowserLockedFullscreen(boca_app_browser)); + EXPECT_FALSE(chromeos::wm::CanFloatWindow( + boca_app_browser->window()->GetNativeWindow())); + EXPECT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); + + // Unlock the Boca app to unblock test teardown that involves browser window + // close. + bundle.set_locked(false); + GetOnTaskSessionManager()->OnBundleUpdated(bundle); + EXPECT_FALSE(platform_util::IsBrowserLockedFullscreen(boca_app_browser)); +} + +IN_PROC_BROWSER_TEST_F(OnTaskSessionManagerBrowserTest, ShouldNotLockBocaSWAInAppReloadIfLockInProgress) { content::TestNavigationObserver navigation_observer((GURL(kTestUrl1))); navigation_observer.StartWatchingNewWebContents();
diff --git a/chrome/browser/ash/smb_client/smb_url.cc b/chrome/browser/ash/smb_client/smb_url.cc index 2cc4afc2..4179cf28 100644 --- a/chrome/browser/ash/smb_client/smb_url.cc +++ b/chrome/browser/ash/smb_client/smb_url.cc
@@ -133,8 +133,9 @@ url::StdStringCanonOutput canonical_output(&url_); url::Component scheme; - if (!url::CanonicalizeScheme(url.c_str(), initial_parsed.scheme, - &canonical_output, &scheme)) { + if (!url::CanonicalizeScheme( + initial_parsed.scheme.as_string_view_on(url.c_str()), + &canonical_output, &scheme)) { Reset(); return; }
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc index c0e1f21e..92259b4 100644 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
@@ -12,6 +12,7 @@ #include "base/strings/cstring_view.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "chrome/browser/ui/lens/lens_overlay_entry_point_controller.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" #include "chrome/browser/autocomplete/document_suggestions_service_factory.h" @@ -41,6 +42,7 @@ #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/ui/browser_command_controller.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_window/public/browser_window_features.h" #include "chrome/browser/ui/omnibox/omnibox_pedal_implementations.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" @@ -537,6 +539,21 @@ return history_embeddings::IsHistoryEmbeddingsSettingVisible(profile_); } +bool ChromeAutocompleteProviderClient::IsLensEnabled() const { +#if !BUILDFLAG(IS_ANDROID) + if (auto* lens_search_controller = + GetLensSearchController(GetWebContents(web_contents_getter_))) { + // Guaranteed to exist if lens_search_controller is not null. + return lens_search_controller->GetTabInterface() + ->GetBrowserWindowInterface() + ->GetFeatures() + .lens_overlay_entry_point_controller() + ->IsEnabled(); + } +#endif + return false; +} + base::CallbackListSubscription ChromeAutocompleteProviderClient::GetLensSuggestInputsWhenReady( LensOverlaySuggestInputsCallback callback) const {
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h index 0f8c25c..bd8cd189 100644 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h
@@ -121,6 +121,7 @@ bool IsSharingHubAvailable() const override; bool IsHistoryEmbeddingsEnabled() const override; bool IsHistoryEmbeddingsSettingVisible() const override; + bool IsLensEnabled() const override; base::CallbackListSubscription GetLensSuggestInputsWhenReady( LensOverlaySuggestInputsCallback callback) const override; base::WeakPtr<AutocompleteProviderClient> GetWeakPtr() override;
diff --git a/chrome/browser/background/glic/BUILD.gn b/chrome/browser/background/glic/BUILD.gn index dfb0b9f..98de8e7 100644 --- a/chrome/browser/background/glic/BUILD.gn +++ b/chrome/browser/background/glic/BUILD.gn
@@ -66,6 +66,7 @@ "//chrome/browser/glic:glic", "//chrome/browser/status_icons:status_icons", "//chrome/browser/ui", + "//chrome/browser/ui:ui_features", "//chrome/browser/ui/webui/whats_new:whats_new", "//chrome/common:chrome_features", "//chrome/test:test_support",
diff --git a/chrome/browser/background/glic/glic_status_icon_unittest.cc b/chrome/browser/background/glic/glic_status_icon_unittest.cc index 3f2f0c3..782ecbda 100644 --- a/chrome/browser/background/glic/glic_status_icon_unittest.cc +++ b/chrome/browser/background/glic/glic_status_icon_unittest.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/status_icons/status_icon.h" #include "chrome/browser/status_icons/status_tray.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/webui/whats_new/whats_new_ui.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/fake_profile_manager.h"
diff --git a/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationIntegrationTest.java b/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationIntegrationTest.java index 4033112..c7900ff 100644 --- a/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationIntegrationTest.java +++ b/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationIntegrationTest.java
@@ -208,7 +208,11 @@ mActivityTestRule.loadUrlInNewTab(mUrl); final AtomicBoolean joinCalled = new AtomicBoolean(); - mDataSharingUIDelegate.setShowJoinFlowRunnable(() -> joinCalled.set(true)); + Callback<Boolean> callback = + (success) -> { + joinCalled.set(true); + }; + mDataSharingUIDelegate.setShowJoinFlowCallback(callback); setFakePreviewData(); // Verify that the fullscreen sign-in promo is shown and accept.
diff --git a/chrome/browser/contextual_cueing/BUILD.gn b/chrome/browser/contextual_cueing/BUILD.gn index bc6e7a0..4c20fd8c 100644 --- a/chrome/browser/contextual_cueing/BUILD.gn +++ b/chrome/browser/contextual_cueing/BUILD.gn
@@ -85,6 +85,7 @@ "//chrome/browser:global_features", "//chrome/browser/content_extraction", "//chrome/browser/optimization_guide:test_support", + "//chrome/browser/ui:ui_features", "//chrome/common:buildflags", "//chrome/test:test_support", "//components/sync_preferences:test_support",
diff --git a/chrome/browser/contextual_cueing/contextual_cueing_helper_unittest.cc b/chrome/browser/contextual_cueing/contextual_cueing_helper_unittest.cc index 87ae3758..e0cee5b 100644 --- a/chrome/browser/contextual_cueing/contextual_cueing_helper_unittest.cc +++ b/chrome/browser/contextual_cueing/contextual_cueing_helper_unittest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" #include "chrome/browser/page_content_annotations/page_content_extraction_service.h" #include "chrome/browser/page_content_annotations/page_content_extraction_service_factory.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h"
diff --git a/chrome/browser/contextual_cueing/contextual_cueing_service_browsertest.cc b/chrome/browser/contextual_cueing/contextual_cueing_service_browsertest.cc index 1d10714..318d176 100644 --- a/chrome/browser/contextual_cueing/contextual_cueing_service_browsertest.cc +++ b/chrome/browser/contextual_cueing/contextual_cueing_service_browsertest.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/buildflags.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h"
diff --git a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/FakeDataSharingUIDelegateImpl.java b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/FakeDataSharingUIDelegateImpl.java index d26e753..67212c5 100644 --- a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/FakeDataSharingUIDelegateImpl.java +++ b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/FakeDataSharingUIDelegateImpl.java
@@ -20,10 +20,12 @@ @NullMarked public class FakeDataSharingUIDelegateImpl implements DataSharingUIDelegate { - private @Nullable Runnable mShowJoinFlowRunnable; private @Nullable Callback<Boolean> mShowCreateFlowCallback; - private @Nullable Runnable mShowManageFlowRunnable; + private @Nullable Callback<Boolean> mShowJoinFlowCallback; + private @Nullable Callback<Boolean> mShowManageFlowCallback; private @Nullable DataSharingCreateUiConfig mCreateUiConfig; + private @Nullable DataSharingJoinUiConfig mJoinUiConfig; + private @Nullable DataSharingManageUiConfig mManageUiConfig; public FakeDataSharingUIDelegateImpl() {} @@ -45,13 +47,21 @@ @Override public String showJoinFlow(DataSharingJoinUiConfig joinUiConfig) { - if (mShowJoinFlowRunnable != null) mShowJoinFlowRunnable.run(); + assert this.mJoinUiConfig == null; + this.mJoinUiConfig = joinUiConfig; + if (mShowJoinFlowCallback != null) { + mShowJoinFlowCallback.onResult(true); + } return ""; } @Override public String showManageFlow(DataSharingManageUiConfig manageUiConfig) { - if (mShowManageFlowRunnable != null) mShowManageFlowRunnable.run(); + assert this.mManageUiConfig == null; + this.mManageUiConfig = manageUiConfig; + if (mShowManageFlowCallback != null) { + mShowManageFlowCallback.onResult(true); + } return ""; } @@ -62,19 +72,19 @@ @Override public void destroyFlow(String sessionId) {} - /* Set a runnable to be called when showJoinFlow() is called. */ - public void setShowJoinFlowRunnable(Runnable runnable) { - mShowJoinFlowRunnable = runnable; - } - /* Set a callback to be called when showCreateFlow() is called. */ public void setShowCreateFlowCallback(Callback<Boolean> callback) { mShowCreateFlowCallback = callback; } - /* Set a runnable to be called when showManageFlow() is called. */ - public void setShowManageFlowRunnable(Runnable runnable) { - mShowManageFlowRunnable = runnable; + /* Set a callback to be called when showJoinFlow() is called. */ + public void setShowJoinFlowCallback(Callback<Boolean> callback) { + mShowJoinFlowCallback = callback; + } + + /* Set a callback to be called when showManageFlow() is called. */ + public void setShowManageFlowCallback(Callback<Boolean> callback) { + mShowManageFlowCallback = callback; } /* Creates group data and calls onGroupCreatedWithWait when showCreateFlow() is called. */
diff --git a/chrome/browser/enterprise/client_certificates/cert_utils.cc b/chrome/browser/enterprise/client_certificates/cert_utils.cc index f993222..47bc1b91 100644 --- a/chrome/browser/enterprise/client_certificates/cert_utils.cc +++ b/chrome/browser/enterprise/client_certificates/cert_utils.cc
@@ -11,6 +11,11 @@ #include "components/enterprise/client_certificates/core/private_key_types.h" #include "components/enterprise/client_certificates/core/unexportable_private_key_factory.h" +#if BUILDFLAG(IS_WIN) +#include "components/enterprise/client_certificates/core/features.h" +#include "components/enterprise/client_certificates/core/win/windows_software_private_key_factory.h" +#endif // BUILDFLAG(IS_WIN) + namespace client_certificates { namespace { @@ -34,6 +39,18 @@ sub_factories.insert_or_assign(PrivateKeySource::kUnexportableKey, std::move(unexportable_key_factory)); } + +#if BUILDFLAG(IS_WIN) + if (features::AreWindowsSoftwareKeysEnabled()) { + auto windows_software_key_factory = + WindowsSoftwarePrivateKeyFactory::TryCreate(); + if (windows_software_key_factory) { + sub_factories.insert_or_assign(PrivateKeySource::kOsSoftwareKey, + std::move(windows_software_key_factory)); + } + } +#endif // BUILDFLAG(IS_WIN) + sub_factories.insert_or_assign(PrivateKeySource::kSoftwareKey, std::make_unique<ECPrivateKeyFactory>());
diff --git a/chrome/browser/extensions/api/cookies/cookies_api.cc b/chrome/browser/extensions/api/cookies/cookies_api.cc index d4d7cfd..c40f736 100644 --- a/chrome/browser/extensions/api/cookies/cookies_api.cc +++ b/chrome/browser/extensions/api/cookies/cookies_api.cc
@@ -138,12 +138,8 @@ CookiesEventRouter::CookiesEventRouter(content::BrowserContext* context) : profile_(Profile::FromBrowserContext(context)), - profile_observation_(this) -#if !BUILDFLAG(IS_ANDROID) - , - otr_profile_observation_(this) -#endif -{ + profile_observation_(this), + otr_profile_observation_(this) { MaybeStartListening(); profile_observation_.Observe(profile_); } @@ -226,9 +222,7 @@ } DCHECK(!otr_receiver_.is_bound()); -#if !BUILDFLAG(IS_ANDROID) otr_profile_observation_.Observe(off_the_record); -#endif BindToCookieManager(&otr_receiver_, off_the_record); } @@ -239,9 +233,7 @@ ? original_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true) : nullptr; if (profile == otr_profile) { -#if !BUILDFLAG(IS_ANDROID) otr_profile_observation_.Reset(); -#endif otr_receiver_.reset(); } } @@ -261,9 +253,7 @@ } if (!otr_receiver_.is_bound() && otr_profile) { -#if !BUILDFLAG(IS_ANDROID) otr_profile_observation_.Observe(otr_profile); -#endif BindToCookieManager(&otr_receiver_, otr_profile); } }
diff --git a/chrome/browser/extensions/api/cookies/cookies_api.h b/chrome/browser/extensions/api/cookies/cookies_api.h index 5e01d7b..645f423e 100644 --- a/chrome/browser/extensions/api/cookies/cookies_api.h +++ b/chrome/browser/extensions/api/cookies/cookies_api.h
@@ -89,11 +89,7 @@ base::ScopedObservation<Profile, ProfileObserver> profile_observation_; -#if !BUILDFLAG(IS_ANDROID) - // TODO(crbug.com/414825266): This is causing check failure on clank. - // Fix the root cause and remove `!ifdef android`. base::ScopedObservation<Profile, ProfileObserver> otr_profile_observation_; -#endif // To listen to cookie changes in both the original and the off the record // profiles, we need a pair of bindings, as well as a pair of
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc index 33a7308c..719f71e 100644 --- a/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc
@@ -681,7 +681,14 @@ << "a specific tab id."; } -IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, IncognitoBasic) { +// TODO(crbug.com/414519997): Flaky on Linux_ASan_LSan. +#if defined(SANITIZER_LINUX) +#define MAYBE_IncognitoBasic DISABLED_IncognitoBasic +#else +#define MAYBE_IncognitoBasic IncognitoBasic +#endif +IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, + MAYBE_IncognitoBasic) { ExtensionTestMessageListener ready_listener("ready"); ASSERT_TRUE(embedded_test_server()->Start()); scoped_refptr<const Extension> extension =
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc index f2ae7a8..067c5c07 100644 --- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc +++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -356,12 +356,8 @@ // in the manifest. if (!popup_string->empty()) { popup_url = extension()->GetResourceURL(*popup_string); - // Validate popup is same-origin (only for this extension). We do not - // validate the file exists (like we do in manifest validation) because an - // extension could potentially intercept the request with a service worker - // and dynamically provide content. - if (!extension()->origin().IsSameOriginWith(popup_url)) { - return RespondNow(Error(manifest_errors::kInvalidExtensionOriginPopup)); + if (!popup_url.is_valid()) { + return RespondNow(Error(manifest_errors::kInvalidExtensionPopupPath)); } }
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc index db8633d..6c9e5e36 100644 --- a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc
@@ -1198,7 +1198,7 @@ auto get_script = [](int tab_id, const char* popup_input) { constexpr char kSetPopup[] = R"(setPopup({tabId: %d, popup: '%s'}, "%s");)"; return base::StringPrintf(kSetPopup, tab_id, popup_input, - manifest_errors::kInvalidExtensionOriginPopup); + manifest_errors::kInvalidExtensionPopupPath); }; content::RenderFrameHost* navigated_host = ui_test_utils::NavigateToURL(
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc index 5733c45..d6eb366 100644 --- a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc +++ b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
@@ -20,7 +20,7 @@ #include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_enums.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/tabs/tab_utils.h" @@ -298,11 +298,11 @@ const base::TimeTicks start_time = base::TimeTicks::Now(); IndicatorChangeObserver observer(browser()); while (!base::Contains(GetTabAlertStatesForContents(contents), - TabAlertState::TAB_CAPTURING)) { + tabs::TabAlert::TAB_CAPTURING)) { if (base::TimeTicks::Now() - start_time > TestTimeouts::action_max_timeout()) { EXPECT_THAT(GetTabAlertStatesForContents(contents), - ::testing::Contains(TabAlertState::TAB_CAPTURING)); + ::testing::Contains(tabs::TabAlert::TAB_CAPTURING)); return; } observer.WaitForTabChange();
diff --git a/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc b/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc index 37e82c6..050e49ed 100644 --- a/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc +++ b/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc
@@ -398,7 +398,7 @@ } TabStripModel* source_tab_strip = source_browser->tab_strip_model(); - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = source_tab_strip->DetachTabGroupForInsertion(group); target_tab_strip->InsertDetachedTabGroupAt(std::move(detached_group), new_index);
diff --git a/chrome/browser/extensions/api/tab_groups/tab_groups_api_apitest.cc b/chrome/browser/extensions/api/tab_groups/tab_groups_api_apitest.cc index 6c357f5..16f9008 100644 --- a/chrome/browser/extensions/api/tab_groups/tab_groups_api_apitest.cc +++ b/chrome/browser/extensions/api/tab_groups/tab_groups_api_apitest.cc
@@ -77,7 +77,7 @@ TestEventRouterObserver event_observer( EventRouter::Get(browser()->profile())); - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = browser()->tab_strip_model()->DetachTabGroupForInsertion(group); event_observer.WaitForEventWithName(api::tab_groups::OnRemoved::kEventName);
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc index 8a3b929..833d62b9 100644 --- a/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -1765,7 +1765,7 @@ TestEventRouterObserver event_observer( EventRouter::Get(browser()->profile())); - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = browser()->tab_strip_model()->DetachTabGroupForInsertion(group); event_observer.WaitForEventWithName(api::tabs::OnUpdated::kEventName);
diff --git a/chrome/browser/extensions/chrome_url_request_util.cc b/chrome/browser/extensions/chrome_url_request_util.cc index 2a904ccf..4ec6c633 100644 --- a/chrome/browser/extensions/chrome_url_request_util.cc +++ b/chrome/browser/extensions/chrome_url_request_util.cc
@@ -298,10 +298,11 @@ const base::FilePath request_relative_path = extensions::file_util::ExtensionURLToRelativeFilePath(request.url); - if (!ExtensionsBrowserClient::Get() - ->GetComponentExtensionResourceManager() - ->IsComponentExtensionResource(extension_resources_path, - request_relative_path, resource_id)) { + auto* manager = + ExtensionsBrowserClient::Get()->GetComponentExtensionResourceManager(); + CHECK(manager); + if (!manager->IsComponentExtensionResource( + extension_resources_path, request_relative_path, resource_id)) { return base::FilePath(); } DCHECK_NE(0, *resource_id);
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index c2b4aff..4bb691e 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -326,7 +326,13 @@ DCHECK(!system_->is_ready()); // Can't redo init. DCHECK_EQ(registry_->enabled_extensions().size(), 0u); +// TODO(crbug.com/417617863): Skip loading component extensions until the +// startup crash is fixed on desktop Android (see bug). +#if BUILDFLAG(ENABLE_EXTENSIONS) component_loader_->LoadAll(); +#else + LOG(WARNING) << "Skipping component extension load."; +#endif bool load_saved_extensions = true; bool load_command_line_extensions = extension_registrar_->extensions_enabled();
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 836a9ed1..9ebf3ae 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -4103,6 +4103,9 @@ } #endif // defined(ENABLE_BLOCKLIST_TESTS) +// TODO(crbug.com/417617863): Skip loading component extensions until the +// startup crash is fixed on desktop Android (see bug). +#if BUILDFLAG(ENABLE_EXTENSIONS) // Tests blocking then unblocking enabled component extensions after the service // has been initialized. TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledComponentExtension) { @@ -4123,6 +4126,7 @@ // Component extension should never block. AssertExtensionBlocksAndUnblocks(false, good0); } +#endif // Tests blocking then unblocking a theme after the service has been // initialized. @@ -4205,6 +4209,9 @@ EXPECT_EQ(0u, registry()->enabled_extensions().size()); } +// TODO(crbug.com/417617863): Skip loading component extensions until the +// startup crash is fixed on desktop Android (see bug). +#if BUILDFLAG(ENABLE_EXTENSIONS) // Tests that component extensions are not blocklisted by policy. TEST_F(ExtensionServiceTest, ComponentExtensionAllowlisted) { InitializeEmptyExtensionServiceWithTestingPrefs(); @@ -4286,6 +4293,7 @@ ->active_permissions() .HasAPIPermission(APIPermissionID::kTab)); } +#endif // Tests that policy-installed extensions are not blocklisted by policy. TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsAllowlisted) { @@ -6976,6 +6984,9 @@ loaded_extensions()[2]->url())); } +// TODO(crbug.com/417617863): Skip loading component extensions until the +// startup crash is fixed on desktop Android (see bug). +#if BUILDFLAG(ENABLE_EXTENSIONS) // Tests ComponentLoader::Add(). TEST_F(ExtensionServiceTest, ComponentExtensions) { // Component extensions should work even when extensions are disabled. @@ -7012,6 +7023,7 @@ ASSERT_EQ(1u, registry()->enabled_extensions().size()); EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id()); } +#endif TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) { InitializeEmptyExtensionService();
diff --git a/chrome/browser/glic/BUILD.gn b/chrome/browser/glic/BUILD.gn index 66a1e6d..3e3827c4 100644 --- a/chrome/browser/glic/BUILD.gn +++ b/chrome/browser/glic/BUILD.gn
@@ -180,6 +180,7 @@ "//chrome/browser/ui:browser_element_identifiers", "//chrome/browser/ui:browser_list", "//chrome/browser/ui:browser_navigator_params_headers", + "//chrome/browser/ui:ui_features", "//chrome/browser/ui/browser_window:browser_window", "//chrome/browser/ui/tabs:tab_strip", "//chrome/browser/ui/user_education", @@ -249,6 +250,7 @@ deps = [ ":glic", ":impl", + "//chrome/browser/ui:ui_features", "//components/signin/public/identity_manager:test_support", "//ui/events:test_support", ] @@ -280,6 +282,7 @@ "//chrome/browser/prefs:prefs", "//chrome/browser/status_icons:status_icons", "//chrome/browser/ui", + "//chrome/browser/ui:ui_features", "//chrome/common:chrome_features", "//chrome/test:test_support", "//components/live_caption:constants", @@ -316,6 +319,7 @@ "//chrome/browser/policy:test_support", "//chrome/browser/prefs:prefs", "//chrome/browser/ui", + "//chrome/browser/ui:ui_features", "//chrome/common:constants", "//chrome/test:test_support", "//chrome/test:test_support_ui",
diff --git a/chrome/browser/glic/browser_ui/glic_button_controller_unittest.cc b/chrome/browser/glic/browser_ui/glic_button_controller_unittest.cc index 3aa9c5bb..080ae66 100644 --- a/chrome/browser/glic/browser_ui/glic_button_controller_unittest.cc +++ b/chrome/browser/glic/browser_ui/glic_button_controller_unittest.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/global_features.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h"
diff --git a/chrome/browser/glic/browser_ui/glic_tab_indicator_helper_interactive_uitest.cc b/chrome/browser/glic/browser_ui/glic_tab_indicator_helper_interactive_uitest.cc index 870e8cb..5149de8 100644 --- a/chrome/browser/glic/browser_ui/glic_tab_indicator_helper_interactive_uitest.cc +++ b/chrome/browser/glic/browser_ui/glic_tab_indicator_helper_interactive_uitest.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/glic/test_support/interactive_glic_test.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_element_identifiers.h" -#include "chrome/browser/ui/tabs/tab_enums.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/tabs/tab_close_button.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" @@ -28,7 +28,7 @@ namespace { class TabAlertStateObserver - : public ui::test::PollingStateObserver<std::vector<TabAlertState>> { + : public ui::test::PollingStateObserver<std::vector<tabs::TabAlert>> { public: TabAlertStateObserver(Browser* browser, int tab_index) : PollingStateObserver([browser, tab_index]() { @@ -39,7 +39,7 @@ auto* const tab = tab_strip->tab_at(tab_index); return tab->data().alert_state; } - return std::vector<TabAlertState>(); + return std::vector<tabs::TabAlert>(); }) {} ~TabAlertStateObserver() override = default; }; @@ -60,12 +60,12 @@ ~GlicTabIndicatorHelperUiTest() override = default; static auto IsAccessing() { - return testing::Matcher<std::vector<TabAlertState>>( - testing::Contains(TabAlertState::GLIC_ACCESSING)); + return testing::Matcher<std::vector<tabs::TabAlert>>( + testing::Contains(tabs::TabAlert::GLIC_ACCESSING)); } static auto IsNotAccessing() { - return testing::Matcher<std::vector<TabAlertState>>( - testing::Not(testing::Contains(TabAlertState::GLIC_ACCESSING))); + return testing::Matcher<std::vector<tabs::TabAlert>>( + testing::Not(testing::Contains(tabs::TabAlert::GLIC_ACCESSING))); } GURL GetTestUrl() const {
diff --git a/chrome/browser/glic/e2e_test/BUILD.gn b/chrome/browser/glic/e2e_test/BUILD.gn index c3c4e951..c43630a 100644 --- a/chrome/browser/glic/e2e_test/BUILD.gn +++ b/chrome/browser/glic/e2e_test/BUILD.gn
@@ -32,6 +32,7 @@ "//chrome/browser/glic:impl", "//chrome/browser/glic:test_support", "//chrome/browser/signin/e2e_tests:test_support", + "//chrome/browser/ui:ui_features", "//chrome/common:constants", "//chrome/test:test_support", "//chrome/test:test_support_ui",
diff --git a/chrome/browser/glic/e2e_test/glic_e2e_test.cc b/chrome/browser/glic/e2e_test/glic_e2e_test.cc index 0cc9838..ded413aa 100644 --- a/chrome/browser/glic/e2e_test/glic_e2e_test.cc +++ b/chrome/browser/glic/e2e_test/glic_e2e_test.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/signin/e2e_tests/signin_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_element_identifiers.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/glic/fre/glic_fre.mojom b/chrome/browser/glic/fre/glic_fre.mojom index 6556a27c..f69f3a6 100644 --- a/chrome/browser/glic/fre/glic_fre.mojom +++ b/chrome/browser/glic/fre/glic_fre.mojom
@@ -34,6 +34,7 @@ WebUiStateChanged(FreWebUiState new_state); }; +// LINT.IfChange(FreWebUiState) enum FreWebUiState { // Glic fre app controller not started. kUninitialized, @@ -54,4 +55,5 @@ kOffline, // Web view is displayed. kReady, -}; \ No newline at end of file +}; +// LINT.ThenChange(//tools/metrics/histograms/metadata/glic/enums.xml:FreWebUiState) \ No newline at end of file
diff --git a/chrome/browser/glic/fre/glic_fre_controller.cc b/chrome/browser/glic/fre/glic_fre_controller.cc index aa83a816e..646d00a 100644 --- a/chrome/browser/glic/fre/glic_fre_controller.cc +++ b/chrome/browser/glic/fre/glic_fre_controller.cc
@@ -52,21 +52,23 @@ GlicFreController::~GlicFreController() = default; void GlicFreController::WebUiStateChanged(mojom::FreWebUiState new_state) { - if (webui_state_ != new_state) { - // UI State has changed - webui_state_ = new_state; - webui_state_callback_list_.Notify(webui_state_); - - // It is possible for the FRE to open directly in an error state. In this - // case, we should not record the FRE load time metric if the content is - // loaded at a later point. - if (new_state == mojom::FreWebUiState::kError || - new_state == mojom::FreWebUiState::kOffline) { - show_start_time_ = base::TimeTicks(); - } - - RecordMetricsIfDialogIsShowingAndReady(); + if (webui_state_ == new_state) { + return; } + + // UI State has changed + webui_state_ = new_state; + webui_state_callback_list_.Notify(webui_state_); + + // It is possible for the FRE to open directly in an error state. In this + // case, we should not record the FRE load time metric if the content is + // loaded at a later point. + if (new_state == mojom::FreWebUiState::kError || + new_state == mojom::FreWebUiState::kOffline) { + show_start_time_ = base::TimeTicks(); + } + + RecordMetricsIfDialogIsShowingAndReady(); } base::CallbackListSubscription GlicFreController::AddWebUiStateChangedCallback( @@ -216,6 +218,8 @@ } void GlicFreController::DismissFre() { + base::UmaHistogramEnumeration("Glic.FreModalWebUiState.FinishState", + webui_state_); web_contents_ = nullptr; source_browser_ = nullptr; if (fre_view_ || fre_widget_) {
diff --git a/chrome/browser/glic/fre/glic_fre_controller_unittest.cc b/chrome/browser/glic/fre/glic_fre_controller_unittest.cc index 950061e..061b97d 100644 --- a/chrome/browser/glic/fre/glic_fre_controller_unittest.cc +++ b/chrome/browser/glic/fre/glic_fre_controller_unittest.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/glic/glic_pref_names.h" #include "chrome/browser/global_features.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/glic/glic_browsertest.cc b/chrome/browser/glic/glic_browsertest.cc index dfa3025..ebf829e4 100644 --- a/chrome/browser/glic/glic_browsertest.cc +++ b/chrome/browser/glic/glic_browsertest.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/glic/test_support/glic_test_util.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/webui_url_constants.h"
diff --git a/chrome/browser/glic/glic_enabling.cc b/chrome/browser/glic/glic_enabling.cc index 287f682f..b2e14a0 100644 --- a/chrome/browser/glic/glic_enabling.cc +++ b/chrome/browser/glic/glic_enabling.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/signin/identity_manager_factory.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/glic/glic_enabling_browsertest.cc b/chrome/browser/glic/glic_enabling_browsertest.cc index fff1ede3..4c5c8c7f 100644 --- a/chrome/browser/glic/glic_enabling_browsertest.cc +++ b/chrome/browser/glic/glic_enabling_browsertest.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_test_util.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/glic/glic_enabling_unittest.cc b/chrome/browser/glic/glic_enabling_unittest.cc index 4e916c7..ea757510 100644 --- a/chrome/browser/glic/glic_enabling_unittest.cc +++ b/chrome/browser/glic/glic_enabling_unittest.cc
@@ -7,6 +7,7 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/glic/test_support/glic_test_util.h" #include "chrome/browser/global_features.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/testing_browser_process.h"
diff --git a/chrome/browser/glic/glic_metrics_unittest.cc b/chrome/browser/glic/glic_metrics_unittest.cc index f78b956..15b5b880 100644 --- a/chrome/browser/glic/glic_metrics_unittest.cc +++ b/chrome/browser/glic/glic_metrics_unittest.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/status_icons/status_icon.h" #include "chrome/browser/status_icons/status_icon_menu_model.h" #include "chrome/browser/status_icons/status_tray.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/scoped_testing_local_state.h"
diff --git a/chrome/browser/glic/glic_profile_manager_browsertest.cc b/chrome/browser/glic/glic_profile_manager_browsertest.cc index 38c670a..d6b6395 100644 --- a/chrome/browser/glic/glic_profile_manager_browsertest.cc +++ b/chrome/browser/glic/glic_profile_manager_browsertest.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/test_browser_window.h"
diff --git a/chrome/browser/glic/glic_user_status_browsertest.cc b/chrome/browser/glic/glic_user_status_browsertest.cc index 4f50aec7..b3c8607 100644 --- a/chrome/browser/glic/glic_user_status_browsertest.cc +++ b/chrome/browser/glic/glic_user_status_browsertest.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/glic/host/context/glic_page_context_eligibility_observer_browsertest.cc b/chrome/browser/glic/host/context/glic_page_context_eligibility_observer_browsertest.cc index b6a57ca..36f4d3eb 100644 --- a/chrome/browser/glic/host/context/glic_page_context_eligibility_observer_browsertest.cc +++ b/chrome/browser/glic/host/context/glic_page_context_eligibility_observer_browsertest.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/public/tab_features.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/glic/host/guest_util_browsertest.cc b/chrome/browser/glic/host/guest_util_browsertest.cc index 6fb8f33..07cba9c 100644 --- a/chrome/browser/glic/host/guest_util_browsertest.cc +++ b/chrome/browser/glic/host/guest_util_browsertest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/webui_url_constants.h"
diff --git a/chrome/browser/glic/resources/internal b/chrome/browser/glic/resources/internal index aeb59fb..3784a74 160000 --- a/chrome/browser/glic/resources/internal +++ b/chrome/browser/glic/resources/internal
@@ -1 +1 @@ -Subproject commit aeb59fb12f8363ded7b2f1052956e538808c5daf +Subproject commit 3784a743ccebd82808a50e14e99db28643e95bac
diff --git a/chrome/browser/glic/test_support/interactive_glic_test.h b/chrome/browser/glic/test_support/interactive_glic_test.h index 6f5c84cd..eb3c688 100644 --- a/chrome/browser/glic/test_support/interactive_glic_test.h +++ b/chrome/browser/glic/test_support/interactive_glic_test.h
@@ -30,6 +30,7 @@ #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_element_identifiers.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/glic/widget/glic_window_controller.h b/chrome/browser/glic/widget/glic_window_controller.h index 01bc4d3..ae3d4dd 100644 --- a/chrome/browser/glic/widget/glic_window_controller.h +++ b/chrome/browser/glic/widget/glic_window_controller.h
@@ -212,13 +212,11 @@ // * Waiting for glic to load (the open animation has finished, but the // glic window contents is not yet ready) // * Open (aka showing, visible) - // * Detaching // * ClosingToReopenDetached enum class State { kClosed, kWaitingForGlicToLoad, kOpen, - kDetaching, kClosingToReopenDetached, }; virtual State state() const = 0;
diff --git a/chrome/browser/glic/widget/glic_window_controller_impl.cc b/chrome/browser/glic/widget/glic_window_controller_impl.cc index c970f082..79fd550 100644 --- a/chrome/browser/glic/widget/glic_window_controller_impl.cc +++ b/chrome/browser/glic/widget/glic_window_controller_impl.cc
@@ -73,7 +73,6 @@ // Default value for adding a buffer to the attachment zone. constexpr static int kAttachmentBuffer = 20; -constexpr static int kDetachYDistance = 36; constexpr static int kInitialPositionBuffer = 4; constexpr static int kMaxWidgetSize = 16'384; @@ -882,19 +881,12 @@ if (state_ != State::kOpen || !attached_browser_) { return; } - SetWindowState(State::kDetaching); + if (!AlwaysDetached()) { // TODO(crbug.com/410629338): Reimplement attachment. } - // Move down a little bit when detaching. - gfx::Point new_position = glic_widget_->GetWindowBoundsInScreen().origin(); - new_position.set_y(new_position.y() + kDetachYDistance); - - glic_window_animator_->AnimatePosition( - new_position, kAnimationDuration, - base::BindOnce(&GlicWindowControllerImpl::DetachFinished, - weak_ptr_factory_.GetWeakPtr())); + NOTIMPLEMENTED(); } void GlicWindowControllerImpl::DetachFinished() { @@ -935,9 +927,8 @@ glic_size_ = size; glic_service_->metrics()->OnGlicWindowResize(); - const bool in_resizable_state = state_ == State::kOpen || - state_ == State::kWaitingForGlicToLoad || - state_ == State::kDetaching; + const bool in_resizable_state = + state_ == State::kOpen || state_ == State::kWaitingForGlicToLoad; // TODO(https://crbug.com/379164689): Drive resize animations for error states // from the browser. For now, we allow animations during the waiting state. @@ -1112,6 +1103,9 @@ // lead to crashes. if (!in_move_loop_) { in_move_loop_ = true; +#if BUILDFLAG(IS_MAC) + GetGlicWidget()->SetCapture(nullptr); +#endif const views::Widget::MoveLoopSource move_loop_source = views::Widget::MoveLoopSource::kMouse; if (!AlwaysDetached()) { @@ -1411,8 +1405,7 @@ } void GlicWindowControllerImpl::MaybeAdjustSizeForDisplay(bool animate) { - if (state_ == State::kOpen || state_ == State::kWaitingForGlicToLoad || - state_ == State::kDetaching) { + if (state_ == State::kOpen || state_ == State::kWaitingForGlicToLoad) { const auto target_size = GetLastRequestedSizeClamped(); if (target_size != glic_window_animator_->GetCurrentTargetBounds().size()) { glic_window_animator_->AnimateSize(
diff --git a/chrome/browser/lifetime/browser_close_manager_browsertest.cc b/chrome/browser/lifetime/browser_close_manager_browsertest.cc index 1240a025..7f1c3a8 100644 --- a/chrome/browser/lifetime/browser_close_manager_browsertest.cc +++ b/chrome/browser/lifetime/browser_close_manager_browsertest.cc
@@ -43,6 +43,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/buildflags.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h"
diff --git a/chrome/browser/mac/auth_session_request.mm b/chrome/browser/mac/auth_session_request.mm index 769d5099..7cb84e87 100644 --- a/chrome/browser/mac/auth_session_request.mm +++ b/chrome/browser/mac/auth_session_request.mm
@@ -177,9 +177,7 @@ std::string scheme) { url::RawCanonOutputT<char> canon_output; url::Component component; - bool result = url::CanonicalizeScheme( - scheme.data(), url::Component(0, static_cast<int>(scheme.size())), - &canon_output, &component); + bool result = url::CanonicalizeScheme(scheme, &canon_output, &component); if (!result) return std::nullopt;
diff --git a/chrome/browser/media/cast_mirroring_service_host_browsertest.cc b/chrome/browser/media/cast_mirroring_service_host_browsertest.cc index 0a08f0f1..092801c 100644 --- a/chrome/browser/media/cast_mirroring_service_host_browsertest.cc +++ b/chrome/browser/media/cast_mirroring_service_host_browsertest.cc
@@ -17,7 +17,7 @@ #include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_enums.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" @@ -437,11 +437,11 @@ // Run the browser until the indicator turns on. const base::TimeTicks start_time = base::TimeTicks::Now(); while (!base::Contains(GetTabAlertStatesForContents(contents), - TabAlertState::TAB_CAPTURING)) { + tabs::TabAlert::TAB_CAPTURING)) { if (base::TimeTicks::Now() - start_time > TestTimeouts::action_max_timeout()) { EXPECT_THAT(GetTabAlertStatesForContents(contents), - ::testing::Contains(TabAlertState::TAB_CAPTURING)); + ::testing::Contains(tabs::TabAlert::TAB_CAPTURING)); return; } observer.WaitForTabChange();
diff --git a/chrome/browser/net/device_bound_sessions_browsertest.cc b/chrome/browser/net/device_bound_sessions_browsertest.cc index fda677b9..3d07e49 100644 --- a/chrome/browser/net/device_bound_sessions_browsertest.cc +++ b/chrome/browser/net/device_bound_sessions_browsertest.cc
@@ -11,6 +11,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "chrome/test/base/web_feature_histogram_tester.h" +#include "components/metrics/content/subprocess_metrics_provider.h" #include "components/unexportable_keys/features.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/test/browser_test.h" @@ -19,6 +20,7 @@ #include "net/cookies/canonical_cookie_test_helpers.h" #include "net/device_bound_sessions/session_access.h" #include "net/device_bound_sessions/session_key.h" +#include "net/device_bound_sessions/session_usage.h" #include "net/device_bound_sessions/test_support.h" #include "net/test/embedded_test_server/http_response.h" #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h" @@ -280,4 +282,55 @@ 2); } +IN_PROC_BROWSER_TEST_F(DeviceBoundSessionBrowserTest, NotDeferredLogs) { + base::HistogramTester histogram_tester; + + base::test::TestFuture<SessionAccess> future; + DeviceBoundSessionAccessObserver observer( + browser()->tab_strip_model()->GetActiveWebContents(), + future.GetRepeatingCallback<const SessionAccess&>()); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), + embedded_test_server()->GetURL("/resource_triggered_dbsc_registration"))); + + ASSERT_TRUE(future.Wait()); + + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL("/ensure_authenticated"))); + + metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + histogram_tester.ExpectBucketCount( + "Net.DeviceBoundSessions.RequestDeferralDecision", + /*sample=*/net::device_bound_sessions::SessionUsage::kInScopeNotDeferred, + /*expected_count=*/1); +} + +IN_PROC_BROWSER_TEST_F(DeviceBoundSessionBrowserTest, DeferredLogs) { + base::HistogramTester histogram_tester; + + content::WebContents* web_contents = + chrome_test_utils::GetActiveWebContents(this); + { + base::test::TestFuture<SessionAccess> future; + DeviceBoundSessionAccessObserver observer( + web_contents, future.GetRepeatingCallback<const SessionAccess&>()); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL( + "/resource_triggered_dbsc_registration"))); + ASSERT_TRUE(future.Wait()); + } + + // Force a refresh. + ASSERT_TRUE( + content::ExecJs(web_contents, "cookieStore.delete('auth_cookie')")); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL("/ensure_authenticated"))); + + metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + histogram_tester.ExpectBucketCount( + "Net.DeviceBoundSessions.RequestDeferralDecision", + /*sample=*/net::device_bound_sessions::SessionUsage::kDeferred, + /*expected_count=*/1); +} + } // namespace
diff --git a/chrome/browser/net/reporting_browsertest.cc b/chrome/browser/net/reporting_browsertest.cc index 58b5b93..47f73960 100644 --- a/chrome/browser/net/reporting_browsertest.cc +++ b/chrome/browser/net/reporting_browsertest.cc
@@ -737,7 +737,7 @@ const std::string* url = report.FindString("url"); const base::Value::Dict* body = report.FindDict("body"); const std::string* reason = body->FindString("reason"); - const std::string* is_top_level = body->FindString("is_top_level"); + const std::optional<bool> is_top_level = body->FindBool("is_top_level"); const std::string* visibility_state = body->FindString("visibility_state"); EXPECT_EQ("crash", *type); @@ -746,10 +746,10 @@ // When the `kCrashReportingAPIMoreContextData` flag is enabled, expect the // extra CrashReportBody context bits to be present. if (GetParam()) { - EXPECT_EQ("true", *is_top_level); + EXPECT_TRUE(*is_top_level); EXPECT_EQ("visible", *visibility_state); } else { - EXPECT_EQ(nullptr, is_top_level); + EXPECT_EQ(std::nullopt, is_top_level); EXPECT_EQ(nullptr, visibility_state); } } @@ -830,15 +830,15 @@ const std::string* url = report.FindString("url"); const base::Value::Dict* body = report.FindDict("body"); const std::string* reason = body->FindString("reason"); - const std::string* is_top_level = body->FindString("is_top_level"); + const std::optional<bool> is_top_level = body->FindBool("is_top_level"); EXPECT_EQ("crash", *type); EXPECT_EQ(*url, iframe_url); EXPECT_EQ("unresponsive", *reason); if (GetParam()) { - EXPECT_EQ("false", *is_top_level); + EXPECT_FALSE(*is_top_level); } else { - EXPECT_EQ(nullptr, is_top_level); + EXPECT_EQ(std::nullopt, is_top_level); } }
diff --git a/chrome/browser/performance_timeline_browsertest.cc b/chrome/browser/performance_timeline_browsertest.cc index 81375e80..68d4af11 100644 --- a/chrome/browser/performance_timeline_browsertest.cc +++ b/chrome/browser/performance_timeline_browsertest.cc
@@ -33,8 +33,7 @@ }); })(); )", - extension->GetResourceURL(extension->url(), "content_script.js") - .spec()); + extension->GetResourceURL("content_script.js").spec()); EXPECT_EQ(content::EvalJs(web_contents(), script_code).error, ""); }
diff --git a/chrome/browser/profiles/gaia_info_update_service_unittest.cc b/chrome/browser/profiles/gaia_info_update_service_unittest.cc index d29a380..297cb69 100644 --- a/chrome/browser/profiles/gaia_info_update_service_unittest.cc +++ b/chrome/browser/profiles/gaia_info_update_service_unittest.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" #include "chrome/browser/signin/test_signin_client_builder.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_browser_process.h"
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudUnsupportedException.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudUnsupportedException.java index c82d2bcb..0b2b62c 100644 --- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudUnsupportedException.java +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/exceptions/ReadAloudUnsupportedException.java
@@ -24,8 +24,6 @@ RejectionReason.CONTENT_TOO_LARGE, RejectionReason.INVALID_URL, RejectionReason.DISALLOWED_FOR_READOUT, RejectionReason.BAD_REQUEST, RejectionReason.EXPIRED_CONTENT_VERSION, RejectionReason.UNSUPPORTED_EMAIL_FORMAT, - RejectionReason.UNSUPPORTED_TUPLE_DATA_EXTRACTION, - RejectionReason.UNSUPPORTED_LATTICE_REVIEW_DATA_EXTRACTION, RejectionReason.DISALLOWED_FOR_TRANSLATION, RejectionReason.COUNT }) // This must be kept in sync with readaloud/enums.xml values @@ -68,10 +66,6 @@ int EXPIRED_CONTENT_VERSION = 16; // We don't support this kind of email. int UNSUPPORTED_EMAIL_FORMAT = 17; - // There is no Tuple data available for this url. - int UNSUPPORTED_TUPLE_DATA_EXTRACTION = 18; - // There is no LatticeReview data available for this url. - int UNSUPPORTED_LATTICE_REVIEW_DATA_EXTRACTION = 19; // The content is not allowed to be translated. int DISALLOWED_FOR_TRANSLATION = 20; int COUNT = 21;
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_entry_row.html b/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_entry_row.html index 8e6994d..140e1a2 100644 --- a/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_entry_row.html +++ b/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_entry_row.html
@@ -24,7 +24,8 @@ } .delete-icon { - --cr-icon-button-size: 20px; + --cr-icon-button-size: 32px; + --cr-icon-button-icon-size: 20px; align-self: center; } </style>
diff --git a/chrome/browser/resources/connectors_internals/connectors_utils.ts b/chrome/browser/resources/connectors_internals/connectors_utils.ts index 619da95..4d1693bd 100644 --- a/chrome/browser/resources/connectors_internals/connectors_utils.ts +++ b/chrome/browser/resources/connectors_internals/connectors_utils.ts
@@ -9,6 +9,7 @@ [KeyTrustLevel.UNSPECIFIED]: 'Unspecified', [KeyTrustLevel.HW]: 'HW', [KeyTrustLevel.OS]: 'OS', + [KeyTrustLevel.OS_SOFTWARE]: 'OS Storage', }; const KeyTypeStringMap = {
diff --git a/chrome/browser/resources/connectors_internals/managed_client_certificate.ts b/chrome/browser/resources/connectors_internals/managed_client_certificate.ts index 0851864..0d80a31 100644 --- a/chrome/browser/resources/connectors_internals/managed_client_certificate.ts +++ b/chrome/browser/resources/connectors_internals/managed_client_certificate.ts
@@ -110,6 +110,10 @@ key: 'Public Key Hash', value: managedIdentity.loadedKeyInfo.encodedSpkiHash, }, + { + key: 'Has SSL Key', + value: managedIdentity.loadedKeyInfo.hasSslKey.toString(), + }, ]); if (managedIdentity.loadedKeyInfo.keyUploadStatus) {
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts index 73eba14..832c0aa 100644 --- a/chrome/browser/resources/side_panel/read_anything/app.ts +++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -22,7 +22,6 @@ import {minOverflowLengthToScroll} from './common.js'; import type {LanguageToastElement} from './language_toast.js'; import {NodeStore} from './node_store.js'; -import {ReadAloudHighlighter} from './read_aloud/highlighter.js'; import {SpeechController} from './read_aloud/speech_controller.js'; import type {SpeechListener} from './read_aloud/speech_controller.js'; import {VoicePackController} from './read_aloud/voice_pack_controller.js'; @@ -124,8 +123,6 @@ private notificationManager_ = VoiceNotificationManager.getInstance(); private logger_: ReadAnythingLogger = ReadAnythingLogger.getInstance(); private styleUpdater_: AppStyleUpdater; - private highlighter_: ReadAloudHighlighter = - ReadAloudHighlighter.getInstance(); private nodeStore_: NodeStore = NodeStore.getInstance(); private voicePackController_: VoicePackController = VoicePackController.getInstance(); @@ -214,7 +211,11 @@ } const {anchorNodeId, anchorOffset, focusNodeId, focusOffset} = - this.getSelectedIds(); + this.isReadAloudEnabled_ ? + this.speechController_.getSelectionAdjustedForHighlights( + selection.anchorNode, selection.anchorOffset, selection.focusNode, + selection.focusOffset) : + this.getSelection(); if (!anchorNodeId || !focusNodeId) { return; } @@ -233,12 +234,8 @@ anchorNodeId, anchorOffset, focusNodeId, focusOffset); } - // If there's been a selection, clear the current Read Aloud highlight. - if (anchorNodeId && focusNodeId) { - // If speech is resumed, this won't be restored. - // TODO: crbug.com/40927698 - Restore the previous highlight after - // speech is resumed after a selection. - this.highlighter_.clearHighlightFormatting(); + if (this.isReadAloudEnabled_) { + this.speechController_.onSelectionChange(); } }; @@ -826,34 +823,6 @@ this.speechController_.onPreviousGranularityClick(); } - private getSelectedIds(): { - anchorNodeId: number|undefined, - anchorOffset: number, - focusNodeId: number|undefined, - focusOffset: number, - } { - const {anchorNode, anchorOffset, focusNode, focusOffset} = - this.getSelection(); - let anchorNodeId = this.nodeStore_.getAxId(anchorNode); - let focusNodeId = this.nodeStore_.getAxId(focusNode); - let adjustedAnchorOffset = anchorOffset; - let adjustedFocusOffset = focusOffset; - if (!anchorNodeId) { - anchorNodeId = this.highlighter_.getAncestorId(anchorNode); - adjustedAnchorOffset += this.highlighter_.getOffsetInAncestor(anchorNode); - } - if (!focusNodeId) { - focusNodeId = this.highlighter_.getAncestorId(focusNode); - adjustedFocusOffset += this.highlighter_.getOffsetInAncestor(focusNode); - } - return { - anchorNodeId: anchorNodeId, - anchorOffset: adjustedAnchorOffset, - focusNodeId: focusNodeId, - focusOffset: adjustedFocusOffset, - }; - } - protected onSelectVoice_( event: CustomEvent<{selectedVoice: SpeechSynthesisVoice}>) { event.preventDefault();
diff --git a/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts b/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts index abce0b51..f334db9 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts +++ b/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts
@@ -130,6 +130,34 @@ (source === PauseActionSource.VOICE_SETTINGS_CHANGE); } + getSelectionAdjustedForHighlights( + anchorNode: Node, anchorOffset: number, focusNode: Node, + focusOffset: number): { + anchorNodeId: number|undefined, + anchorOffset: number, + focusNodeId: number|undefined, + focusOffset: number, + } { + let anchorNodeId = this.nodeStore_.getAxId(anchorNode); + let focusNodeId = this.nodeStore_.getAxId(focusNode); + let adjustedAnchorOffset = anchorOffset; + let adjustedFocusOffset = focusOffset; + if (!anchorNodeId) { + anchorNodeId = this.highlighter_.getAncestorId(anchorNode); + adjustedAnchorOffset += this.highlighter_.getOffsetInAncestor(anchorNode); + } + if (!focusNodeId) { + focusNodeId = this.highlighter_.getAncestorId(focusNode); + adjustedFocusOffset += this.highlighter_.getOffsetInAncestor(focusNode); + } + return { + anchorNodeId: anchorNodeId, + anchorOffset: adjustedAnchorOffset, + focusNodeId: focusNodeId, + focusOffset: adjustedFocusOffset, + }; + } + initializeSpeechTree(startingNodeId?: number) { if (startingNodeId && !this.model_.getFirstTextNode()) { this.model_.setFirstTextNode(startingNodeId); @@ -147,6 +175,13 @@ chrome.readingMode.preprocessTextForSpeech(); } + onSelectionChange() { + // If speech is resumed, this won't be restored. + // TODO: crbug.com/40927698 - Restore the previous highlight after + // speech is resumed after a selection. + this.highlighter_.clearHighlightFormatting(); + } + // If the screen is locked during speech, we should stop speaking. onLockScreen() { if (this.isSpeechActive()) {
diff --git a/chrome/browser/safety_hub/android/unused_site_permissions_bridge.cc b/chrome/browser/safety_hub/android/unused_site_permissions_bridge.cc index f8d35523..a39be235 100644 --- a/chrome/browser/safety_hub/android/unused_site_permissions_bridge.cc +++ b/chrome/browser/safety_hub/android/unused_site_permissions_bridge.cc
@@ -118,10 +118,7 @@ RevokedPermissionsService* service = RevokedPermissionsServiceFactory::GetForProfile(profile); CHECK(service); - - for (const auto& permissions_data : permissions_data_list) { - service->StorePermissionInRevokedPermissionSetting(permissions_data); - } + service->RestoreDeletedRevokedPermissionsList(permissions_data_list); } std::vector<std::u16string> ContentSettingsTypeToString(
diff --git a/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc b/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc index 6a355952..588dffd 100644 --- a/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_preferences_sync_test.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/sync/test/integration/sync_service_impl_harness.h" #include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths.h"
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 2149941..460c80d 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -5834,7 +5834,9 @@ public_deps = [ "//base", "//build:branding_buildflags", + "//chrome/browser:browser_process", "//chrome/common:buildflags", + "//components/variations/service:service", "//extensions/buildflags", ] deps = [
diff --git a/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java b/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java index 24a92d2e..d0b1c99d 100644 --- a/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java +++ b/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java
@@ -204,7 +204,7 @@ private void onInsetsRectsUpdated(Rect widestUnoccludedRect) { // mActivity is only set to null in destroy(). boolean isOnExternalDisplay = - DisplayUtil.isContextInDefaultDisplay(assumeNonNull(mActivity)); + !DisplayUtil.isContextInDefaultDisplay(assumeNonNull(mActivity)); mHeuristicResult = checkIsInDesktopWindow( mCaptionBarRectProvider, mHeuristicResult, isOnExternalDisplay);
diff --git a/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinatorUnitTest.java b/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinatorUnitTest.java index 9387ba84..c67173f 100644 --- a/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinatorUnitTest.java +++ b/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinatorUnitTest.java
@@ -73,15 +73,15 @@ public class AppHeaderCoordinatorUnitTest { @Implements(DisplayUtil.class) static class ShadowDisplayUtil { - private static boolean sIsOnExternalDisplay; + private static boolean sIsOnDefaultDisplay; - private static void setOnExternalDisplay(boolean isOnExternalDisplay) { - sIsOnExternalDisplay = isOnExternalDisplay; + private static void setOnDefaultDisplay(boolean isOnDefaultDisplay) { + sIsOnDefaultDisplay = isOnDefaultDisplay; } @Implementation public static boolean isContextInDefaultDisplay(Context context) { - return sIsOnExternalDisplay; + return sIsOnDefaultDisplay; } } @@ -120,7 +120,7 @@ @Before public void setup() { - ShadowDisplayUtil.setOnExternalDisplay(false); + ShadowDisplayUtil.setOnDefaultDisplay(true); mActivityScenarioRule.getScenario().onActivity(activity -> mSpyActivity = spy(activity)); mEdgeToEdgeStateProvider = new EdgeToEdgeStateProvider(mSpyActivity.getWindow()); mSpyRootView = spy(mSpyActivity.getWindow().getDecorView()); @@ -203,7 +203,7 @@ HistogramWatcher.newSingleRecordWatcher( "Android.DesktopWindowHeuristicResult3", DesktopWindowHeuristicResult.DISALLOWED_ON_EXTERNAL_DISPLAY); - ShadowDisplayUtil.setOnExternalDisplay(true); + ShadowDisplayUtil.setOnDefaultDisplay(false); updateFeatureParams(/* enableOnExternalDisplay= */ false); setupWithLeftAndRightBoundingRect(); notifyInsetsRectObserver(); @@ -216,7 +216,7 @@ @Test public void enabledOnExternalDisplayWhenAllowed() { - ShadowDisplayUtil.setOnExternalDisplay(true); + ShadowDisplayUtil.setOnDefaultDisplay(false); updateFeatureParams(/* enableOnExternalDisplay= */ true); setupWithLeftAndRightBoundingRect(); notifyInsetsRectObserver();
diff --git a/chrome/browser/ui/ash/capture_mode/chrome_capture_mode_delegate.cc b/chrome/browser/ui/ash/capture_mode/chrome_capture_mode_delegate.cc index 3d99b7f..0f3d070 100644 --- a/chrome/browser/ui/ash/capture_mode/chrome_capture_mode_delegate.cc +++ b/chrome/browser/ui/ash/capture_mode/chrome_capture_mode_delegate.cc
@@ -1312,12 +1312,6 @@ std::move(on_search_url_fetched_callback_).Run(final_url); } - // No other actions to take if we are not using the Lens Web API for Copy - // Text. - if (!ash::features::IsSunfishLensWebCopyTextEnabled()) { - return; - } - // Get the vsr ID from the redirect URL so it can be used again in the // /qfmetadata request. std::string vsr_id;
diff --git a/chrome/browser/ui/ash/capture_mode/sunfish_browsertest.cc b/chrome/browser/ui/ash/capture_mode/sunfish_browsertest.cc index 6dbfd601..dd00075 100644 --- a/chrome/browser/ui/ash/capture_mode/sunfish_browsertest.cc +++ b/chrome/browser/ui/ash/capture_mode/sunfish_browsertest.cc
@@ -98,7 +98,7 @@ VerifyActiveBehavior(BehaviorType::kSunfish); // Simulate showing the panel while the session is active. - controller->ShowSearchResultsPanel(gfx::ImageSkia()); + controller->ShowSearchResultsPanel(); controller->NavigateSearchResultsPanel(GURL("kTestUrl1")); ASSERT_TRUE(controller->IsActive()); auto* search_results_view = @@ -158,7 +158,7 @@ VerifyActiveBehavior(BehaviorType::kSunfish); // Simulate showing the panel while the session is active. - controller->ShowSearchResultsPanel(gfx::ImageSkia()); + controller->ShowSearchResultsPanel(); controller->NavigateSearchResultsPanel(GURL("kTestUrl1")); ASSERT_TRUE(controller->IsActive()); auto* search_results_view =
diff --git a/chrome/browser/ui/autofill/BUILD.gn b/chrome/browser/ui/autofill/BUILD.gn index 41d56125..0863d727 100644 --- a/chrome/browser/ui/autofill/BUILD.gn +++ b/chrome/browser/ui/autofill/BUILD.gn
@@ -152,10 +152,6 @@ "//components/password_manager/core/browser:metrics_util", "//components/password_manager/core/browser:password_form", "//components/password_manager/core/browser/form_parsing", - "//components/plus_addresses:features", - "//components/plus_addresses:hats_utils", - "//components/plus_addresses:types", - "//components/plus_addresses/resources/strings", "//components/profile_metrics", "//components/security_state/content", "//components/strings:components_strings_grit", @@ -207,7 +203,7 @@ "//chrome/browser/ui/webui/signin:login", "//components/autofill_ai/core/browser", "//components/password_manager/core/browser/features:password_features", - "//components/plus_addresses", + "//components/plus_addresses/resources/strings", "//extensions/browser", ] @@ -471,7 +467,6 @@ "//components/password_manager/core/browser/password_store:test_support", "//components/password_manager/core/common", "//components/plus_addresses:blocklist_data", - "//components/plus_addresses:plus_address_blocklist_proto", "//components/plus_addresses:test_support", "//components/plus_addresses/resources/strings", "//components/signin/public/base",
diff --git a/chrome/browser/ui/browser_command_controller_browsertest.cc b/chrome/browser/ui/browser_command_controller_browsertest.cc index 9a64d235..3058a75 100644 --- a/chrome/browser/ui/browser_command_controller_browsertest.cc +++ b/chrome/browser/ui/browser_command_controller_browsertest.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/ui/startup/startup_browser_creator.h" #include "chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/side_panel/side_panel_ui.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/test_browser_window.h"
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 488381a2..6e5347d 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -455,6 +455,8 @@ browser->tab_strip_model()->GetWebContentsAt(selected_index)); } + base::UmaHistogramCounts100("TabStrip.Tab.ReloadCount", selected_tabs.size()); + for (WebContents* const selected_tab : selected_tabs) { // Skip this tab if it is no longer part of this tabstrip. N.B. we do this // instead of using WeakPtr<WebContents> because we do not want to reload @@ -1133,7 +1135,7 @@ Browser::Create(Browser::CreateParams(browser->profile(), true)); } - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = browser->tab_strip_model()->DetachTabGroupForInsertion(group); new_browser->tab_strip_model()->InsertDetachedTabGroupAt( std::move(detached_group), 0); @@ -1258,7 +1260,7 @@ Browser* target, tab_groups::TabGroupId group) { CHECK(source->tab_strip_model()->group_model()->ContainsTabGroup(group)); - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = source->tab_strip_model()->DetachTabGroupForInsertion(group); target->tab_strip_model()->InsertDetachedTabGroupAt(std::move(detached_group), 0);
diff --git a/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.cc b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.cc index 9ef2c046..55753fd 100644 --- a/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.cc +++ b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.cc
@@ -134,6 +134,14 @@ ContentSettingsType::REVOKED_ABUSIVE_NOTIFICATION_PERMISSIONS, {}); } +void AbusiveNotificationPermissionsManager::RestoreDeletedRevokedPermission( + const ContentSettingsPattern& primary_pattern, + content_settings::ContentSettingConstraints constraints) { + safety_hub_util::SetRevokedAbusiveNotificationPermission( + hcsm_.get(), primary_pattern.ToRepresentativeUrl(), /*is_ignored=*/false, + constraints); +} + const base::Clock* AbusiveNotificationPermissionsManager::GetClock() { if (clock_for_testing_) { return clock_for_testing_;
diff --git a/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.h b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.h index ac8a6caa..c34fd8b 100644 --- a/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.h +++ b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.h
@@ -71,6 +71,13 @@ const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern); + // Restores REVOKED_ABUSIVE_NOTIFICATION_PERMISSIONS entry for the + // primary_pattern after it was deleted after user + // has accepted the revocation (via `ClearRevokedPermissionsList()`). + void RestoreDeletedRevokedPermission( + const ContentSettingsPattern& primary_pattern, + content_settings::ContentSettingConstraints constraints); + // If there's a clock for testing, return that. Otherwise, return an instance // of a default clock. const base::Clock* GetClock();
diff --git a/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager_unittest.cc b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager_unittest.cc index fc67ace..bfc603d 100644 --- a/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager_unittest.cc +++ b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager_unittest.cc
@@ -372,6 +372,27 @@ } TEST_F(AbusiveNotificationPermissionsManagerTest, + RestoreDeletedRevokedPermissionsList) { + auto manager = + AbusiveNotificationPermissionsManager(mock_database_manager(), hcsm()); + RunUntilSafeBrowsingChecksComplete(&manager); + + content_settings::ContentSettingConstraints constraints; + manager.RestoreDeletedRevokedPermission( + ContentSettingsPattern::FromURLNoWildcard(GURL(url1)), + constraints.Clone()); + manager.RestoreDeletedRevokedPermission( + ContentSettingsPattern::FromURLNoWildcard(GURL(url2)), + constraints.Clone()); + + ContentSettingsForOneType content_settings = + safety_hub_util::GetRevokedAbusiveNotificationPermissions(hcsm()); + EXPECT_EQ(content_settings.size(), 2u); + EXPECT_TRUE(IsUrlInContentSettings(content_settings, url1)); + EXPECT_TRUE(IsUrlInContentSettings(content_settings, url2)); +} + +TEST_F(AbusiveNotificationPermissionsManagerTest, SetRevokedAbusiveNotificationPermission) { AddAbusiveNotification(url1, ContentSetting::CONTENT_SETTING_ALLOW); AddAbusiveNotification(url2, ContentSetting::CONTENT_SETTING_ALLOW);
diff --git a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.cc b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.cc index 6f529af..8b89def0d 100644 --- a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.cc +++ b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.cc
@@ -483,6 +483,30 @@ ContentSettingsType::REVOKED_DISRUPTIVE_NOTIFICATION_PERMISSIONS, {}); } +void DisruptiveNotificationPermissionsManager::RestoreDeletedRevokedPermission( + const ContentSettingsPattern& primary_pattern, + content_settings::ContentSettingConstraints constraints) { + GURL url = primary_pattern.ToRepresentativeUrl(); + base::Value engagement_as_value = hcsm_->GetWebsiteSetting( + url, GURL(), ContentSettingsType::NOTIFICATION_INTERACTIONS); + if (engagement_as_value.is_none() || !engagement_as_value.is_dict()) { + return; + } + + ContentSettingHelper(*hcsm_).PersistRevocationEntry( + url, + RevocationEntry{ + .revocation_state = RevocationState::kRevoked, + .site_engagement = site_engagement_service_->GetScore(url), + .daily_notification_count = permissions:: + NotificationsEngagementService::GetDailyAverageNotificationCount( + engagement_as_value.GetDict()), + .timestamp = clock_->Now(), + .created_at = constraints.expiration() - constraints.lifetime(), + .lifetime = constraints.lifetime(), + }); +} + bool DisruptiveNotificationPermissionsManager::IsNotificationDisruptive( const GURL& url, int daily_notification_count) {
diff --git a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.h b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.h index a10b03e..7b902ab6 100644 --- a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.h +++ b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.h
@@ -146,6 +146,14 @@ const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern); + // Restores REVOKED_DISRUPTIVE_NOTIFICATION_PERMISSIONS entry for the + // primary_pattern after it was deleted after user has accepted the revocation + // (via `ClearRevokedPermissionsList()`). Only restores the value if there is + // a matching notification engagement entry. + void RestoreDeletedRevokedPermission( + const ContentSettingsPattern& primary_pattern, + content_settings::ContentSettingConstraints constraints); + // If the URL is in the revoke or proposed revoke list, report a false // positive and record metrics. static void MaybeReportFalsePositive(Profile* profile,
diff --git a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager_unittest.cc b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager_unittest.cc index 7968804..8c3d3a55b 100644 --- a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager_unittest.cc +++ b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager_unittest.cc
@@ -810,6 +810,28 @@ } TEST_F(DisruptiveNotificationPermissionsManagerRevocationTest, + RestoreDeletedRevokedPermission) { + GURL url("https://www.example1.com"); + + SetDailyAverageNotificationCount(url, 3); + site_engagement_service()->ResetBaseScoreForURL(url, 1.0); + + content_settings::ContentSettingConstraints constraints; + manager()->RestoreDeletedRevokedPermission( + ContentSettingsPattern::FromURLNoWildcard(url), constraints.Clone()); + + std::optional<RevocationEntry> revocation_entry = + ContentSettingHelper(*hcsm()).GetRevocationEntry(url); + + EXPECT_THAT(revocation_entry, + Optional(Field(&RevocationEntry::has_reported_proposal, false))); + EXPECT_THAT(revocation_entry, + Optional(Field(&RevocationEntry::site_engagement, 1.0))); + EXPECT_THAT(revocation_entry, + Optional(Field(&RevocationEntry::daily_notification_count, 3))); +} + +TEST_F(DisruptiveNotificationPermissionsManagerRevocationTest, UpdateNotificationContentSettingsChanged) { GURL url("https://chrome.test/"); ContentSettingHelper(*hcsm()).PersistRevocationEntry(
diff --git a/chrome/browser/ui/safety_hub/revoked_permissions_service.cc b/chrome/browser/ui/safety_hub/revoked_permissions_service.cc index d44c0761..de674475 100644 --- a/chrome/browser/ui/safety_hub/revoked_permissions_service.cc +++ b/chrome/browser/ui/safety_hub/revoked_permissions_service.cc
@@ -168,6 +168,30 @@ return constraint; } +bool IsUnusedPermissionRevocation(PermissionsRevocationType revocation_type) { + return revocation_type == PermissionsRevocationType::kUnusedPermissions || + revocation_type == PermissionsRevocationType:: + kUnusedPermissionsAndAbusiveNotifications || + revocation_type == PermissionsRevocationType:: + kUnusedPermissionsAndDisruptiveNotifications; +} + +bool IsAbusiveNotificationPermissionRevocation( + PermissionsRevocationType revocation_type) { + return revocation_type == + PermissionsRevocationType::kAbusiveNotificationPermissions || + revocation_type == PermissionsRevocationType:: + kUnusedPermissionsAndAbusiveNotifications; +} + +bool IsDisruptiveNotificationPermissionRevocation( + PermissionsRevocationType revocation_type) { + return revocation_type == + PermissionsRevocationType::kDisruptiveNotificationPermissions || + revocation_type == PermissionsRevocationType:: + kUnusedPermissionsAndDisruptiveNotifications; +} + } // namespace // static @@ -667,7 +691,7 @@ // revoked settings if necessary. is_unused_site_revocation_running = false; - StorePermissionInRevokedPermissionSetting( + StorePermissionInUnusedSitePermissionSetting( unused_site_permission_types, permissions_data.chooser_permissions_data, permissions_data.constraints.Clone(), permissions_data.primary_pattern, ContentSettingsPattern::Wildcard()); @@ -1045,7 +1069,7 @@ // Store revoked permissions on HCSM. if (!revoked_permissions.empty()) { - StorePermissionInRevokedPermissionSetting( + StorePermissionInUnusedSitePermissionSetting( revoked_permissions, chooser_permissions_data, std::nullopt, primary_pattern, secondary_pattern); } @@ -1071,18 +1095,36 @@ is_unused_site_revocation_running = false; } -void RevokedPermissionsService::StorePermissionInRevokedPermissionSetting( - const PermissionsData& permissions_data) { - // The |secondary_pattern| for - // |ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS| is always wildcard. - StorePermissionInRevokedPermissionSetting( - permissions_data.permission_types, - permissions_data.chooser_permissions_data, - permissions_data.constraints.Clone(), permissions_data.primary_pattern, - ContentSettingsPattern::Wildcard()); +void RevokedPermissionsService::RestoreDeletedRevokedPermissionsList( + const std::vector<PermissionsData>& permissions_data_list) { + for (const auto& permissions_data : permissions_data_list) { + if (IsUnusedPermissionRevocation(permissions_data.revocation_type)) { + StorePermissionInUnusedSitePermissionSetting( + permissions_data.permission_types, + permissions_data.chooser_permissions_data, + permissions_data.constraints.Clone(), + permissions_data.primary_pattern, ContentSettingsPattern::Wildcard()); + } + + if (IsAbusiveNotificationAutoRevocationEnabled() && + IsAbusiveNotificationPermissionRevocation( + permissions_data.revocation_type)) { + abusive_notification_manager_->RestoreDeletedRevokedPermission( + permissions_data.primary_pattern, + permissions_data.constraints.Clone()); + } + + if (disruptive_notification_manager_ && + IsDisruptiveNotificationPermissionRevocation( + permissions_data.revocation_type)) { + disruptive_notification_manager_->RestoreDeletedRevokedPermission( + permissions_data.primary_pattern, + permissions_data.constraints.Clone()); + } + } } -void RevokedPermissionsService::StorePermissionInRevokedPermissionSetting( +void RevokedPermissionsService::StorePermissionInUnusedSitePermissionSetting( const std::set<ContentSettingsType>& permissions, const base::Value::Dict& chooser_permissions_data, const std::optional<content_settings::ContentSettingConstraints> constraint,
diff --git a/chrome/browser/ui/safety_hub/revoked_permissions_service.h b/chrome/browser/ui/safety_hub/revoked_permissions_service.h index f919b88..c46ef08 100644 --- a/chrome/browser/ui/safety_hub/revoked_permissions_service.h +++ b/chrome/browser/ui/safety_hub/revoked_permissions_service.h
@@ -199,9 +199,10 @@ // the user. Does not change permissions themselves. void ClearRevokedPermissionsList(); - // Stores revoked permissions data on HCSM. - void StorePermissionInRevokedPermissionSetting( - const PermissionsData& permission_data); + // Restores the list of revoked permissions after it was deleted after user + // has accepted the revocation (via `ClearRevokedPermissionsList()`). + void RestoreDeletedRevokedPermissionsList( + const std::vector<PermissionsData>& permissions_data_list); // Returns the list of all permissions that have been revoked. std::unique_ptr<RevokedPermissionsResult> GetRevokedPermissions(); @@ -272,7 +273,7 @@ void RevokeUnusedPermissions(); // Stores revoked permissions data on HCSM. - void StorePermissionInRevokedPermissionSetting( + void StorePermissionInUnusedSitePermissionSetting( const std::set<ContentSettingsType>& permissions, const base::Value::Dict& chooser_permissions_data, const std::optional<content_settings::ContentSettingConstraints>
diff --git a/chrome/browser/ui/safety_hub/revoked_permissions_service_unittest.cc b/chrome/browser/ui/safety_hub/revoked_permissions_service_unittest.cc index d244503..db0143e 100644 --- a/chrome/browser/ui/safety_hub/revoked_permissions_service_unittest.cc +++ b/chrome/browser/ui/safety_hub/revoked_permissions_service_unittest.cc
@@ -23,6 +23,7 @@ #include "base/time/time.h" #include "base/values.h" #include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/permissions/notifications_engagement_service_factory.h" #include "chrome/browser/safe_browsing/test_safe_browsing_service.h" #include "chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.h" #include "chrome/browser/ui/safety_hub/mock_safe_browsing_database_manager.h" @@ -1280,6 +1281,58 @@ ExpectRevokedDisruptiveNotificationPermissionSize(0U); } +TEST_P(RevokedPermissionsServiceTest, RestoreClearedRevokedPermissionsList) { + if (ShouldSetupAbusiveNotificationSites()) { + SetupAbusiveNotificationSite(url2, ContentSetting::CONTENT_SETTING_ASK); + SetupAbusiveNotificationSite(url3, ContentSetting::CONTENT_SETTING_ASK); + SetupRevokedAbusiveNotificationSite(url2); + SetupRevokedAbusiveNotificationSite(url3); + ExpectRevokedAbusiveNotificationPermissionSize(2U); + } + if (ShouldSetupUnusedSites()) { + SetupRevokedUnusedPermissionSite(url1); + SetupRevokedUnusedPermissionSite(url2); + EXPECT_EQ(2U, GetRevokedUnusedPermissions(hcsm()).size()); + } + if (ShouldSetupDisruptiveSites()) { + auto* notifications_engagement_service = + NotificationsEngagementServiceFactory::GetForProfile(profile()); + notifications_engagement_service->RecordNotificationDisplayed(GURL(url4), + 21); + SetupRevokedDisruptiveNotificationSite(url4); + } + + auto new_service = std::make_unique<RevokedPermissionsService>( + profile(), profile()->GetPrefs()); + auto opt_result = new_service->GetCachedResult(); + EXPECT_TRUE(opt_result.has_value()); + auto* result = + static_cast<RevokedPermissionsService::RevokedPermissionsResult*>( + opt_result.value().get()); + auto revoked_permissions_list = result->GetRevokedPermissions(); + std::vector<PermissionsData> revoked_permissions_vector{ + std::begin(revoked_permissions_list), std::end(revoked_permissions_list)}; + + // Revoked permissions list should be empty after clearing the revoked + // permissions list. + service()->ClearRevokedPermissionsList(); + EXPECT_EQ(0U, GetRevokedUnusedPermissions(hcsm()).size()); + ExpectRevokedAbusiveNotificationPermissionSize(0U); + ExpectRevokedDisruptiveNotificationPermissionSize(0U); + + service()->RestoreDeletedRevokedPermissionsList(revoked_permissions_vector); + + if (ShouldSetupUnusedSites()) { + EXPECT_EQ(GetRevokedUnusedPermissions(hcsm()).size(), 2u); + } + if (ShouldSetupAbusiveNotificationSites()) { + ExpectRevokedAbusiveNotificationPermissionSize(2U); + } + if (ShouldSetupDisruptiveSites()) { + ExpectRevokedDisruptiveNotificationPermissionSize(1U); + } +} + TEST_P(RevokedPermissionsServiceTest, RecordRegrantMetricForAllowAgain) { SetupRevokedUnusedPermissionSite(url1); SetupRevokedUnusedPermissionSite(url2);
diff --git a/chrome/browser/ui/tabs/BUILD.gn b/chrome/browser/ui/tabs/BUILD.gn index 5a6c098..27e2b31 100644 --- a/chrome/browser/ui/tabs/BUILD.gn +++ b/chrome/browser/ui/tabs/BUILD.gn
@@ -280,6 +280,7 @@ "//chrome/browser/ui:browser_list", "//chrome/browser/ui/color:color_headers", "//chrome/browser/ui/startup:startup_tab", + "//chrome/browser/ui/tabs/alert:tab_alert", "//components/collaboration/public:public", "//components/keyed_service/core", "//components/tabs:public",
diff --git a/chrome/browser/ui/tabs/alert/BUILD.gn b/chrome/browser/ui/tabs/alert/BUILD.gn new file mode 100644 index 0000000..47ae9fc --- /dev/null +++ b/chrome/browser/ui/tabs/alert/BUILD.gn
@@ -0,0 +1,11 @@ +# Copyright 2021 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +assert(is_win || is_mac || is_linux || is_chromeos || is_android) + +import("//chrome/common/features.gni") + +source_set("tab_alert") { + public = [ "tab_alert.h" ] +}
diff --git a/chrome/browser/ui/tabs/alert/tab_alert.h b/chrome/browser/ui/tabs/alert/tab_alert.h new file mode 100644 index 0000000..0ba9dc9 --- /dev/null +++ b/chrome/browser/ui/tabs/alert/tab_alert.h
@@ -0,0 +1,29 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_TABS_ALERT_TAB_ALERT_H_ +#define CHROME_BROWSER_UI_TABS_ALERT_TAB_ALERT_H_ + +namespace tabs { +// Alert states for a tab. Any number of these (or none) may apply at once. +enum class TabAlert { + MEDIA_RECORDING, // Audio/Video [both] being recorded, consumed by tab. + TAB_CAPTURING, // Tab contents being captured. + AUDIO_PLAYING, // Audible audio is playing from the tab. + AUDIO_MUTING, // Tab audio is being muted. + BLUETOOTH_CONNECTED, // Tab is connected to a BT Device. + BLUETOOTH_SCAN_ACTIVE, // Tab is actively scanning for BT devices. + USB_CONNECTED, // Tab is connected to a USB device. + HID_CONNECTED, // Tab is connected to a HID device. + SERIAL_CONNECTED, // Tab is connected to a serial device. + PIP_PLAYING, // Tab contains a video in Picture-in-Picture mode. + DESKTOP_CAPTURING, // Desktop contents being recorded, consumed by tab. + VR_PRESENTING_IN_HEADSET, // VR content is being presented in a headset. + AUDIO_RECORDING, // Audio [only] being recorded, consumed by tab. + VIDEO_RECORDING, // Video [only] being recorded, consumed by tab. + GLIC_ACCESSING, // Glic is accessing the tab's contents. +}; +} // namespace tabs + +#endif // CHROME_BROWSER_UI_TABS_ALERT_TAB_ALERT_H_
diff --git a/chrome/browser/ui/tabs/features.cc b/chrome/browser/ui/tabs/features.cc index 1ea0ada..221adc86 100644 --- a/chrome/browser/ui/tabs/features.cc +++ b/chrome/browser/ui/tabs/features.cc
@@ -6,7 +6,7 @@ #include "base/feature_list.h" #include "chrome/browser/buildflags.h" -#include "chrome/common/chrome_features.h" +#include "chrome/browser/ui/ui_features.h" namespace tabs {
diff --git a/chrome/browser/ui/tabs/tab_enums.h b/chrome/browser/ui/tabs/tab_enums.h index 281589db..b83c85b0 100644 --- a/chrome/browser/ui/tabs/tab_enums.h +++ b/chrome/browser/ui/tabs/tab_enums.h
@@ -5,25 +5,6 @@ #ifndef CHROME_BROWSER_UI_TABS_TAB_ENUMS_H_ #define CHROME_BROWSER_UI_TABS_TAB_ENUMS_H_ -// Alert states for a tab. Any number of these (or none) may apply at once. -enum class TabAlertState { - MEDIA_RECORDING, // Audio/Video [both] being recorded, consumed by tab. - TAB_CAPTURING, // Tab contents being captured. - AUDIO_PLAYING, // Audible audio is playing from the tab. - AUDIO_MUTING, // Tab audio is being muted. - BLUETOOTH_CONNECTED, // Tab is connected to a BT Device. - BLUETOOTH_SCAN_ACTIVE, // Tab is actively scanning for BT devices. - USB_CONNECTED, // Tab is connected to a USB device. - HID_CONNECTED, // Tab is connected to a HID device. - SERIAL_CONNECTED, // Tab is connected to a serial device. - PIP_PLAYING, // Tab contains a video in Picture-in-Picture mode. - DESKTOP_CAPTURING, // Desktop contents being recorded, consumed by tab. - VR_PRESENTING_IN_HEADSET, // VR content is being presented in a headset. - AUDIO_RECORDING, // Audio [only] being recorded, consumed by tab. - VIDEO_RECORDING, // Video [only] being recorded, consumed by tab. - GLIC_ACCESSING, // Glic is accessing the tab's contents. -}; - // State indicating if the user is following the web feed of the site loaded in // a tab. enum class TabWebFeedFollowState {
diff --git a/chrome/browser/ui/tabs/tab_renderer_data.h b/chrome/browser/ui/tabs/tab_renderer_data.h index ce89504..5a37dde 100644 --- a/chrome/browser/ui/tabs/tab_renderer_data.h +++ b/chrome/browser/ui/tabs/tab_renderer_data.h
@@ -9,6 +9,7 @@ #include "base/memory/weak_ptr.h" #include "base/process/kill.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_network_state.h" #include "ui/base/models/image_model.h" @@ -63,7 +64,7 @@ bool show_icon = true; bool pinned = false; bool blocked = false; - std::vector<TabAlertState> alert_state; + std::vector<tabs::TabAlert> alert_state; bool should_hide_throbber = false; bool should_render_empty_title = false; bool should_themify_favicon = false;
diff --git a/chrome/browser/ui/tabs/tab_renderer_data_unittest.cc b/chrome/browser/ui/tabs/tab_renderer_data_unittest.cc index ae3753d..c6c11ed 100644 --- a/chrome/browser/ui/tabs/tab_renderer_data_unittest.cc +++ b/chrome/browser/ui/tabs/tab_renderer_data_unittest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/resource_coordinator/utils.h" #include "chrome/browser/ui/performance_controls/tab_resource_usage_tab_helper.h" #include "chrome/browser/ui/tab_ui_helper.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h" #include "chrome/browser/ui/tabs/test_util.h" @@ -288,7 +289,7 @@ TabRendererData::FromTabInModel(&tab_strip_model_, index); EXPECT_NE(data.alert_state.end(), std::find(data.alert_state.begin(), data.alert_state.end(), - TabAlertState::AUDIO_PLAYING)); + tabs::TabAlert::AUDIO_PLAYING)); } TEST_F(TabRendererDataTest, ShouldHideThrobber) {
diff --git a/chrome/browser/ui/tabs/tab_strip_api/BUILD.gn b/chrome/browser/ui/tabs/tab_strip_api/BUILD.gn index eadb3ff9..7c9c2a4 100644 --- a/chrome/browser/ui/tabs/tab_strip_api/BUILD.gn +++ b/chrome/browser/ui/tabs/tab_strip_api/BUILD.gn
@@ -29,7 +29,7 @@ }, { mojom = "tabs_api.mojom.TabAlertState" - cpp = "::TabAlertState" + cpp = "::tabs::TabAlert" }, { mojom = "tabs_api.mojom.TabNetworkState" @@ -40,6 +40,7 @@ "//chrome/browser/ui/tabs/tab_strip_api/tab_id.h", "//chrome/browser/ui/tabs/tab_strip_api/tab_id_traits.h", "//chrome/browser/ui/tabs/tab_strip_api/tab_enum_traits.h", + "//chrome/browser/ui/tabs/alert/tab_alert.h", ] traits_sources = [ "//chrome/browser/ui/tabs/tab_strip_api/tab_enum_traits.cc",
diff --git a/chrome/browser/ui/tabs/tab_strip_api/tab_enum_traits.h b/chrome/browser/ui/tabs/tab_strip_api/tab_enum_traits.h index d2b547d..2e52a0a8 100644 --- a/chrome/browser/ui/tabs/tab_strip_api/tab_enum_traits.h +++ b/chrome/browser/ui/tabs/tab_strip_api/tab_enum_traits.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_TABS_TAB_STRIP_API_TAB_ENUM_TRAITS_H_ #define CHROME_BROWSER_UI_TABS_TAB_STRIP_API_TAB_ENUM_TRAITS_H_ +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_network_state.h" #include "chrome/browser/ui/tabs/tab_strip_api/tab_strip_api.mojom.h" @@ -22,7 +23,7 @@ }; using MojoTabAlertState = tabs_api::mojom::TabAlertState; -using NativeTabAlertState = enum TabAlertState; +using NativeTabAlertState = enum tabs::TabAlert; // TabAlertState Enum mapping. template <>
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index 58b53b3..bb27ffe 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -28,6 +28,7 @@ #include "base/functional/callback.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" @@ -171,13 +172,14 @@ return std::make_unique<TabGroupModel>(controller); } -DetachedTabGroup::DetachedTabGroup( - std::unique_ptr<tabs::TabGroupTabCollection> collection, +DetachedTabCollection::DetachedTabCollection( + std::variant<std::unique_ptr<tabs::TabGroupTabCollection>, + std::unique_ptr<tabs::SplitTabCollection>> collection, std::optional<int> active_index) : collection_(std::move(collection)), active_index_(active_index) {} -DetachedTabGroup::~DetachedTabGroup() = default; -DetachedTabGroup::DetachedTabGroup(DetachedTabGroup&&) = default; +DetachedTabCollection::~DetachedTabCollection() = default; +DetachedTabCollection::DetachedTabCollection(DetachedTabCollection&&) = default; DetachedTab::DetachedTab(int index_before_any_removals, int index_at_time_of_removal, @@ -403,7 +405,8 @@ return std::move(notifications.detached_tab[0]); } -std::unique_ptr<DetachedTabGroup> TabStripModel::DetachTabGroupForInsertion( +std::unique_ptr<DetachedTabCollection> +TabStripModel::DetachTabGroupForInsertion( const tab_groups::TabGroupId group_id) { ReentrancyCheck reentrancy_check(&reentrancy_guard_); @@ -414,14 +417,21 @@ } gfx::Range TabStripModel::InsertDetachedTabGroupAt( - std::unique_ptr<DetachedTabGroup> group, + std::unique_ptr<DetachedTabCollection> group, int index) { ReentrancyCheck reentrancy_check(&reentrancy_guard_); CHECK(group_model_); - CHECK(!group_model_->ContainsTabGroup(group->collection_->GetTabGroupId())); + CHECK(std::holds_alternative<std::unique_ptr<tabs::TabGroupTabCollection>>( + group->collection_)); + + tabs::TabGroupTabCollection* group_collection = + std::get<std::unique_ptr<tabs::TabGroupTabCollection>>(group->collection_) + .get(); + + CHECK(!group_model_->ContainsTabGroup(group_collection->GetTabGroupId())); // Notify tab is added to model. - for (tabs::TabInterface* tab : *(group->collection_)) { + for (tabs::TabInterface* tab : *(group_collection)) { static_cast<tabs::TabModel*>(tab)->OnAddedToModel(this); } @@ -441,7 +451,7 @@ } } -std::unique_ptr<DetachedTabGroup> TabStripModel::DetachTabGroupImpl( +std::unique_ptr<DetachedTabCollection> TabStripModel::DetachTabGroupImpl( const tab_groups::TabGroupId& group_id) { // Prepare for group to be removed. const gfx::Range tabs_in_group = @@ -571,20 +581,26 @@ active_tab_removed ? group_collection->GetIndexOfTabRecursive(active_tab_model) : std::nullopt; - return std::make_unique<DetachedTabGroup>(std::move(group_collection), - active_index_in_group); + return std::make_unique<DetachedTabCollection>(std::move(group_collection), + active_index_in_group); } gfx::Range TabStripModel::InsertDetachedTabGroupImpl( - std::unique_ptr<DetachedTabGroup> detached_group, + std::unique_ptr<DetachedTabCollection> detached_group, int index) { - CHECK(detached_group->collection_); + CHECK(std::holds_alternative<std::unique_ptr<tabs::TabGroupTabCollection>>( + detached_group->collection_)); + + std::unique_ptr<tabs::TabGroupTabCollection> group_collection = + std::move(std::get<std::unique_ptr<tabs::TabGroupTabCollection>>( + detached_group->collection_)); + CHECK(group_collection); + + tabs::TabGroupTabCollection* group_collection_ptr = group_collection.get(); const tab_groups::TabGroupId& group_id = - detached_group->collection_->GetTabGroupId(); - tabs::TabGroupTabCollection* group_collection = - detached_group->collection_.get(); - for (const tabs::TabInterface* tab : *group_collection) { + group_collection_ptr->GetTabGroupId(); + for (const tabs::TabInterface* tab : *group_collection_ptr) { delegate()->WillAddWebContents(tab->GetContents()); } @@ -593,14 +609,12 @@ const bool tab_strip_empty_initially = empty(); // Add the group collection. - group_model_->AddTabGroup( - std::move(detached_group->collection_->GetTabGroup()), - base::PassKey<TabStripModel>()); - contents_data_->InsertTabGroupAt(std::move(detached_group->collection_), - index); + group_model_->AddTabGroup(std::move(group_collection_ptr->GetTabGroup()), + base::PassKey<TabStripModel>()); + contents_data_->InsertTabGroupAt(std::move(group_collection), index); for (int i = index; - i < index + static_cast<int>(group_collection->TabCountRecursive()); + i < index + static_cast<int>(group_collection_ptr->TabCountRecursive()); i++) { selection_model_.IncrementFrom(index); } @@ -615,7 +629,7 @@ ValidateTabStripModel(); std::set<split_tabs::SplitTabId> splits_in_group; - for (tabs::TabInterface* tab : *group_collection) { + for (tabs::TabInterface* tab : *group_collection_ptr) { static_cast<tabs::TabModel*>(tab)->DidInsert( base::PassKey<TabStripModel>()); @@ -644,7 +658,7 @@ OnChange(change, selection); // Send group attach notification. - NotifyTabGroupAttached(group_collection); + NotifyTabGroupAttached(group_collection_ptr); // Send split attach notification for (const split_tabs::SplitTabId& split_id : splits_in_group) { @@ -2107,7 +2121,10 @@ if (!delegate_->CanReload()) { break; } - for (int index : GetIndicesForCommand(context_index)) { + const std::vector<int> indices = GetIndicesForCommand(context_index); + base::UmaHistogramCounts100("TabStrip.Tab.ContextMenuReloadCount", + indices.size()); + for (int index : indices) { WebContents* tab = GetWebContentsAt(index); if (tab) { tab->GetController().Reload(content::ReloadType::NORMAL, true);
diff --git a/chrome/browser/ui/tabs/tab_strip_model.h b/chrome/browser/ui/tabs/tab_strip_model.h index 6ae8930..1b33376 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.h +++ b/chrome/browser/ui/tabs/tab_strip_model.h
@@ -73,17 +73,20 @@ std::unique_ptr<TabGroupModel> Create(TabGroupController* controller); }; -// Holds the collection object for the group. Have DetachedTabGroup object as a -// container of the collection_ so client does not need to worry or deal with -// the collection object. -struct DetachedTabGroup { - DetachedTabGroup(std::unique_ptr<tabs::TabGroupTabCollection> collection, - std::optional<int> active_index); - DetachedTabGroup(const DetachedTabGroup&) = delete; - DetachedTabGroup& operator=(const DetachedTabGroup&) = delete; - ~DetachedTabGroup(); - DetachedTabGroup(DetachedTabGroup&&); - std::unique_ptr<tabs::TabGroupTabCollection> collection_; +// Have DetachedTabCollection object as a container of the `collection_` so +// client does not need to worry or deal with the collection object. +struct DetachedTabCollection { + DetachedTabCollection( + std::variant<std::unique_ptr<tabs::TabGroupTabCollection>, + std::unique_ptr<tabs::SplitTabCollection>> collection, + std::optional<int> active_index); + DetachedTabCollection(const DetachedTabCollection&) = delete; + DetachedTabCollection& operator=(const DetachedTabCollection&) = delete; + ~DetachedTabCollection(); + DetachedTabCollection(DetachedTabCollection&&); + std::variant<std::unique_ptr<tabs::TabGroupTabCollection>, + std::unique_ptr<tabs::SplitTabCollection>> + collection_; // Store the index of tab that was active in the detached group. std::optional<int> active_index_ = std::nullopt; }; @@ -278,12 +281,13 @@ // Removes the group collection from the collection hierarchy and passes it to // the client. The client can re-insert into another tabstrip using // `InsertDetachedGroupAt` without destroying the group. - std::unique_ptr<DetachedTabGroup> DetachTabGroupForInsertion( + std::unique_ptr<DetachedTabCollection> DetachTabGroupForInsertion( const tab_groups::TabGroupId group_id); // Inserts a detached tab group into the tabstrip starting at `index`. - gfx::Range InsertDetachedTabGroupAt(std::unique_ptr<DetachedTabGroup> group, - int index); + gfx::Range InsertDetachedTabGroupAt( + std::unique_ptr<DetachedTabCollection> group, + int index); // Closes the WebContents at the specified index. This causes the // WebContents to be destroyed, but it may not happen immediately. @@ -876,11 +880,11 @@ TabStripModelChange::RemoveReason web_contents_remove_reason, tabs::TabInterface::DetachReason tab_detach_reason); - std::unique_ptr<DetachedTabGroup> DetachTabGroupImpl( + std::unique_ptr<DetachedTabCollection> DetachTabGroupImpl( const tab_groups::TabGroupId& group); gfx::Range InsertDetachedTabGroupImpl( - std::unique_ptr<DetachedTabGroup> detached_group, + std::unique_ptr<DetachedTabCollection> detached_group, int index); // We batch send notifications. This has two benefits:
diff --git a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc index c743618..2f9a529 100644 --- a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc +++ b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
@@ -905,10 +905,14 @@ tab_groups::TabGroupId group_id = tabstrip()->AddToNewGroup(std::vector<int>{1, 2}); - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = tabstrip()->DetachTabGroupForInsertion(group_id); + tabs::TabGroupTabCollection* group_collection = + std::get<std::unique_ptr<tabs::TabGroupTabCollection>>( + detached_group->collection_) + .get(); - EXPECT_EQ(detached_group->collection_->TabCountRecursive(), 2u); + EXPECT_EQ(group_collection->TabCountRecursive(), 2u); EXPECT_FALSE(tabstrip()->group_model()->ContainsTabGroup(group_id)); EXPECT_EQ(tabstrip()->count(), 4); @@ -939,7 +943,7 @@ tabstrip()->ActivateTabAt(2); tabstrip()->ForgetAllOpeners(); tabstrip()->SetOpenerOfWebContentsAt(0, tabstrip()->GetWebContentsAt(1)); - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = tabstrip()->DetachTabGroupForInsertion(group_id); EXPECT_EQ(tabstrip()->active_index(), 0); @@ -1003,10 +1007,14 @@ split_tabs::SplitTabId split_id = tabstrip()->AddToNewSplit({3}, split_tabs::SplitTabLayout::kVertical); - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = tabstrip()->DetachTabGroupForInsertion(group_id); + tabs::TabGroupTabCollection* group_collection = + std::get<std::unique_ptr<tabs::TabGroupTabCollection>>( + detached_group->collection_) + .get(); - EXPECT_EQ(detached_group->collection_->TabCountRecursive(), 3u); + EXPECT_EQ(group_collection->TabCountRecursive(), 3u); EXPECT_FALSE(tabstrip()->group_model()->ContainsTabGroup(group_id)); EXPECT_EQ(tabstrip()->count(), 2); @@ -1038,7 +1046,7 @@ tab_groups::TabGroupId group_id = tabstrip()->AddToNewGroup(std::vector<int>{1, 2}); tabstrip()->ActivateTabAt(1); - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = tabstrip()->DetachTabGroupForInsertion(group_id); tabs::TabInterface* active_tab = tabstrip()->GetActiveTab();
diff --git a/chrome/browser/ui/tabs/tab_utils.cc b/chrome/browser/ui/tabs/tab_utils.cc index 2eb6c95..16d9767 100644 --- a/chrome/browser/ui/tabs/tab_utils.cc +++ b/chrome/browser/ui/tabs/tab_utils.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/recently_audible_helper.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/vr/vr_tab_helper.h" @@ -29,9 +30,9 @@ #include "chrome/browser/glic/resources/grit/glic_browser_resources.h" #endif -std::vector<TabAlertState> GetTabAlertStatesForContents( +std::vector<tabs::TabAlert> GetTabAlertStatesForContents( content::WebContents* contents) { - std::vector<TabAlertState> states; + std::vector<tabs::TabAlert> states; if (!contents) { return states; } @@ -46,50 +47,50 @@ // with tooltip that notes all the states in play. if (indicator->IsCapturingWindow(contents) || indicator->IsCapturingDisplay(contents)) { - states.push_back(TabAlertState::DESKTOP_CAPTURING); + states.push_back(tabs::TabAlert::DESKTOP_CAPTURING); } if (indicator->IsBeingMirrored(contents)) { - states.push_back(TabAlertState::TAB_CAPTURING); + states.push_back(tabs::TabAlert::TAB_CAPTURING); } if (indicator->IsCapturingAudio(contents) && indicator->IsCapturingVideo(contents)) { - states.push_back(TabAlertState::MEDIA_RECORDING); + states.push_back(tabs::TabAlert::MEDIA_RECORDING); } else if (indicator->IsCapturingAudio(contents)) { - states.push_back(TabAlertState::AUDIO_RECORDING); + states.push_back(tabs::TabAlert::AUDIO_RECORDING); } else if (indicator->IsCapturingVideo(contents)) { - states.push_back(TabAlertState::VIDEO_RECORDING); + states.push_back(tabs::TabAlert::VIDEO_RECORDING); } } if (contents->IsCapabilityActive( content::WebContentsCapabilityType::kBluetoothConnected)) { - states.push_back(TabAlertState::BLUETOOTH_CONNECTED); + states.push_back(tabs::TabAlert::BLUETOOTH_CONNECTED); } if (contents->IsCapabilityActive( content::WebContentsCapabilityType::kBluetoothScanning)) { - states.push_back(TabAlertState::BLUETOOTH_SCAN_ACTIVE); + states.push_back(tabs::TabAlert::BLUETOOTH_SCAN_ACTIVE); } if (contents->IsCapabilityActive(content::WebContentsCapabilityType::kUSB)) { - states.push_back(TabAlertState::USB_CONNECTED); + states.push_back(tabs::TabAlert::USB_CONNECTED); } if (contents->IsCapabilityActive(content::WebContentsCapabilityType::kHID)) { - states.push_back(TabAlertState::HID_CONNECTED); + states.push_back(tabs::TabAlert::HID_CONNECTED); } if (contents->IsCapabilityActive( content::WebContentsCapabilityType::kSerial)) { - states.push_back(TabAlertState::SERIAL_CONNECTED); + states.push_back(tabs::TabAlert::SERIAL_CONNECTED); } #if BUILDFLAG(ENABLE_GLIC) glic::GlicKeyedService* glic_service = glic::GlicKeyedService::Get( Profile::FromBrowserContext(contents->GetBrowserContext())); if (glic_service && glic_service->IsContextAccessIndicatorShown(contents)) { - states.push_back(TabAlertState::GLIC_ACCESSING); + states.push_back(tabs::TabAlert::GLIC_ACCESSING); } #endif @@ -98,12 +99,12 @@ // because most VR content has audio and its usage is implied by the VR // icon. if (vr::VrTabHelper::IsContentDisplayedInHeadset(contents)) { - states.push_back(TabAlertState::VR_PRESENTING_IN_HEADSET); + states.push_back(tabs::TabAlert::VR_PRESENTING_IN_HEADSET); } if (contents->HasPictureInPictureVideo() || contents->HasPictureInPictureDocument()) { - states.push_back(TabAlertState::PIP_PLAYING); + states.push_back(tabs::TabAlert::PIP_PLAYING); } // Only tabs have a RecentlyAudibleHelper, but this function is abused for @@ -116,58 +117,58 @@ } if (audible) { if (contents->IsAudioMuted()) { - states.push_back(TabAlertState::AUDIO_MUTING); + states.push_back(tabs::TabAlert::AUDIO_MUTING); } - states.push_back(TabAlertState::AUDIO_PLAYING); + states.push_back(tabs::TabAlert::AUDIO_PLAYING); } return states; } -std::u16string GetTabAlertStateText(const TabAlertState alert_state) { +std::u16string GetTabAlertStateText(const tabs::TabAlert alert_state) { switch (alert_state) { - case TabAlertState::AUDIO_PLAYING: + case tabs::TabAlert::AUDIO_PLAYING: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_AUDIO_PLAYING); - case TabAlertState::AUDIO_MUTING: + case tabs::TabAlert::AUDIO_MUTING: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_AUDIO_MUTING); - case TabAlertState::MEDIA_RECORDING: + case tabs::TabAlert::MEDIA_RECORDING: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_MEDIA_RECORDING); - case TabAlertState::AUDIO_RECORDING: + case tabs::TabAlert::AUDIO_RECORDING: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_AUDIO_RECORDING); - case TabAlertState::VIDEO_RECORDING: + case tabs::TabAlert::VIDEO_RECORDING: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_VIDEO_RECORDING); - case TabAlertState::TAB_CAPTURING: + case tabs::TabAlert::TAB_CAPTURING: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_TAB_CAPTURING); - case TabAlertState::BLUETOOTH_CONNECTED: + case tabs::TabAlert::BLUETOOTH_CONNECTED: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_BLUETOOTH_CONNECTED); - case TabAlertState::BLUETOOTH_SCAN_ACTIVE: + case tabs::TabAlert::BLUETOOTH_SCAN_ACTIVE: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_BLUETOOTH_SCAN_ACTIVE); - case TabAlertState::USB_CONNECTED: + case tabs::TabAlert::USB_CONNECTED: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_USB_CONNECTED); - case TabAlertState::HID_CONNECTED: + case tabs::TabAlert::HID_CONNECTED: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_HID_CONNECTED); - case TabAlertState::SERIAL_CONNECTED: + case tabs::TabAlert::SERIAL_CONNECTED: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_SERIAL_CONNECTED); - case TabAlertState::PIP_PLAYING: + case tabs::TabAlert::PIP_PLAYING: return l10n_util::GetStringUTF16(IDS_TOOLTIP_TAB_ALERT_STATE_PIP_PLAYING); - case TabAlertState::DESKTOP_CAPTURING: + case tabs::TabAlert::DESKTOP_CAPTURING: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_DESKTOP_CAPTURING); - case TabAlertState::VR_PRESENTING_IN_HEADSET: + case tabs::TabAlert::VR_PRESENTING_IN_HEADSET: return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_VR_PRESENTING); - case TabAlertState::GLIC_ACCESSING: + case tabs::TabAlert::GLIC_ACCESSING: #if BUILDFLAG(ENABLE_GLIC) return l10n_util::GetStringUTF16( IDS_TOOLTIP_TAB_ALERT_STATE_GLIC_ACCESSING);
diff --git a/chrome/browser/ui/tabs/tab_utils.h b/chrome/browser/ui/tabs/tab_utils.h index 83e3a69c..c5aa63f 100644 --- a/chrome/browser/ui/tabs/tab_utils.h +++ b/chrome/browser/ui/tabs/tab_utils.h
@@ -19,6 +19,10 @@ class WebContents; } // namespace content +namespace tabs { +enum class TabAlert; +} // namespace tabs + struct LastMuteMetadata : public content::WebContentsUserData<LastMuteMetadata> { TabMutedReason reason = TabMutedReason::NONE; @@ -35,11 +39,11 @@ // privacy, i.e. if only one is to be shown, it should be the first. // TabAlertState::NONE will never be present in the list; an empty list // is returned instead. -std::vector<TabAlertState> GetTabAlertStatesForContents( +std::vector<tabs::TabAlert> GetTabAlertStatesForContents( content::WebContents* contents); // Returns a localized string describing the |alert_state|. -std::u16string GetTabAlertStateText(const TabAlertState alert_state); +std::u16string GetTabAlertStateText(const tabs::TabAlert alert_state); // Sets whether all audio output from |contents| is muted, along with the // |reason| it is to be muted/unmuted (via UI or extension API). When |reason|
diff --git a/chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model_browsertest.cc b/chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model_browsertest.cc index 77effcf..e36c74f 100644 --- a/chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model_browsertest.cc +++ b/chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model_browsertest.cc
@@ -10,7 +10,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model_factory.h" #include "chrome/browser/ui/toolbar/toolbar_pref_names.h" -#include "chrome/common/chrome_features.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/testing_profile.h"
diff --git a/chrome/browser/ui/toolbar/toolbar_pref_names.cc b/chrome/browser/ui/toolbar/toolbar_pref_names.cc index 4dd7496..2ac0c02 100644 --- a/chrome/browser/ui/toolbar/toolbar_pref_names.cc +++ b/chrome/browser/ui/toolbar/toolbar_pref_names.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/ui/toolbar/toolbar_pref_names.h" #include "chrome/browser/ui/actions/chrome_action_id.h" -#include "chrome/common/chrome_features.h" +#include "chrome/browser/ui/ui_features.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_registry_simple.h" #include "ui/actions/actions.h"
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc index 25a35fdf..9309686 100644 --- a/chrome/browser/ui/ui_features.cc +++ b/chrome/browser/ui/ui_features.cc
@@ -8,7 +8,9 @@ #include "base/metrics/field_trial_params.h" #include "base/time/time.h" #include "build/build_config.h" +#include "chrome/browser/browser_process.h" #include "components/search/ntp_features.h" +#include "components/variations/service/variations_service.h" #include "components/webui/flags/feature_entry.h" #include "ui/base/ui_base_features.h" @@ -413,4 +415,37 @@ "TabStripBrowserApi", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kTabstripComboButton, + "TabstripComboButton", + base::FEATURE_DISABLED_BY_DEFAULT); + +const base::FeatureParam<bool> kTabstripComboButtonHasBackground{ + &kTabstripComboButton, "has_background", false}; + +const base::FeatureParam<bool> kTabstripComboButtonHasReverseButtonOrder{ + &kTabstripComboButton, "reverse_button_order", false}; + +const base::FeatureParam<bool> kTabSearchToolbarButton{ + &kTabstripComboButton, "tab_search_toolbar_button", false}; + +bool IsTabSearchMoving() { + return base::FeatureList::IsEnabled(features::kTabstripComboButton); +} + +bool HasTabstripComboButtonWithBackground() { + return IsTabSearchMoving() && + features::kTabstripComboButtonHasBackground.Get() && + !features::kTabSearchToolbarButton.Get(); +} + +bool HasTabstripComboButtonWithReverseButtonOrder() { + return IsTabSearchMoving() && + features::kTabstripComboButtonHasReverseButtonOrder.Get() && + !features::kTabSearchToolbarButton.Get(); +} + +bool HasTabSearchToolbarButton() { + return IsTabSearchMoving() && features::kTabSearchToolbarButton.Get(); +} + } // namespace features
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h index 1adaa40..fd90bcf 100644 --- a/chrome/browser/ui/ui_features.h +++ b/chrome/browser/ui/ui_features.h
@@ -270,6 +270,17 @@ // Controls whether to use the TabStrip browser api's controller. BASE_DECLARE_FEATURE(kTabStripBrowserApi); +// Controls where tab search lives in the browser. +BASE_DECLARE_FEATURE(kTabstripComboButton); +extern const base::FeatureParam<bool> kTabstripComboButtonHasBackground; +extern const base::FeatureParam<bool> kTabstripComboButtonHasReverseButtonOrder; +extern const base::FeatureParam<bool> kTabSearchToolbarButton; +extern const base::FeatureParam<bool> kLaunchedTabSearchToolbarButton; +bool IsTabSearchMoving(); +bool HasTabstripComboButtonWithBackground(); +bool HasTabstripComboButtonWithReverseButtonOrder(); +bool HasTabSearchToolbarButton(); + } // namespace features #endif // CHROME_BROWSER_UI_UI_FEATURES_H_
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_button_base.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_button_base.cc index 6c1ba43..9f4eee4 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_button_base.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_button_base.cc
@@ -10,6 +10,8 @@ #include "chrome/browser/ui/views/bookmarks/bookmark_button_util.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" +#include "ui/compositor/layer.h" +#include "ui/views/animation/ink_drop.h" #include "ui/views/controls/button/label_button_border.h" #include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/highlight_path_generator.h" @@ -21,6 +23,13 @@ SetImageLabelSpacing(ChromeLayoutProvider::Get()->GetDistanceMetric( DISTANCE_RELATED_LABEL_HORIZONTAL_LIST)); views::InstallPillHighlightPathGenerator(this); + +#if BUILDFLAG(IS_WIN) + // Paint image(s) to a layer so that the canvas is snapped to pixel + // boundaries. + image_container_view()->SetPaintToLayer(); + image_container_view()->layer()->SetFillsBoundsOpaquely(false); +#endif } // MenuButton: @@ -29,5 +38,18 @@ return bookmark_button_util::CreateBookmarkButtonBorder(); } +#if BUILDFLAG(IS_WIN) +void BookmarkMenuButtonBase::AddLayerToRegion(ui::Layer* new_layer, + views::LayerRegion region) { + ink_drop_container()->SetVisible(true); + ink_drop_container()->AddLayerToRegion(new_layer, region); +} + +void BookmarkMenuButtonBase::RemoveLayerFromRegions(ui::Layer* old_layer) { + ink_drop_container()->RemoveLayerFromRegions(old_layer); + ink_drop_container()->SetVisible(false); +} +#endif + BEGIN_METADATA(BookmarkMenuButtonBase) END_METADATA
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_button_base.h b/chrome/browser/ui/views/bookmarks/bookmark_menu_button_base.h index 45e54d1a..348776c 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_button_base.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_button_base.h
@@ -7,6 +7,7 @@ #include <string_view> +#include "build/buildflag.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/views/controls/button/menu_button.h" @@ -24,6 +25,11 @@ // MenuButton: std::unique_ptr<views::LabelButtonBorder> CreateDefaultBorder() const override; +#if BUILDFLAG(IS_WIN) + void AddLayerToRegion(ui::Layer* new_layer, + views::LayerRegion region) override; + void RemoveLayerFromRegions(ui::Layer* old_layer) override; +#endif }; #endif // CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_MENU_BUTTON_BASE_H_
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_overflow_button.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_overflow_button.cc index b7d3795..c0d82b53 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_overflow_button.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_overflow_button.cc
@@ -22,7 +22,9 @@ #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/ui_base_features.h" #include "ui/color/color_provider.h" +#include "ui/compositor/layer.h" #include "ui/views/accessibility/view_accessibility.h" +#include "ui/views/animation/ink_drop.h" #include "ui/views/controls/button/label_button_border.h" #include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/highlight_path_generator.h" @@ -48,6 +50,13 @@ DISTANCE_RELATED_LABEL_HORIZONTAL_LIST)); SetProperty(views::kElementIdentifierKey, kSavedTabGroupOverflowButtonElementId); + +#if BUILDFLAG(IS_WIN) + // Paint image(s) to a layer so that the canvas is snapped to pixel + // boundaries. + image_container_view()->SetPaintToLayer(); + image_container_view()->layer()->SetFillsBoundsOpaquely(false); +#endif } SavedTabGroupOverflowButton::~SavedTabGroupOverflowButton() = default; @@ -77,6 +86,19 @@ return; } +#if BUILDFLAG(IS_WIN) +void SavedTabGroupOverflowButton::AddLayerToRegion(ui::Layer* new_layer, + views::LayerRegion region) { + ink_drop_container()->SetVisible(true); + ink_drop_container()->AddLayerToRegion(new_layer, region); +} + +void SavedTabGroupOverflowButton::RemoveLayerFromRegions(ui::Layer* old_layer) { + ink_drop_container()->RemoveLayerFromRegions(old_layer); + ink_drop_container()->SetVisible(false); +} +#endif + BEGIN_METADATA(SavedTabGroupOverflowButton) END_METADATA
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_overflow_button.h b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_overflow_button.h index 1bf502c..e19c531 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_overflow_button.h +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_overflow_button.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_VIEWS_BOOKMARKS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_OVERFLOW_BUTTON_H_ #define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_SAVED_TAB_GROUPS_SAVED_TAB_GROUP_OVERFLOW_BUTTON_H_ +#include "build/buildflag.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/controls/button/menu_button.h" @@ -25,6 +26,11 @@ std::unique_ptr<views::LabelButtonBorder> CreateDefaultBorder() const override; void OnThemeChanged() override; +#if BUILDFLAG(IS_WIN) + void AddLayerToRegion(ui::Layer* new_layer, + views::LayerRegion region) override; + void RemoveLayerFromRegions(ui::Layer* old_layer) override; +#endif }; } // namespace tab_groups
diff --git a/chrome/browser/ui/views/commerce/product_specifications_button_browsertest.cc b/chrome/browser/ui/views/commerce/product_specifications_button_browsertest.cc index 2a112838..7cba8a6 100644 --- a/chrome/browser/ui/views/commerce/product_specifications_button_browsertest.cc +++ b/chrome/browser/ui/views/commerce/product_specifications_button_browsertest.cc
@@ -12,11 +12,11 @@ #include "chrome/browser/ui/commerce/product_specifications_entry_point_controller.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_prefs.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/tab_strip_region_view.h" #include "chrome/browser/ui/views/tabs/tab_search_button.h" #include "chrome/browser/ui/views/tabs/tab_strip_action_container.h" -#include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/views/chrome_views_test_base.h" #include "components/commerce/core/commerce_feature_list.h"
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index eefb48c2..047ba69 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -88,6 +88,7 @@ #include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.h" #include "chrome/browser/ui/sharing_hub/sharing_hub_bubble_view.h" #include "chrome/browser/ui/sync/one_click_signin_links_delegate_impl.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_tab_data.h" #include "chrome/browser/ui/tabs/saved_tab_groups/shared_tab_group_feedback_controller.h" #include "chrome/browser/ui/tabs/tab_enums.h" @@ -4263,66 +4264,66 @@ } // Alert tab states. - std::optional<TabAlertState> alert = tabstrip_->GetTabAlertState(index); + std::optional<tabs::TabAlert> alert = tabstrip_->GetTabAlertState(index); if (alert.has_value()) { switch (alert.value()) { - case TabAlertState::AUDIO_PLAYING: + case tabs::TabAlert::AUDIO_PLAYING: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_AUDIO_PLAYING_FORMAT, title); break; - case TabAlertState::USB_CONNECTED: + case tabs::TabAlert::USB_CONNECTED: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_USB_CONNECTED_FORMAT, title); break; - case TabAlertState::BLUETOOTH_CONNECTED: + case tabs::TabAlert::BLUETOOTH_CONNECTED: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_BLUETOOTH_CONNECTED_FORMAT, title); break; - case TabAlertState::BLUETOOTH_SCAN_ACTIVE: + case tabs::TabAlert::BLUETOOTH_SCAN_ACTIVE: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_BLUETOOTH_SCAN_ACTIVE_FORMAT, title); break; - case TabAlertState::HID_CONNECTED: + case tabs::TabAlert::HID_CONNECTED: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_HID_CONNECTED_FORMAT, title); break; - case TabAlertState::SERIAL_CONNECTED: + case tabs::TabAlert::SERIAL_CONNECTED: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_SERIAL_CONNECTED_FORMAT, title); break; - case TabAlertState::MEDIA_RECORDING: + case tabs::TabAlert::MEDIA_RECORDING: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_MEDIA_RECORDING_FORMAT, title); break; - case TabAlertState::AUDIO_RECORDING: + case tabs::TabAlert::AUDIO_RECORDING: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_AUDIO_RECORDING_FORMAT, title); break; - case TabAlertState::VIDEO_RECORDING: + case tabs::TabAlert::VIDEO_RECORDING: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_VIDEO_RECORDING_FORMAT, title); break; - case TabAlertState::AUDIO_MUTING: + case tabs::TabAlert::AUDIO_MUTING: title = l10n_util::GetStringFUTF16(IDS_TAB_AX_LABEL_AUDIO_MUTING_FORMAT, title); break; - case TabAlertState::TAB_CAPTURING: + case tabs::TabAlert::TAB_CAPTURING: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_TAB_CAPTURING_FORMAT, title); break; - case TabAlertState::PIP_PLAYING: + case tabs::TabAlert::PIP_PLAYING: title = l10n_util::GetStringFUTF16(IDS_TAB_AX_LABEL_PIP_PLAYING_FORMAT, title); break; - case TabAlertState::DESKTOP_CAPTURING: + case tabs::TabAlert::DESKTOP_CAPTURING: title = l10n_util::GetStringFUTF16( IDS_TAB_AX_LABEL_DESKTOP_CAPTURING_FORMAT, title); break; - case TabAlertState::VR_PRESENTING_IN_HEADSET: + case tabs::TabAlert::VR_PRESENTING_IN_HEADSET: title = l10n_util::GetStringFUTF16(IDS_TAB_AX_LABEL_VR_PRESENTING, title); break; - case TabAlertState::GLIC_ACCESSING: + case tabs::TabAlert::GLIC_ACCESSING: #if BUILDFLAG(ENABLE_GLIC) title = l10n_util::GetStringFUTF16(IDS_TAB_AX_LABEL_GLIC_ACCESSING, title);
diff --git a/chrome/browser/ui/views/frame/browser_view_unittest.cc b/chrome/browser/ui/views/frame/browser_view_unittest.cc index 5431782..1f61f48 100644 --- a/chrome/browser/ui/views/frame/browser_view_unittest.cc +++ b/chrome/browser/ui/views/frame/browser_view_unittest.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/performance_controls/tab_resource_usage_tab_helper.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/tab_activity_simulator.h" #include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -482,7 +483,7 @@ Tab* tab = browser_view()->tabstrip()->tab_at(0); TabRendererData start_media; - start_media.alert_state = {TabAlertState::AUDIO_PLAYING}; + start_media.alert_state = {tabs::TabAlert::AUDIO_PLAYING}; tab->SetData(std::move(start_media)); EXPECT_EQ(SubBrowserName(u"about:blank - Audio playing - ", u""), browser_view()->GetAccessibleWindowTitleForChannelAndProfile(
diff --git a/chrome/browser/ui/views/frame/system_menu_model_builder_browsertest.cc b/chrome/browser/ui/views/frame/system_menu_model_builder_browsertest.cc index e0e9f4b..d3157ca 100644 --- a/chrome/browser/ui/views/frame/system_menu_model_builder_browsertest.cc +++ b/chrome/browser/ui/views/frame/system_menu_model_builder_browsertest.cc
@@ -5,6 +5,7 @@ #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/ui/views/frame/tab_strip_region_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/tab_strip_region_view_interactive_uitest.cc index fe7aa57c..9521ccb 100644 --- a/chrome/browser/ui/views/frame/tab_strip_region_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/frame/tab_strip_region_view_interactive_uitest.cc
@@ -10,13 +10,13 @@ #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/tabs/features.h" #include "chrome/browser/ui/tabs/tab_strip_prefs.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/tab_strip_region_view.h" #include "chrome/browser/ui/views/tabs/new_tab_button.h" #include "chrome/browser/ui/views/tabs/tab_search_button.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/tabs/tab_strip_combo_button.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc b/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc index 8753aa8..9b54387 100644 --- a/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc
@@ -3,12 +3,18 @@ // found in the LICENSE file. #include "build/build_config.h" +#include "chrome/browser/ui/actions/chrome_action_id.h" +#include "chrome/browser/ui/browser_window/public/browser_window_features.h" +#include "chrome/browser/ui/page_action/page_action_icon_type.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/browser/ui/views/location_bar/location_icon_view.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" +#include "chrome/browser/ui/views/page_action/page_action_view.h" #include "chrome/browser/ui/views/page_info/page_info_bubble_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" +#include "chrome/browser/ui/views/translate/translate_bubble_controller.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" #include "content/public/test/browser_test.h" @@ -80,15 +86,25 @@ web_contents, translate::TRANSLATE_STEP_AFTER_TRANSLATE, "en", "fr", translate::TranslateErrors::NONE, true); - PageActionIconView* icon_view = - browser_view->toolbar_button_provider()->GetPageActionIconView( - PageActionIconType::kTranslate); + views::View* icon_view; + if (IsPageActionMigrated(PageActionIconType::kTranslate)) { + icon_view = browser_view->toolbar_button_provider()->GetPageActionView( + kActionShowTranslate); + } else { + icon_view = browser_view->toolbar_button_provider()->GetPageActionIconView( + PageActionIconType::kTranslate); + } + ASSERT_TRUE(icon_view); EXPECT_TRUE(icon_view->GetVisible()); // Ensure the bubble's widget is visible, but inactive. Active widgets are // focused by accessibility, so not of concern. - views::Widget* widget = icon_view->GetBubble()->GetWidget(); + views::Widget* widget = browser() + ->GetFeatures() + .translate_bubble_controller() + ->GetTranslateBubble() + ->GetWidget(); widget->Deactivate(); widget->ShowInactive(); EXPECT_TRUE(widget->IsVisible());
diff --git a/chrome/browser/ui/views/side_panel/side_panel_interactive_uitest.cc b/chrome/browser/ui/views/side_panel/side_panel_interactive_uitest.cc index e824643..003adf2 100644 --- a/chrome/browser/ui/views/side_panel/side_panel_interactive_uitest.cc +++ b/chrome/browser/ui/views/side_panel/side_panel_interactive_uitest.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/ui/toolbar/app_menu_model.h" #include "chrome/browser/ui/toolbar/bookmark_sub_menu_model.h" #include "chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h" @@ -26,7 +27,6 @@ #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/browser/ui/web_applications/web_app_launch_utils.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/interaction/interaction_test_util_browser.h" #include "chrome/test/interaction/interactive_browser_test.h"
diff --git a/chrome/browser/ui/views/tabs/alert_indicator_button.cc b/chrome/browser/ui/views/tabs/alert_indicator_button.cc index 25262f5..85672a1 100644 --- a/chrome/browser/ui/views/tabs/alert_indicator_button.cc +++ b/chrome/browser/ui/views/tabs/alert_indicator_button.cc
@@ -13,6 +13,7 @@ #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/browser_element_identifiers.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/views/tabs/tab.h" #include "chrome/browser/ui/views/tabs/tab_slot_controller.h" #include "chrome/common/chrome_features.h" @@ -90,28 +91,28 @@ } ui::ImageModel GetTabAlertIndicatorImageForPressedState( - TabAlertState alert_state, + tabs::TabAlert alert_state, ui::ColorId button_color) { switch (alert_state) { - case TabAlertState::AUDIO_PLAYING: + case tabs::TabAlert::AUDIO_PLAYING: return AlertIndicatorButton::GetTabAlertIndicatorImage( - TabAlertState::AUDIO_MUTING, button_color); - case TabAlertState::AUDIO_MUTING: + tabs::TabAlert::AUDIO_MUTING, button_color); + case tabs::TabAlert::AUDIO_MUTING: return AlertIndicatorButton::GetTabAlertIndicatorImage( - TabAlertState::AUDIO_PLAYING, button_color); - case TabAlertState::MEDIA_RECORDING: - case TabAlertState::AUDIO_RECORDING: - case TabAlertState::VIDEO_RECORDING: - case TabAlertState::TAB_CAPTURING: - case TabAlertState::BLUETOOTH_CONNECTED: - case TabAlertState::USB_CONNECTED: - case TabAlertState::PIP_PLAYING: - case TabAlertState::DESKTOP_CAPTURING: - case TabAlertState::BLUETOOTH_SCAN_ACTIVE: - case TabAlertState::HID_CONNECTED: - case TabAlertState::SERIAL_CONNECTED: - case TabAlertState::VR_PRESENTING_IN_HEADSET: - case TabAlertState::GLIC_ACCESSING: + tabs::TabAlert::AUDIO_PLAYING, button_color); + case tabs::TabAlert::MEDIA_RECORDING: + case tabs::TabAlert::AUDIO_RECORDING: + case tabs::TabAlert::VIDEO_RECORDING: + case tabs::TabAlert::TAB_CAPTURING: + case tabs::TabAlert::BLUETOOTH_CONNECTED: + case tabs::TabAlert::USB_CONNECTED: + case tabs::TabAlert::PIP_PLAYING: + case tabs::TabAlert::DESKTOP_CAPTURING: + case tabs::TabAlert::BLUETOOTH_SCAN_ACTIVE: + case tabs::TabAlert::HID_CONNECTED: + case tabs::TabAlert::SERIAL_CONNECTED: + case tabs::TabAlert::VR_PRESENTING_IN_HEADSET: + case tabs::TabAlert::GLIC_ACCESSING: return AlertIndicatorButton::GetTabAlertIndicatorImage(alert_state, button_color); } @@ -162,22 +163,22 @@ AlertIndicatorButton::~AlertIndicatorButton() = default; void AlertIndicatorButton::TransitionToAlertState( - std::optional<TabAlertState> next_state) { + std::optional<tabs::TabAlert> next_state) { if (next_state == alert_state_) { return; } - std::optional<TabAlertState> previous_alert_showing_state = + std::optional<tabs::TabAlert> previous_alert_showing_state = showing_alert_state_; if (next_state) { UpdateIconForAlertState(next_state.value()); } - if ((alert_state_ == TabAlertState::AUDIO_PLAYING && - next_state == TabAlertState::AUDIO_MUTING) || - (alert_state_ == TabAlertState::AUDIO_MUTING && - next_state == TabAlertState::AUDIO_PLAYING)) { + if ((alert_state_ == tabs::TabAlert::AUDIO_PLAYING && + next_state == tabs::TabAlert::AUDIO_MUTING) || + (alert_state_ == tabs::TabAlert::AUDIO_MUTING && + next_state == tabs::TabAlert::AUDIO_PLAYING)) { // Instant user feedback: No fade animation. showing_alert_state_ = next_state; fade_animation_.reset(); @@ -208,8 +209,8 @@ const bool was_enabled = GetEnabled(); bool enable = base::FeatureList::IsEnabled(media::kEnableTabMuting) && - (alert_state_ == TabAlertState::AUDIO_PLAYING || - alert_state_ == TabAlertState::AUDIO_MUTING); + (alert_state_ == tabs::TabAlert::AUDIO_PLAYING || + alert_state_ == tabs::TabAlert::AUDIO_MUTING); // If the tab is not the currently-active tab, make sure it is wide enough // before enabling click-to-mute. This ensures that there is enough click @@ -229,8 +230,8 @@ } void AlertIndicatorButton::OnParentTabButtonColorChanged() { - if (alert_state_ == TabAlertState::AUDIO_PLAYING || - alert_state_ == TabAlertState::AUDIO_MUTING) { + if (alert_state_ == tabs::TabAlert::AUDIO_PLAYING || + alert_state_ == tabs::TabAlert::AUDIO_MUTING) { UpdateIconForAlertState(alert_state_.value()); } } @@ -268,13 +269,13 @@ // instant feedback. In the very unlikely event that the mute toggle fails, // TransitionToAlertState() will be called again, via another code path, to // set the image to be consistent with the final outcome. - if (alert_state_ == TabAlertState::AUDIO_PLAYING) { + if (alert_state_ == tabs::TabAlert::AUDIO_PLAYING) { base::RecordAction(base::UserMetricsAction("AlertIndicatorButton_Mute")); - TransitionToAlertState(TabAlertState::AUDIO_MUTING); + TransitionToAlertState(tabs::TabAlert::AUDIO_MUTING); } else { - DCHECK(alert_state_ == TabAlertState::AUDIO_MUTING); + DCHECK(alert_state_ == tabs::TabAlert::AUDIO_MUTING); base::RecordAction(base::UserMetricsAction("AlertIndicatorButton_Unmute")); - TransitionToAlertState(TabAlertState::AUDIO_PLAYING); + TransitionToAlertState(tabs::TabAlert::AUDIO_PLAYING); } GetTab()->controller()->ToggleTabAudioMute(GetTab()); @@ -325,15 +326,15 @@ std::unique_ptr<gfx::Animation> AlertIndicatorButton::CreateTabAlertIndicatorFadeAnimation( - std::optional<TabAlertState> alert_state) { - if (alert_state == TabAlertState::MEDIA_RECORDING || - alert_state == TabAlertState::AUDIO_RECORDING || - alert_state == TabAlertState::VIDEO_RECORDING || - alert_state == TabAlertState::TAB_CAPTURING || - alert_state == TabAlertState::DESKTOP_CAPTURING) { - if ((alert_state == TabAlertState::MEDIA_RECORDING || - alert_state == TabAlertState::AUDIO_RECORDING || - alert_state == TabAlertState::VIDEO_RECORDING) && + std::optional<tabs::TabAlert> alert_state) { + if (alert_state == tabs::TabAlert::MEDIA_RECORDING || + alert_state == tabs::TabAlert::AUDIO_RECORDING || + alert_state == tabs::TabAlert::VIDEO_RECORDING || + alert_state == tabs::TabAlert::TAB_CAPTURING || + alert_state == tabs::TabAlert::DESKTOP_CAPTURING) { + if ((alert_state == tabs::TabAlert::MEDIA_RECORDING || + alert_state == tabs::TabAlert::AUDIO_RECORDING || + alert_state == tabs::TabAlert::VIDEO_RECORDING) && camera_mic_indicator_start_time_ == base::Time()) { camera_mic_indicator_start_time_ = base::Time::Now(); } @@ -380,53 +381,53 @@ // Returns a cached image, to be shown by the alert indicator for the given // `alert_state`. Uses the global ui::ResourceBundle shared instance. ui::ImageModel AlertIndicatorButton::GetTabAlertIndicatorImage( - TabAlertState alert_state, + tabs::TabAlert alert_state, ui::ColorId button_color) { const gfx::VectorIcon* icon = nullptr; int image_width = GetLayoutConstant(TAB_ALERT_INDICATOR_ICON_WIDTH); switch (alert_state) { - case TabAlertState::AUDIO_PLAYING: + case tabs::TabAlert::AUDIO_PLAYING: icon = &vector_icons::kVolumeUpChromeRefreshIcon; break; - case TabAlertState::AUDIO_MUTING: + case tabs::TabAlert::AUDIO_MUTING: icon = &vector_icons::kVolumeOffChromeRefreshIcon; break; - case TabAlertState::MEDIA_RECORDING: - case TabAlertState::AUDIO_RECORDING: - case TabAlertState::VIDEO_RECORDING: - case TabAlertState::DESKTOP_CAPTURING: + case tabs::TabAlert::MEDIA_RECORDING: + case tabs::TabAlert::AUDIO_RECORDING: + case tabs::TabAlert::VIDEO_RECORDING: + case tabs::TabAlert::DESKTOP_CAPTURING: icon = &vector_icons::kRadioButtonCheckedIcon; break; - case TabAlertState::TAB_CAPTURING: + case tabs::TabAlert::TAB_CAPTURING: icon = &vector_icons::kCaptureIcon; // Tab capturing and presenting icon uses a different width compared to // the other tab alert indicator icons. image_width = GetLayoutConstant(TAB_ALERT_INDICATOR_CAPTURE_ICON_WIDTH); break; - case TabAlertState::BLUETOOTH_CONNECTED: + case tabs::TabAlert::BLUETOOTH_CONNECTED: icon = &vector_icons::kBluetoothConnectedIcon; break; - case TabAlertState::BLUETOOTH_SCAN_ACTIVE: + case tabs::TabAlert::BLUETOOTH_SCAN_ACTIVE: icon = &vector_icons::kBluetoothScanningChromeRefreshIcon; break; - case TabAlertState::USB_CONNECTED: + case tabs::TabAlert::USB_CONNECTED: icon = &vector_icons::kUsbChromeRefreshIcon; icon = &kTabUsbConnectedIcon; break; - case TabAlertState::HID_CONNECTED: + case tabs::TabAlert::HID_CONNECTED: icon = &vector_icons::kVideogameAssetChromeRefreshIcon; break; - case TabAlertState::SERIAL_CONNECTED: + case tabs::TabAlert::SERIAL_CONNECTED: icon = &vector_icons::kSerialPortChromeRefreshIcon; break; - case TabAlertState::PIP_PLAYING: + case tabs::TabAlert::PIP_PLAYING: icon = &vector_icons::kPictureInPictureAltIcon; break; - case TabAlertState::VR_PRESENTING_IN_HEADSET: + case tabs::TabAlert::VR_PRESENTING_IN_HEADSET: icon = &vector_icons::kCardboardIcon; break; - case TabAlertState::GLIC_ACCESSING: + case tabs::TabAlert::GLIC_ACCESSING: #if BUILDFLAG(ENABLE_GLIC) icon = &glic::GlicVectorIconManager::GetVectorIcon(IDR_GLIC_ACCESSING_ICON); @@ -440,34 +441,34 @@ } ui::ImageModel AlertIndicatorButton::GetTabAlertIndicatorImageForHoverCard( - TabAlertState alert_state) { + tabs::TabAlert alert_state) { switch (alert_state) { - case TabAlertState::MEDIA_RECORDING: - case TabAlertState::AUDIO_RECORDING: - case TabAlertState::VIDEO_RECORDING: - case TabAlertState::DESKTOP_CAPTURING: + case tabs::TabAlert::MEDIA_RECORDING: + case tabs::TabAlert::AUDIO_RECORDING: + case tabs::TabAlert::VIDEO_RECORDING: + case tabs::TabAlert::DESKTOP_CAPTURING: return AlertIndicatorButton::GetTabAlertIndicatorImage( alert_state, kColorHoverCardTabAlertMediaRecordingIcon); - case TabAlertState::TAB_CAPTURING: - case TabAlertState::PIP_PLAYING: - case TabAlertState::GLIC_ACCESSING: + case tabs::TabAlert::TAB_CAPTURING: + case tabs::TabAlert::PIP_PLAYING: + case tabs::TabAlert::GLIC_ACCESSING: return AlertIndicatorButton::GetTabAlertIndicatorImage( alert_state, kColorHoverCardTabAlertPipPlayingIcon); - case TabAlertState::AUDIO_PLAYING: - case TabAlertState::AUDIO_MUTING: - case TabAlertState::BLUETOOTH_CONNECTED: - case TabAlertState::BLUETOOTH_SCAN_ACTIVE: - case TabAlertState::USB_CONNECTED: - case TabAlertState::HID_CONNECTED: - case TabAlertState::SERIAL_CONNECTED: - case TabAlertState::VR_PRESENTING_IN_HEADSET: + case tabs::TabAlert::AUDIO_PLAYING: + case tabs::TabAlert::AUDIO_MUTING: + case tabs::TabAlert::BLUETOOTH_CONNECTED: + case tabs::TabAlert::BLUETOOTH_SCAN_ACTIVE: + case tabs::TabAlert::USB_CONNECTED: + case tabs::TabAlert::HID_CONNECTED: + case tabs::TabAlert::SERIAL_CONNECTED: + case tabs::TabAlert::VR_PRESENTING_IN_HEADSET: return AlertIndicatorButton::GetTabAlertIndicatorImage( alert_state, kColorHoverCardTabAlertAudioPlayingIcon); } NOTREACHED(); } -void AlertIndicatorButton::UpdateIconForAlertState(TabAlertState state) { +void AlertIndicatorButton::UpdateIconForAlertState(tabs::TabAlert state) { const ui::ColorId color = parent_tab_->GetAlertIndicatorColor(state); const ui::ImageModel indicator_image = GetTabAlertIndicatorImage(state, color);
diff --git a/chrome/browser/ui/views/tabs/alert_indicator_button.h b/chrome/browser/ui/views/tabs/alert_indicator_button.h index 141497c..c7d7e313 100644 --- a/chrome/browser/ui/views/tabs/alert_indicator_button.h +++ b/chrome/browser/ui/views/tabs/alert_indicator_button.h
@@ -23,6 +23,10 @@ class AnimationDelegate; } // namespace gfx +namespace tabs { +enum class TabAlert; +} // namespace tabs + // This is an ImageButton subclass that serves as both the alert indicator icon // (audio, tab capture, etc.), and as a mute button. It is meant to only be // used as a child view of Tab. @@ -41,26 +45,26 @@ AlertIndicatorButton& operator=(const AlertIndicatorButton&) = delete; ~AlertIndicatorButton() override; - static ui::ImageModel GetTabAlertIndicatorImage(TabAlertState alert_state, + static ui::ImageModel GetTabAlertIndicatorImage(tabs::TabAlert alert_state, ui::ColorId button_color); static ui::ImageModel GetTabAlertIndicatorImageForHoverCard( - TabAlertState alert_state); + tabs::TabAlert alert_state); - // Returns the current TabAlertState except, while the indicator image is - // fading out, returns the prior TabAlertState. - std::optional<TabAlertState> showing_alert_state() const { + // Returns the current TabAlert except, while the indicator image is + // fading out, returns the prior TabAlert. + std::optional<tabs::TabAlert> showing_alert_state() const { return showing_alert_state_; } // Calls ResetImages(), starts fade animations, and activates/deactivates // button functionality as appropriate. - void TransitionToAlertState(std::optional<TabAlertState> next_state); + void TransitionToAlertState(std::optional<tabs::TabAlert> next_state); // Determines whether the AlertIndicatorButton will be clickable for toggling // muting. This should be called whenever the active/inactive state of a tab // has changed. Internally, TransitionToAlertState() and OnBoundsChanged() - // calls this when the TabAlertState or the bounds have changed. + // calls this when the TabAlert or the bounds have changed. void UpdateEnabledForMuteToggle(); // Called when the parent tab's button color changes. Determines whether @@ -97,24 +101,24 @@ // indicator to alert the user that recording, tab capture, or audio playback // has started/stopped. std::unique_ptr<gfx::Animation> CreateTabAlertIndicatorFadeAnimation( - std::optional<TabAlertState> alert_state); + std::optional<tabs::TabAlert> alert_state); // Returns the tab (parent view) of this AlertIndicatorButton. Tab* GetTab(); // Resets the images to display on the button to reflect `state` and the // parent tab's button color. Should be called when either of these changes. - void UpdateIconForAlertState(TabAlertState state); + void UpdateIconForAlertState(tabs::TabAlert state); const raw_ptr<Tab> parent_tab_; - std::optional<TabAlertState> alert_state_; + std::optional<tabs::TabAlert> alert_state_; // Alert indicator fade-in/out animation (i.e., only on show/hide, not a // continuous animation). std::unique_ptr<gfx::AnimationDelegate> fade_animation_delegate_; std::unique_ptr<gfx::Animation> fade_animation_; - std::optional<TabAlertState> showing_alert_state_; + std::optional<tabs::TabAlert> showing_alert_state_; // The time when the alert indicator is displayed when a camera and/or a // microphone are captured.
diff --git a/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.cc index 8fd4d8e..8e267520 100644 --- a/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.cc +++ b/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.cc
@@ -1169,7 +1169,7 @@ TabDragContext* attached_context, std::unique_ptr<TabDragController> controller, std::vector<std::variant<std::unique_ptr<tabs::TabModel>, - std::unique_ptr<DetachedTabGroup>>> + std::unique_ptr<DetachedTabCollection>>> owned_tabs_and_groups) { // We should already have detached by the time we get here. CHECK(!attached_context_); @@ -1227,7 +1227,7 @@ index++; } else { auto group = std::move( - *std::get_if<std::unique_ptr<DetachedTabGroup>>(&tab_or_group)); + *std::get_if<std::unique_ptr<DetachedTabCollection>>(&tab_or_group)); // If it's a group - we add it to the tabstrip. This will add all the // tabs. const gfx::Range group_indices = @@ -1279,7 +1279,7 @@ std::tuple<std::unique_ptr<TabDragController>, std::vector<std::variant<std::unique_ptr<tabs::TabModel>, - std::unique_ptr<DetachedTabGroup>>>> + std::unique_ptr<DetachedTabCollection>>>> TabDragController::Detach(ReleaseCapture release_capture) { TRACE_EVENT1("views", "TabDragController::Detach", "release_capture", release_capture); @@ -1326,7 +1326,7 @@ attached_model->GetGroupsDestroyedFromRemovingIndices(dragged_indices); std::vector<std::variant<std::unique_ptr<tabs::TabModel>, - std::unique_ptr<DetachedTabGroup>>> + std::unique_ptr<DetachedTabCollection>>> owned_tabs_and_groups; for (TabDragData& tab_drag_datum : drag_data_.tab_drag_data_) { const int index =
diff --git a/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.h b/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.h index 388524da..d7b8af8 100644 --- a/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.h +++ b/chrome/browser/ui/views/tabs/dragging/tab_drag_controller.h
@@ -59,7 +59,7 @@ class TabStripScrollSession; class WindowFinder; class TabStripScrollSession; -struct DetachedTabGroup; +struct DetachedTabCollection; // TabDragController is responsible for managing the tab dragging session. When // the user presses the mouse on a tab a new TabDragController is created and @@ -352,7 +352,7 @@ TabDragContext* attached_context, std::unique_ptr<TabDragController> controller, std::vector<std::variant<std::unique_ptr<tabs::TabModel>, - std::unique_ptr<DetachedTabGroup>>> + std::unique_ptr<DetachedTabCollection>>> owned_tabs_and_groups); // Sets up dragging in `attached_context_`. The dragged tabs must already @@ -365,7 +365,7 @@ // nullptr. std::tuple<std::unique_ptr<TabDragController>, std::vector<std::variant<std::unique_ptr<tabs::TabModel>, - std::unique_ptr<DetachedTabGroup>>>> + std::unique_ptr<DetachedTabCollection>>>> Detach(ReleaseCapture release_capture); // Detach from `attached_context_` and attach to `target_context` instead.
diff --git a/chrome/browser/ui/views/tabs/fade_footer_view.cc b/chrome/browser/ui/views/tabs/fade_footer_view.cc index 1e9c2de..913a7c2 100644 --- a/chrome/browser/ui/views/tabs/fade_footer_view.cc +++ b/chrome/browser/ui/views/tabs/fade_footer_view.cc
@@ -8,6 +8,7 @@ #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/views/tabs/alert_indicator_button.h" #include "chrome/grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" @@ -124,7 +125,7 @@ // ----------------------------------------------------------------------- void FadeAlertFooterRow::SetData(const AlertFooterRowData& data) { - std::optional<TabAlertState> alert_state = data.alert_state; + std::optional<tabs::TabAlert> alert_state = data.alert_state; if (data.should_show_discard_status) { std::u16string row_text; if (data.memory_savings_in_bytes > 0) {
diff --git a/chrome/browser/ui/views/tabs/fade_footer_view.h b/chrome/browser/ui/views/tabs/fade_footer_view.h index 2df0381..696a7ca 100644 --- a/chrome/browser/ui/views/tabs/fade_footer_view.h +++ b/chrome/browser/ui/views/tabs/fade_footer_view.h
@@ -7,7 +7,6 @@ #include <string> -#include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/views/tabs/fade_view.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/gfx/geometry/size.h" @@ -15,8 +14,12 @@ #include "ui/views/controls/label.h" #include "ui/views/layout/flex_layout.h" +namespace tabs { +enum class TabAlert; +} // namespace tabs + struct AlertFooterRowData { - std::optional<TabAlertState> alert_state; + std::optional<tabs::TabAlert> alert_state; bool should_show_discard_status = false; int64_t memory_savings_in_bytes = 0; };
diff --git a/chrome/browser/ui/views/tabs/glic_button_browsertest.cc b/chrome/browser/ui/views/tabs/glic_button_browsertest.cc index 903b6083..f78440b 100644 --- a/chrome/browser/ui/views/tabs/glic_button_browsertest.cc +++ b/chrome/browser/ui/views/tabs/glic_button_browsertest.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/glic/test_support/glic_test_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/tab_strip_region_view.h" #include "chrome/browser/ui/views/tabs/tab_strip_action_container.h"
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index 8867580..c34a8256 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/tab_contents/core_tab_helper.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_tab_data.h" #include "chrome/browser/ui/tabs/tab_style.h" #include "chrome/browser/ui/tabs/tab_utils.h" @@ -846,7 +847,7 @@ controller_->GetGroupColorId(group().value())); } -ui::ColorId Tab::GetAlertIndicatorColor(TabAlertState state) const { +ui::ColorId Tab::GetAlertIndicatorColor(tabs::TabAlert state) const { const ui::ColorProvider* color_provider = GetColorProvider(); if (!color_provider) { return gfx::kPlaceholderColor; @@ -854,25 +855,25 @@ int group; switch (state) { - case TabAlertState::MEDIA_RECORDING: - case TabAlertState::AUDIO_RECORDING: - case TabAlertState::VIDEO_RECORDING: - case TabAlertState::DESKTOP_CAPTURING: + case tabs::TabAlert::MEDIA_RECORDING: + case tabs::TabAlert::AUDIO_RECORDING: + case tabs::TabAlert::VIDEO_RECORDING: + case tabs::TabAlert::DESKTOP_CAPTURING: group = 0; break; - case TabAlertState::TAB_CAPTURING: - case TabAlertState::PIP_PLAYING: - case TabAlertState::GLIC_ACCESSING: + case tabs::TabAlert::TAB_CAPTURING: + case tabs::TabAlert::PIP_PLAYING: + case tabs::TabAlert::GLIC_ACCESSING: group = 1; break; - case TabAlertState::AUDIO_PLAYING: - case TabAlertState::AUDIO_MUTING: - case TabAlertState::BLUETOOTH_CONNECTED: - case TabAlertState::BLUETOOTH_SCAN_ACTIVE: - case TabAlertState::USB_CONNECTED: - case TabAlertState::HID_CONNECTED: - case TabAlertState::SERIAL_CONNECTED: - case TabAlertState::VR_PRESENTING_IN_HEADSET: + case tabs::TabAlert::AUDIO_PLAYING: + case tabs::TabAlert::AUDIO_MUTING: + case tabs::TabAlert::BLUETOOTH_CONNECTED: + case tabs::TabAlert::BLUETOOTH_SCAN_ACTIVE: + case tabs::TabAlert::USB_CONNECTED: + case tabs::TabAlert::HID_CONNECTED: + case tabs::TabAlert::SERIAL_CONNECTED: + case tabs::TabAlert::VR_PRESENTING_IN_HEADSET: group = 2; break; } @@ -1055,7 +1056,7 @@ // static std::u16string Tab::GetTooltipText(const std::u16string& title, - std::optional<TabAlertState> alert_state) { + std::optional<tabs::TabAlert> alert_state) { if (!alert_state) { return title; } @@ -1069,8 +1070,8 @@ } // static -std::optional<TabAlertState> Tab::GetAlertStateToShow( - const std::vector<TabAlertState>& alert_states) { +std::optional<tabs::TabAlert> Tab::GetAlertStateToShow( + const std::vector<tabs::TabAlert>& alert_states) { if (alert_states.empty()) { return std::nullopt; } @@ -1264,7 +1265,7 @@ if (!alert_indicator_button_ || !alert_indicator_button_->GetVisible()) { base::RecordAction(UserMetricsAction("CloseTab_NoAlertIndicator")); } else if (GetAlertStateToShow(data_.alert_state) == - TabAlertState::AUDIO_PLAYING) { + tabs::TabAlert::AUDIO_PLAYING) { base::RecordAction(UserMetricsAction("CloseTab_AudioIndicator")); } else { base::RecordAction(UserMetricsAction("CloseTab_RecordingIndicator"));
diff --git a/chrome/browser/ui/views/tabs/tab.h b/chrome/browser/ui/views/tabs/tab.h index 6894d79..13e379a 100644 --- a/chrome/browser/ui/views/tabs/tab.h +++ b/chrome/browser/ui/views/tabs/tab.h
@@ -43,6 +43,10 @@ class View; } // namespace views +namespace tabs { +enum class TabAlert; +} + /////////////////////////////////////////////////////////////////////////////// // // A View that renders a Tab in a TabStrip. @@ -116,7 +120,7 @@ std::optional<SkColor> GetGroupColor() const; // Returns the color used for the alert indicator icon. - ui::ColorId GetAlertIndicatorColor(TabAlertState state) const; + ui::ColorId GetAlertIndicatorColor(tabs::TabAlert state) const; // Returns true if this tab is the active tab. bool IsActive() const; @@ -179,11 +183,11 @@ // Exposed publicly for tests. static std::u16string GetTooltipText( const std::u16string& title, - std::optional<TabAlertState> alert_state); + std::optional<tabs::TabAlert> alert_state); // Returns an alert state to be shown among given alert states. - static std::optional<TabAlertState> GetAlertStateToShow( - const std::vector<TabAlertState>& alert_states); + static std::optional<tabs::TabAlert> GetAlertStateToShow( + const std::vector<tabs::TabAlert>& alert_states); bool showing_close_button_for_testing() const { return showing_close_button_;
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h index 19a3d6c2..2926468 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.h
@@ -31,6 +31,10 @@ class ImageSkia; } +namespace tabs { +enum class TabAlert; +} + class Tab; class TabStyle; class FadeLabelView; @@ -104,7 +108,7 @@ raw_ptr<FadeLabelView> domain_label_ = nullptr; raw_ptr<ThumbnailView> thumbnail_view_ = nullptr; raw_ptr<FooterView> footer_view_ = nullptr; - std::optional<TabAlertState> alert_state_; + std::optional<tabs::TabAlert> alert_state_; const raw_ptr<const TabStyle> tab_style_; const InitParams bubble_params_;
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc index d9b3a563..f704389d 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller_interactive_uitest.cc
@@ -19,8 +19,8 @@ #include "chrome/browser/ui/performance_controls/tab_resource_usage_tab_helper.h" #include "chrome/browser/ui/performance_controls/test_support/memory_metrics_refresh_waiter.h" #include "chrome/browser/ui/performance_controls/test_support/memory_saver_interactive_test_mixin.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_tab_data.h" -#include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/test/tab_strip_interactive_test_mixin.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/tabs/fade_footer_view.h" @@ -82,7 +82,7 @@ TabRendererData new_tab_data = TabRendererData(); new_tab_data.title = kTabTitle; new_tab_data.last_committed_url = GURL(kTabUrl); - new_tab_data.alert_state = {TabAlertState::AUDIO_PLAYING}; + new_tab_data.alert_state = {tabs::TabAlert::AUDIO_PLAYING}; return new_tab_data; } @@ -747,7 +747,7 @@ browser()->tab_strip_model()->ActivateTabAt(0); Tab* const tab = tab_strip->tab_at(1); TabRendererData data = tab->data(); - data.alert_state = {TabAlertState::AUDIO_PLAYING}; + data.alert_state = {tabs::TabAlert::AUDIO_PLAYING}; tab->SetData(data); tab_strip->GetFocusManager()->SetFocusedView(tab); WaitForHoverCardVisible(tab_strip);
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 0d8bfbe..713beef 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -48,6 +48,7 @@ #include "chrome/browser/ui/browser_element_identifiers.h" #include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/features.h" #include "chrome/browser/ui/tabs/tab_group_theme.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -1107,7 +1108,7 @@ return tab_at(tab_index)->data().network_state == TabNetworkState::kError; } -std::optional<TabAlertState> TabStrip::GetTabAlertState(int tab_index) const { +std::optional<tabs::TabAlert> TabStrip::GetTabAlertState(int tab_index) const { return Tab::GetAlertStateToShow(tab_at(tab_index)->data().alert_state); }
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index b3249f63..eddce1f 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -16,7 +16,6 @@ #include "base/memory/raw_ref.h" #include "base/time/time.h" #include "build/build_config.h" -#include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_types.h" #include "chrome/browser/ui/tabs/tab_utils.h" #include "chrome/browser/ui/views/frame/browser_root_view.h" @@ -58,6 +57,10 @@ class ListSelectionModel; } +namespace tabs { +enum class TabAlert; +} // namespace tabs + // A View that represents the TabStripModel. The TabStrip has the // following responsibilities: // @@ -120,7 +123,7 @@ // Returns information about tabs at given indices. bool IsTabCrashed(int tab_index) const; bool TabHasNetworkError(int tab_index) const; - std::optional<TabAlertState> GetTabAlertState(int tab_index) const; + std::optional<tabs::TabAlert> GetTabAlertState(int tab_index) const; // Updates the loading animations displayed by tabs in the tabstrip to the // next frame. The `elapsed_time` parameter is shared between tabs and used to
diff --git a/chrome/browser/ui/views/tabs/tab_strip_action_container_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_action_container_unittest.cc index 1657940..a88558b 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_action_container_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_action_container_unittest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/ui/browser_window/test/mock_browser_window_interface.h" #include "chrome/browser/ui/tabs/test/mock_tab_interface.h" #include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/commerce/product_specifications_button.h" #include "chrome/browser/ui/views/frame/tab_strip_region_view.h" #include "chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h"
diff --git a/chrome/browser/ui/views/tabs/tab_strip_browsertest.cc b/chrome/browser/ui/views/tabs/tab_strip_browsertest.cc index 794fbc86..58dcc8a7a 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_browsertest.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_browsertest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/browser_command_controller.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/performance_controls/tab_resource_usage_tab_helper.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h" #include "chrome/browser/ui/tabs/tab_group.h" #include "chrome/browser/ui/tabs/tab_group_model.h" @@ -130,7 +131,7 @@ tab_groups::TabGroupId group = tab_strip_model()->AddToNewGroup({0, 1}); - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = tab_strip_model()->DetachTabGroupForInsertion(group); EXPECT_EQ(tab_strip()->GetTabCount(), 1); @@ -1000,7 +1001,7 @@ // AccessibleName update with alert on tab tab_renderer_data = tab_strip()->tab_at(new_index)->data(); tab_renderer_data.network_state = TabNetworkState::kLoading; - tab_renderer_data.alert_state.push_back(TabAlertState::AUDIO_PLAYING); + tab_renderer_data.alert_state.push_back(tabs::TabAlert::AUDIO_PLAYING); tab_strip()->tab_at(new_index)->SetData(tab_renderer_data); data = ui::AXNodeData(); tab_strip()->tab_at(new_index)->GetViewAccessibility().GetAccessibleNodeData(
diff --git a/chrome/browser/ui/views/tabs/tab_strip_combo_button.cc b/chrome/browser/ui/views/tabs/tab_strip_combo_button.cc index 2f219a6..27fba58 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_combo_button.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_combo_button.cc
@@ -9,10 +9,10 @@ #include "chrome/browser/ui/browser_element_identifiers.h" #include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/tabs/tab_search_button.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/tabs/tab_strip_control_button.h" -#include "chrome/common/chrome_features.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/vector_icons/vector_icons.h"
diff --git a/chrome/browser/ui/views/tabs/tab_strip_combo_button_browsertest.cc b/chrome/browser/ui/views/tabs/tab_strip_combo_button_browsertest.cc index b3b4718..66329cf8 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_combo_button_browsertest.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_combo_button_browsertest.cc
@@ -6,10 +6,10 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/tab_strip_region_view.h" #include "chrome/browser/ui/views/tabs/tab_search_button.h" -#include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.cc b/chrome/browser/ui/views/tabs/tab_style_views.cc index 3e2e0f0a..b8a53a0 100644 --- a/chrome/browser/ui/views/tabs/tab_style_views.cc +++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/tabs/tab_style.h" #include "chrome/browser/ui/tabs/tab_types.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/top_container_background.h" @@ -27,7 +28,6 @@ #include "chrome/browser/ui/views/tabs/tab_group_underline.h" #include "chrome/browser/ui/views/tabs/tab_slot_controller.h" #include "chrome/browser/ui/views/tabs/tab_slot_view.h" -#include "chrome/common/chrome_features.h" #include "chrome/grit/theme_resources.h" #include "components/tab_groups/tab_group_visual_data.h" #include "third_party/skia/include/core/SkRRect.h" @@ -45,14 +45,6 @@ namespace { -Tab* GetLeftTab(const Tab* tab) { - return tab->controller()->GetAdjacentTab(tab, base::i18n::IsRTL() ? 1 : -1); -} - -Tab* GetRightTab(const Tab* tab) { - return tab->controller()->GetAdjacentTab(tab, base::i18n::IsRTL() ? -1 : 1); -} - // Updates a target value, returning true if it changed. template <class T> bool UpdateValue(T* dest, const T& src) { @@ -290,17 +282,13 @@ const int right_separator_overlap = tab_style()->GetSeparatorSize().width() - left_separator_overlap; - // If there is a tab before this one, then expand into its overlap. - const Tab* const previous_tab = GetLeftTab(tab()); - if (expand_into_previous_separator && previous_tab) { + if (expand_into_previous_separator) { left -= (tab_style()->GetSeparatorMargins().right() + left_separator_overlap) * scale; } - // If there is a tab after this one, then expand into its overlap. - const Tab* const next_tab = GetRightTab(tab()); - if (expand_into_next_separator && next_tab) { + if (expand_into_next_separator) { right += (tab_style()->GetSeparatorMargins().left() + right_separator_overlap) * scale;
diff --git a/chrome/browser/ui/views/tabs/tab_unittest.cc b/chrome/browser/ui/views/tabs/tab_unittest.cc index bb8ca23a..461dc720 100644 --- a/chrome/browser/ui/views/tabs/tab_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_unittest.cc
@@ -14,8 +14,8 @@ #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_tick_clock.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_tab_data.h" -#include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_style.h" #include "chrome/browser/ui/tabs/tab_types.h" #include "chrome/browser/ui/tabs/tab_utils.h" @@ -387,12 +387,12 @@ } TEST_F(TabTest, LayoutAndVisibilityOfElements) { - static const std::optional<TabAlertState> kAlertStatesToTest[] = { + static const std::optional<tabs::TabAlert> kAlertStatesToTest[] = { std::nullopt, - TabAlertState::TAB_CAPTURING, - TabAlertState::AUDIO_PLAYING, - TabAlertState::AUDIO_MUTING, - TabAlertState::PIP_PLAYING, + tabs::TabAlert::TAB_CAPTURING, + tabs::TabAlert::AUDIO_PLAYING, + tabs::TabAlert::AUDIO_MUTING, + tabs::TabAlert::PIP_PLAYING, }; auto controller = std::make_unique<FakeTabSlotController>(); @@ -410,7 +410,7 @@ // results. for (bool is_pinned_tab : {false, true}) { for (bool is_active_tab : {false, true}) { - for (std::optional<TabAlertState> alert_state : kAlertStatesToTest) { + for (std::optional<tabs::TabAlert> alert_state : kAlertStatesToTest) { SCOPED_TRACE( ::testing::Message() << (is_active_tab ? "Active " : "Inactive ") @@ -632,7 +632,7 @@ views::View* icon = GetTabIcon(tab); int icon_x = icon->x(); TabRendererData data; - data.alert_state = {TabAlertState::AUDIO_PLAYING}; + data.alert_state = {tabs::TabAlert::AUDIO_PLAYING}; tab->SetData(data); EXPECT_EQ(icon_x, icon->x()); } @@ -681,7 +681,7 @@ Tab* tab = widget->SetContentsView(std::make_unique<Tab>(controller.get())); controller->set_active_tab(tab); TabRendererData data; - data.alert_state = {TabAlertState::AUDIO_PLAYING}; + data.alert_state = {tabs::TabAlert::AUDIO_PLAYING}; tab->SetData(data); tab->SetBounds(0, 0, 200, 50); @@ -779,7 +779,7 @@ EXPECT_FALSE(showing_close_button(media_tab)); TabRendererData start_media; - start_media.alert_state = {TabAlertState::AUDIO_PLAYING}; + start_media.alert_state = {tabs::TabAlert::AUDIO_PLAYING}; start_media.pinned = media_tab->data().pinned; media_tab->SetData(std::move(start_media)); @@ -820,7 +820,7 @@ EXPECT_EQ(base::Time(), get_camera_mic_indicator_start_time(media_tab)); TabRendererData start_media; - start_media.alert_state = {TabAlertState::MEDIA_RECORDING}; + start_media.alert_state = {tabs::TabAlert::MEDIA_RECORDING}; start_media.pinned = media_tab->data().pinned; media_tab->SetData(std::move(start_media)); @@ -851,7 +851,7 @@ EXPECT_EQ(base::Time(), get_camera_mic_indicator_start_time(media_tab)); TabRendererData start_media; - start_media.alert_state = {TabAlertState::MEDIA_RECORDING}; + start_media.alert_state = {tabs::TabAlert::MEDIA_RECORDING}; start_media.pinned = media_tab->data().pinned; media_tab->SetData(std::move(start_media));
diff --git a/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container_browsertest.cc b/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container_browsertest.cc index 451f932..990654a 100644 --- a/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container_browsertest.cc +++ b/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container_browsertest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ui/actions/chrome_action_id.h" #include "chrome/browser/ui/browser_window/public/browser_window_features.h" #include "chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/side_panel/side_panel_ui.h" #include "chrome/browser/ui/views/toolbar/pinned_action_toolbar_button.h" @@ -19,7 +20,6 @@ #include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_view.h" #include "chrome/browser/web_applications/test/os_integration_test_override_impl.h" #include "chrome/browser/web_applications/test/web_app_install_test_utils.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "components/prefs/pref_service.h"
diff --git a/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container_unittest.cc b/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container_unittest.cc index b8eed8a..4c32af79 100644 --- a/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container_unittest.cc +++ b/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container_unittest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model.h" #include "chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model_factory.h" #include "chrome/browser/ui/toolbar/toolbar_pref_names.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/test_with_browser_view.h" #include "chrome/browser/ui/views/toolbar/pinned_action_toolbar_button.h" @@ -23,7 +24,6 @@ #include "chrome/browser/ui/views/toolbar/pinned_toolbar_button_status_indicator.h" #include "chrome/browser/ui/views/toolbar/toolbar_button.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" -#include "chrome/common/chrome_features.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "components/keyed_service/core/keyed_service.h"
diff --git a/chrome/browser/ui/views/toolbar/toolbar_controller_interactive_uitest.cc b/chrome/browser/ui/views/toolbar/toolbar_controller_interactive_uitest.cc index 9b36dcd..980d752 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_controller_interactive_uitest.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/ui/browser_window/public/browser_window_features.h" #include "chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model.h" #include "chrome/browser/ui/toolbar_controller_util.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/extensions/extensions_toolbar_container.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h" @@ -26,7 +27,6 @@ #include "chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.h" #include "chrome/browser/ui/views/toolbar/toolbar_controller.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" -#include "chrome/common/chrome_features.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/ui/webui/connectors_internals/connectors_internals.mojom b/chrome/browser/ui/webui/connectors_internals/connectors_internals.mojom index 07c7777..9b3878d 100644 --- a/chrome/browser/ui/webui/connectors_internals/connectors_internals.mojom +++ b/chrome/browser/ui/webui/connectors_internals/connectors_internals.mojom
@@ -17,6 +17,7 @@ UNSPECIFIED = 0, HW = 1, OS = 2, + OS_SOFTWARE = 3, }; // Type of the signing key, equivalent to the algorithm used for its generation. @@ -64,6 +65,9 @@ // Result of an attempt to upload the key. May be empty if the // key has not yet been uploaded. KeyUploadStatus? key_upload_status; + + // Whether the key was correctly converted into an SSL key. + bool has_ssl_key; }; struct KeyInfo {
diff --git a/chrome/browser/ui/webui/connectors_internals/device_trust_utils.cc b/chrome/browser/ui/webui/connectors_internals/device_trust_utils.cc index 4f29233..1035eecf 100644 --- a/chrome/browser/ui/webui/connectors_internals/device_trust_utils.cc +++ b/chrome/browser/ui/webui/connectors_internals/device_trust_utils.cc
@@ -32,6 +32,7 @@ #include "components/enterprise/client_certificates/core/private_key.h" #include "components/enterprise/client_certificates/core/private_key_types.h" #include "net/cert/x509_certificate.h" +#include "net/ssl/ssl_private_key.h" #endif // BUILDFLAG(ENTERPRISE_CLIENT_CERTIFICATES) namespace enterprise_connectors::utils { @@ -116,6 +117,8 @@ return connectors_internals::mojom::KeyTrustLevel::HW; case client_certificates::PrivateKeySource::kSoftwareKey: return connectors_internals::mojom::KeyTrustLevel::OS; + case client_certificates::PrivateKeySource::kOsSoftwareKey: + return connectors_internals::mojom::KeyTrustLevel::OS_SOFTWARE; } } @@ -145,8 +148,8 @@ return connectors_internals::mojom::LoadedKeyInfo::New( ConvertPrivateKeySource(private_key->GetSource()), AlgorithmToType(private_key->GetAlgorithm()), - HashAndEncodeString(BufferToString(spki_bytes)), - std::move(upload_status)); + HashAndEncodeString(BufferToString(spki_bytes)), std::move(upload_status), + bool(private_key->GetSSLPrivateKey())); } connectors_internals::mojom::CertificateMetadataPtr ConvertCertificate( @@ -190,7 +193,8 @@ HashAndEncodeString(metadata->spki_bytes), connectors_internals::mojom::KeyUploadStatus:: NewSyncKeyResponseCode( - ToMojomValue(metadata->synchronization_response_code))), + ToMojomValue(metadata->synchronization_response_code)), + /*has_ssl_key=*/false), ConvertPermanentFailure(metadata->permanent_failure)); }
diff --git a/chrome/browser/ui/webui/settings/appearance_handler_browsertest.cc b/chrome/browser/ui/webui/settings/appearance_handler_browsertest.cc index 1fe8f376..a61ac10f 100644 --- a/chrome/browser/ui/webui/settings/appearance_handler_browsertest.cc +++ b/chrome/browser/ui/webui/settings/appearance_handler_browsertest.cc
@@ -10,8 +10,8 @@ #include "chrome/browser/ui/browser_window/public/browser_window_features.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/toolbar/pinned_toolbar/pinned_toolbar_actions_model.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/side_panel/side_panel_ui.h" -#include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h"
diff --git a/chrome/browser/ui/webui/settings/glic_handler_browsertest.cc b/chrome/browser/ui/webui/settings/glic_handler_browsertest.cc index ea64e670..344873a 100644 --- a/chrome/browser/ui/webui/settings/glic_handler_browsertest.cc +++ b/chrome/browser/ui/webui/settings/glic_handler_browsertest.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/background/glic/glic_launcher_configuration.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/glic/glic_pref_names.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/test_browser_window.h"
diff --git a/chrome/browser/ui/webui/settings/safety_hub_handler.cc b/chrome/browser/ui/webui/settings/safety_hub_handler.cc index b239180..6700ccc 100644 --- a/chrome/browser/ui/webui/settings/safety_hub_handler.cc +++ b/chrome/browser/ui/webui/settings/safety_hub_handler.cc
@@ -68,6 +68,8 @@ namespace { +const char kRevocationTypeKey[] = "revocation_type"; + // Get values from |UnusedSitePermission| object in // safety_hub_browser_proxy.ts. PermissionsData GetUnusedSitePermissionsFromDict( @@ -115,6 +117,9 @@ content_settings::ContentSettingConstraints(expiration - lifetime); permissions_data.constraints.set_lifetime(lifetime); + permissions_data.revocation_type = static_cast<PermissionsRevocationType>( + unused_site_permissions.FindInt(kRevocationTypeKey).value_or(0)); + return permissions_data; } @@ -239,42 +244,13 @@ RevokedPermissionsServiceFactory::GetForProfile(profile_); CHECK(service); + std::vector<PermissionsData> permissions_data_list; for (const auto& unused_site_permissions_js : unused_site_permissions_list) { CHECK(unused_site_permissions_js.is_dict()); - PermissionsData permissions_data = - GetUnusedSitePermissionsFromDict(unused_site_permissions_js.GetDict()); - if (base::FeatureList::IsEnabled( - safe_browsing::kSafetyHubAbusiveNotificationRevocation)) { - HostContentSettingsMap* map = - HostContentSettingsMapFactory::GetForProfile(profile_); - // This pattern is origin-scoped, so this conversion is safe. - GURL permission_url = - permissions_data.primary_pattern.ToRepresentativeUrl(); - DCHECK(permission_url.is_valid()); - // If the permission_types includes `NOTIFICATIONS`, then the revocation - // is for a site that should have a - // `REVOKED_ABUSIVE_NOTIFICATION_PERMISSIONS` setting. - if (permissions_data.permission_types.contains( - ContentSettingsType::NOTIFICATIONS)) { - safety_hub_util::SetRevokedAbusiveNotificationPermission( - map, permission_url, /*is_ignored=*/false, - permissions_data.constraints); - // Remove `NOTIFICATIONS` from permission type list for handling unused - // permission revocation below. - permissions_data.permission_types.erase( - ContentSettingsType::NOTIFICATIONS); - } - - // If the permission_types include any permission type that is not - // `NOTIFICATIONS`, then the revocation is for an unused site that should - // have a `REVOKED_UNUSED_SITE_PERMISSIONS` setting. - if (!permissions_data.permission_types.empty()) { - service->StorePermissionInRevokedPermissionSetting(permissions_data); - } - } else { - service->StorePermissionInRevokedPermissionSetting(permissions_data); - } + permissions_data_list.push_back( + GetUnusedSitePermissionsFromDict(unused_site_permissions_js.GetDict())); } + service->RestoreDeletedRevokedPermissionsList(permissions_data_list); SendUnusedSitePermissionsReviewList(); } @@ -325,6 +301,9 @@ safety_hub::kSafetyHubChooserPermissionsData, base::Value(permissions_data.chooser_permissions_data.Clone())); + revoked_permission_value.Set( + kRevocationTypeKey, static_cast<int>(permissions_data.revocation_type)); + result.Append(std::move(revoked_permission_value)); }
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc index bbf9fc4..b5e6efa 100644 --- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc +++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
@@ -39,6 +39,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/browser_window/public/browser_window_features.h" #include "chrome/browser/ui/color/chrome_color_id.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/organization/tab_declutter_controller.h" #include "chrome/browser/ui/tabs/organization/tab_organization_request.h" #include "chrome/browser/ui/tabs/organization/tab_organization_service.h" @@ -1440,18 +1441,18 @@ ? custom_last_active_text : GetLastActiveElapsedText(last_active_time_ticks); - std::vector<TabAlertState> alert_states = + std::vector<tabs::TabAlert> alert_states = GetTabAlertStatesForContents(contents); // Currently, we only report media alert states. std::ranges::copy_if(alert_states.begin(), alert_states.end(), std::back_inserter(tab_data->alert_states), - [](TabAlertState alert) { - return alert == TabAlertState::MEDIA_RECORDING || - alert == TabAlertState::AUDIO_RECORDING || - alert == TabAlertState::VIDEO_RECORDING || - alert == TabAlertState::AUDIO_PLAYING || - alert == TabAlertState::AUDIO_MUTING || - alert == TabAlertState::GLIC_ACCESSING; + [](tabs::TabAlert alert) { + return alert == tabs::TabAlert::MEDIA_RECORDING || + alert == tabs::TabAlert::AUDIO_RECORDING || + alert == tabs::TabAlert::VIDEO_RECORDING || + alert == tabs::TabAlert::AUDIO_PLAYING || + alert == tabs::TabAlert::AUDIO_MUTING || + alert == tabs::TabAlert::GLIC_ACCESSING; }); return tab_data;
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_page_handler_unittest.cc b/chrome/browser/ui/webui/tab_search/tab_search_page_handler_unittest.cc index 2c8b260..2f37aae 100644 --- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler_unittest.cc +++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler_unittest.cc
@@ -22,8 +22,8 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/browser_window/test/mock_browser_window_interface.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/tabs/organization/tab_declutter_controller.h" -#include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_utils.h" #include "chrome/browser/ui/tabs/test_tab_strip_model_delegate.h" #include "chrome/browser/ui/tabs/test_util.h" @@ -445,7 +445,7 @@ [&](tab_search::mojom::ProfileDataPtr profile_tabs) { auto* window1 = profile_tabs->windows[0].get(); auto* tab1 = window1->tabs[0].get(); - EXPECT_EQ(TabAlertState::AUDIO_PLAYING, tab1->alert_states[0]); + EXPECT_EQ(tabs::TabAlert::AUDIO_PLAYING, tab1->alert_states[0]); }); handler()->GetProfileData(std::move(callback));
diff --git a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.cc b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.cc index a9f1c158..3298a7a 100644 --- a/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.cc +++ b/chrome/browser/ui/webui/tab_strip/tab_strip_ui_util.cc
@@ -82,7 +82,7 @@ return; } - std::unique_ptr<DetachedTabGroup> detached_group = + std::unique_ptr<DetachedTabCollection> detached_group = source_browser->tab_strip_model()->DetachTabGroupForInsertion(group_id); target_browser->tab_strip_model()->InsertDetachedTabGroupAt( std::move(detached_group), to_index);
diff --git a/chrome/browser/ui/webui/tabs/BUILD.gn b/chrome/browser/ui/webui/tabs/BUILD.gn index 9c92e28..8d3eb41 100644 --- a/chrome/browser/ui/webui/tabs/BUILD.gn +++ b/chrome/browser/ui/webui/tabs/BUILD.gn
@@ -14,14 +14,14 @@ types = [ { mojom = "tabs.mojom.TabAlertState" - cpp = "::TabAlertState" + cpp = "::tabs::TabAlert" }, ] - traits_headers = [ "tabs_mojom_traits.h" ] - traits_public_deps = [ - "//base", - "//chrome/browser/ui/tabs:tab_enums", + traits_headers = [ + "tabs_mojom_traits.h", + "//chrome/browser/ui/tabs/alert/tab_alert.h", ] + traits_public_deps = [ "//base" ] }, ] }
diff --git a/chrome/browser/ui/webui/tabs/tabs_mojom_traits.h b/chrome/browser/ui/webui/tabs/tabs_mojom_traits.h index c5e62ab9..8984bcc 100644 --- a/chrome/browser/ui/webui/tabs/tabs_mojom_traits.h +++ b/chrome/browser/ui/webui/tabs/tabs_mojom_traits.h
@@ -6,78 +6,78 @@ #define CHROME_BROWSER_UI_WEBUI_TABS_TABS_MOJOM_TRAITS_H_ #include "base/containers/fixed_flat_map.h" -#include "chrome/browser/ui/tabs/tab_enums.h" +#include "chrome/browser/ui/tabs/alert/tab_alert.h" #include "chrome/browser/ui/webui/tabs/tabs.mojom.h" namespace mojo { template <> -struct EnumTraits<tabs::mojom::TabAlertState, TabAlertState> { - static tabs::mojom::TabAlertState ToMojom(TabAlertState input) { +struct EnumTraits<tabs::mojom::TabAlertState, tabs::TabAlert> { + static tabs::mojom::TabAlertState ToMojom(tabs::TabAlert input) { static constexpr auto alert_state_map = - base::MakeFixedFlatMap<TabAlertState, tabs::mojom::TabAlertState>( - {{TabAlertState::MEDIA_RECORDING, + base::MakeFixedFlatMap<tabs::TabAlert, tabs::mojom::TabAlertState>( + {{tabs::TabAlert::MEDIA_RECORDING, tabs::mojom::TabAlertState::kMediaRecording}, - {TabAlertState::TAB_CAPTURING, + {tabs::TabAlert::TAB_CAPTURING, tabs::mojom::TabAlertState::kTabCapturing}, - {TabAlertState::AUDIO_PLAYING, + {tabs::TabAlert::AUDIO_PLAYING, tabs::mojom::TabAlertState::kAudioPlaying}, - {TabAlertState::AUDIO_MUTING, + {tabs::TabAlert::AUDIO_MUTING, tabs::mojom::TabAlertState::kAudioMuting}, - {TabAlertState::BLUETOOTH_CONNECTED, + {tabs::TabAlert::BLUETOOTH_CONNECTED, tabs::mojom::TabAlertState::kBluetoothConnected}, - {TabAlertState::BLUETOOTH_SCAN_ACTIVE, + {tabs::TabAlert::BLUETOOTH_SCAN_ACTIVE, tabs::mojom::TabAlertState::kBluetoothConnected}, - {TabAlertState::USB_CONNECTED, + {tabs::TabAlert::USB_CONNECTED, tabs::mojom::TabAlertState::kUsbConnected}, - {TabAlertState::HID_CONNECTED, + {tabs::TabAlert::HID_CONNECTED, tabs::mojom::TabAlertState::kHidConnected}, - {TabAlertState::SERIAL_CONNECTED, + {tabs::TabAlert::SERIAL_CONNECTED, tabs::mojom::TabAlertState::kSerialConnected}, - {TabAlertState::PIP_PLAYING, + {tabs::TabAlert::PIP_PLAYING, tabs::mojom::TabAlertState::kPipPlaying}, - {TabAlertState::DESKTOP_CAPTURING, + {tabs::TabAlert::DESKTOP_CAPTURING, tabs::mojom::TabAlertState::kDesktopCapturing}, - {TabAlertState::VR_PRESENTING_IN_HEADSET, + {tabs::TabAlert::VR_PRESENTING_IN_HEADSET, tabs::mojom::TabAlertState::kVrPresentingInHeadset}, - {TabAlertState::AUDIO_RECORDING, + {tabs::TabAlert::AUDIO_RECORDING, tabs::mojom::TabAlertState::kAudioRecording}, - {TabAlertState::VIDEO_RECORDING, + {tabs::TabAlert::VIDEO_RECORDING, tabs::mojom::TabAlertState::kVideoRecording}, - {TabAlertState::GLIC_ACCESSING, + {tabs::TabAlert::GLIC_ACCESSING, tabs::mojom::TabAlertState::kGlicAccessing}}); return alert_state_map.at(input); } - static bool FromMojom(tabs::mojom::TabAlertState input, TabAlertState* out) { + static bool FromMojom(tabs::mojom::TabAlertState input, tabs::TabAlert* out) { static constexpr auto alert_state_map = - base::MakeFixedFlatMap<tabs::mojom::TabAlertState, TabAlertState>( + base::MakeFixedFlatMap<tabs::mojom::TabAlertState, tabs::TabAlert>( {{tabs::mojom::TabAlertState::kMediaRecording, - TabAlertState::MEDIA_RECORDING}, + tabs::TabAlert::MEDIA_RECORDING}, {tabs::mojom::TabAlertState::kTabCapturing, - TabAlertState::TAB_CAPTURING}, + tabs::TabAlert::TAB_CAPTURING}, {tabs::mojom::TabAlertState::kAudioPlaying, - TabAlertState::AUDIO_PLAYING}, + tabs::TabAlert::AUDIO_PLAYING}, {tabs::mojom::TabAlertState::kAudioMuting, - TabAlertState::AUDIO_MUTING}, + tabs::TabAlert::AUDIO_MUTING}, {tabs::mojom::TabAlertState::kBluetoothConnected, - TabAlertState::BLUETOOTH_CONNECTED}, + tabs::TabAlert::BLUETOOTH_CONNECTED}, {tabs::mojom::TabAlertState::kUsbConnected, - TabAlertState::USB_CONNECTED}, + tabs::TabAlert::USB_CONNECTED}, {tabs::mojom::TabAlertState::kHidConnected, - TabAlertState::HID_CONNECTED}, + tabs::TabAlert::HID_CONNECTED}, {tabs::mojom::TabAlertState::kSerialConnected, - TabAlertState::SERIAL_CONNECTED}, + tabs::TabAlert::SERIAL_CONNECTED}, {tabs::mojom::TabAlertState::kPipPlaying, - TabAlertState::PIP_PLAYING}, + tabs::TabAlert::PIP_PLAYING}, {tabs::mojom::TabAlertState::kDesktopCapturing, - TabAlertState::DESKTOP_CAPTURING}, + tabs::TabAlert::DESKTOP_CAPTURING}, {tabs::mojom::TabAlertState::kVrPresentingInHeadset, - TabAlertState::VR_PRESENTING_IN_HEADSET}, + tabs::TabAlert::VR_PRESENTING_IN_HEADSET}, {tabs::mojom::TabAlertState::kAudioRecording, - TabAlertState::AUDIO_RECORDING}, + tabs::TabAlert::AUDIO_RECORDING}, {tabs::mojom::TabAlertState::kVideoRecording, - TabAlertState::VIDEO_RECORDING}}); + tabs::TabAlert::VIDEO_RECORDING}}); *out = alert_state_map.at(input); return true; }
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 57e6c676..142f1c1f 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -86,7 +86,7 @@ #if BUILDFLAG(IS_MAC) BASE_FEATURE(kDiyAppIconsMaskedOnMacUpdate, "DiyAppIconsMaskedOnMacUpdate", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); #endif // static
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 05c9d8d4..e4b2544 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1747249678-e43702381cd568814955b66dcd87a7e0826fdb43-2b23ba12fc0bff23d878248a3cd6ed11f376680d.profdata +chrome-android64-main-1747267889-3b0200515b525bd4e5909a6ab320d601f1a9ee17-5469682bc6b1ea94267ce7c44a4cac37bbffd1d7.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 6a1d25d..b657069 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1747252715-bb00393b72fe86fcfdefb11ecaf54c3b04294b53-d46c76c1dc5bcf8388ea12080d1eb072e90f6943.profdata +chrome-mac-arm-main-1747274301-dfbe16ba589ec1e1ce9a76907777456126ecac29-ae5ec58f91555ac5fb0e12a58b6f7ef82a3a88d5.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index e32ea8d..fda23b946 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1747245510-6fcfb0d502d85532aa200db62276832dbae43a35-db287c7cb3630d08c8a452237cf6eece15867f61.profdata +chrome-mac-main-1747266928-68763f645594aa6109e1defd80fc6b95c7859f29-4ba649be861fbbcceaa3a1dd000c6785c3b595ef.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index 76f4bdc..5d3d150b 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1747245510-6b1ef9862ff7ebff7797a61e689663c752e957ce-db287c7cb3630d08c8a452237cf6eece15867f61.profdata +chrome-win-arm64-main-1747266928-497eea47c75771870ac54f916dbf1154a8415ca4-4ba649be861fbbcceaa3a1dd000c6785c3b595ef.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index b9b48cb..06f8ac8f 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1747234746-d4ab879dc17a0e6bb741531c30f7cb9da0c43c01-54671829bfbb662a4d8a7c1b4c9f3826e618fb42.profdata +chrome-win32-main-1747245510-9066dd76f445ed6dcaf9fd83deb5ac82f8efa48f-db287c7cb3630d08c8a452237cf6eece15867f61.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 02fd60b..e9a14605 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1747213155-31f4a89a5bfae9bc892ab93991c3b615a2b67384-57643b439871e4cf9f63b22a9cde066ef3fa9b7f.profdata +chrome-win64-main-1747234746-beca5e55a25c645ffaee0dfd1b05f6860f5301ec-54671829bfbb662a4d8a7c1b4c9f3826e618fb42.profdata
diff --git a/chrome/common/actor.mojom b/chrome/common/actor.mojom index d57a77f..f3b7c2a 100644 --- a/chrome/common/actor.mojom +++ b/chrome/common/actor.mojom
@@ -207,6 +207,17 @@ // Navigations were created but asynchronously cancelled before being started. kHistoryCancelledBeforeStart = 801, + // Back traversal was requested when at beginning of session history. + kHistoryNoBackEntries = 802, + + // Forward traversal was requested when at end of session history. + kHistoryNoForwardEntries = 803, + + // History navigation was aborted before commit. + kHistoryFailedBeforeCommit = 804, + + // History navigation committed to an error page. + kHistoryErrorPage = 805, }; // All information required to invoke a tool in the renderer.
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 6c3b7722..54693ee 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -538,39 +538,6 @@ base::FEATURE_DISABLED_BY_DEFAULT); #endif // BUILDFLAG(ENABLE_GLIC) -BASE_FEATURE(kTabstripComboButton, - "TabstripComboButton", - base::FEATURE_DISABLED_BY_DEFAULT); - -bool IsTabSearchMoving() { - return base::FeatureList::IsEnabled(features::kTabstripComboButton); -} - -const base::FeatureParam<bool> kTabstripComboButtonHasBackground{ - &kTabstripComboButton, "has_background", false}; - -const base::FeatureParam<bool> kTabstripComboButtonHasReverseButtonOrder{ - &kTabstripComboButton, "reverse_button_order", false}; - -const base::FeatureParam<bool> kTabSearchToolbarButton{ - &kTabstripComboButton, "tab_search_toolbar_button", false}; - -bool HasTabstripComboButtonWithBackground() { - return IsTabSearchMoving() && - features::kTabstripComboButtonHasBackground.Get() && - !features::kTabSearchToolbarButton.Get(); -} - -bool HasTabstripComboButtonWithReverseButtonOrder() { - return IsTabSearchMoving() && - features::kTabstripComboButtonHasReverseButtonOrder.Get() && - !features::kTabSearchToolbarButton.Get(); -} - -bool HasTabSearchToolbarButton() { - return IsTabSearchMoving() && features::kTabSearchToolbarButton.Get(); -} - // Force Privacy Guide to be available even if it would be unavailable // otherwise. This is meant for development and test purposes only. BASE_FEATURE(kPrivacyGuideForceAvailable,
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index a178e48..2fdf59ff 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -311,18 +311,6 @@ BASE_DECLARE_FEATURE(kGlicUnloadOnClose); #endif // BUILDFLAG(ENABLE_GLIC) -COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kTabstripComboButton); -COMPONENT_EXPORT(CHROME_FEATURES) bool IsTabSearchMoving(); -COMPONENT_EXPORT(CHROME_FEATURES) -extern const base::FeatureParam<bool> kTabstripComboButtonHasBackground; -COMPONENT_EXPORT(CHROME_FEATURES) bool HasTabstripComboButtonWithBackground(); -COMPONENT_EXPORT(CHROME_FEATURES) -extern const base::FeatureParam<bool> kTabstripComboButtonHasReverseButtonOrder; -COMPONENT_EXPORT(CHROME_FEATURES) -bool HasTabstripComboButtonWithReverseButtonOrder(); -extern const base::FeatureParam<bool> kTabSearchToolbarButton; -COMPONENT_EXPORT(CHROME_FEATURES) bool HasTabSearchToolbarButton(); - COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kPrivacyGuideForceAvailable);
diff --git a/chrome/common/extensions/extension_unittest.cc b/chrome/common/extensions/extension_unittest.cc index 43fdd0d..71c911c 100644 --- a/chrome/common/extensions/extension_unittest.cc +++ b/chrome/common/extensions/extension_unittest.cc
@@ -176,12 +176,11 @@ EXPECT_TRUE(extension.get()); EXPECT_EQ(extension->url().spec() + "bar/baz.js", - Extension::GetResourceURL(extension->url(), "bar/baz.js").spec()); + extension->GetResourceURL("bar/baz.js").spec()); EXPECT_EQ(extension->url().spec() + "baz.js", - Extension::GetResourceURL(extension->url(), - "bar/../baz.js").spec()); + extension->GetResourceURL("bar/../baz.js").spec()); EXPECT_EQ(extension->url().spec() + "baz.js", - Extension::GetResourceURL(extension->url(), "../baz.js").spec()); + extension->GetResourceURL("../baz.js").spec()); // Test that absolute-looking paths ("/"-prefixed) are pasted correctly. EXPECT_EQ(extension->url().spec() + "test.html",
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 4712c66..2ba6f037 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2012,7 +2012,10 @@ "${target_gen_dir}/android_browsertests_manifest/AndroidManifest.xml" android_manifest_dep = ":android_browsertests_manifest" - deps = android_sync_integration_tests_deps + [ "//chrome/browser/sync" ] + deps = android_sync_integration_tests_deps + [ + "//chrome/browser/sync", + "//chrome/browser/ui:ui_features", + ] sources = sync_integration_tests_sources data = android_sync_integration_tests_data }
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 0db4f7e..71fefd6 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -323,6 +323,7 @@ if (!is_android) { deps += [ + "//chrome/browser/ui:ui_features", "//components/history_clusters/core", "//components/password_manager/content/common", "//components/power_bookmarks/core:features",
diff --git a/chrome/test/data/webui/glic/glic_browsertest.cc b/chrome/test/data/webui/glic/glic_browsertest.cc index d0678f2b..1f3f9d2 100644 --- a/chrome/test/data/webui/glic/glic_browsertest.cc +++ b/chrome/test/data/webui/glic/glic_browsertest.cc
@@ -4,6 +4,7 @@ #include "base/test/scoped_feature_list.h" #include "build/build_config.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/web_ui_mocha_browser_test.h"
diff --git a/chrome/test/data/webui/settings/settings_browsertest.cc b/chrome/test/data/webui/settings/settings_browsertest.cc index 8b0d373..e6714ee6 100644 --- a/chrome/test/data/webui/settings/settings_browsertest.cc +++ b/chrome/test/data/webui/settings/settings_browsertest.cc
@@ -7,6 +7,7 @@ #include "build/build_config.h" #include "build/config/coverage/buildflags.h" #include "chrome/browser/preloading/preloading_features.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/web_ui_mocha_browser_test.h"
diff --git a/chrome/test/data/webui/settings/settings_focus_test.cc b/chrome/test/data/webui/settings/settings_focus_test.cc index 217fa09e..90cbc09 100644 --- a/chrome/test/data/webui/settings/settings_focus_test.cc +++ b/chrome/test/data/webui/settings/settings_focus_test.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/web_ui_mocha_browser_test.h"
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights_test.ts b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights_test.ts index c57aa77..9758912 100644 --- a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights_test.ts +++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights_test.ts
@@ -4,7 +4,7 @@ import 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js'; import type {AppElement} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js'; -import {BrowserProxy, currentReadHighlightClass, previousReadHighlightClass, ReadAloudHighlighter} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js'; +import {BrowserProxy, currentReadHighlightClass, previousReadHighlightClass, ReadAloudHighlighter, SpeechController} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js'; import {assertEquals} from 'chrome-untrusted://webui-test/chai_assert.js'; import {microtasksFinished} from 'chrome-untrusted://webui-test/test_util.js'; @@ -43,8 +43,10 @@ BrowserProxy.setInstance(new TestColorUpdaterBrowserProxy()); const readingMode = new FakeReadingMode(); chrome.readingMode = readingMode as unknown as typeof chrome.readingMode; + chrome.readingMode.isReadAloudEnabled = true; highlighter = new ReadAloudHighlighter(); ReadAloudHighlighter.setInstance(highlighter); + SpeechController.setInstance(new SpeechController()); // Don't use await createApp() when using a FakeTree, as it seems to cause // flakiness.
diff --git a/chrome/test/data/webui/webview/webui_webview_browsertest.cc b/chrome/test/data/webui/webview/webui_webview_browsertest.cc index 909690d..595819c 100644 --- a/chrome/test/data/webui/webview/webui_webview_browsertest.cc +++ b/chrome/test/data/webui/webview/webui_webview_browsertest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/signin/signin_promo.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/ui_features.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index f49ddf1..9ea32b7 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -5148,6 +5148,24 @@ ASSERT_NO_FATAL_FAILURE(Uninstall()); } +TEST_F(IntegrationTest, OfflineOverInstall) { + ScopedServer test_server(test_commands_); + ExpectInstallEvent(test_server, kUpdaterAppId); + ASSERT_NO_FATAL_FAILURE(Install({kEnableCecaExperimentSwitch})); + ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); + + ExpectInstallEvent(test_server, "{CDABE316-39CD-43BA-8440-6D1E0547AEE6}"); + ASSERT_NO_FATAL_FAILURE(RunOfflineInstall(/*is_legacy_install=*/false, + /*is_silent_install=*/false)); + + ExpectInstallEvent(test_server, "{CDABE316-39CD-43BA-8440-6D1E0547AEE6}"); + ASSERT_NO_FATAL_FAILURE(RunOfflineInstall(/*is_legacy_install=*/false, + /*is_silent_install=*/false)); + + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); + ASSERT_NO_FATAL_FAILURE(Uninstall()); +} + TEST_F(IntegrationTest, OfflineInstallOsNotSupported) { ScopedServer test_server(test_commands_); ExpectInstallEvent(test_server, kUpdaterAppId);
diff --git a/chromeos/ash/components/boca/on_task/on_task_session_manager.cc b/chromeos/ash/components/boca/on_task/on_task_session_manager.cc index 2aa33fa..1499ec5 100644 --- a/chromeos/ash/components/boca/on_task/on_task_session_manager.cc +++ b/chromeos/ash/components/boca/on_task/on_task_session_manager.cc
@@ -300,6 +300,15 @@ void OnTaskSessionManager::LockOrUnlockWindow(bool lock_window) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (lock_in_progress_ && lock_window) { + // Enter pause mode and remove countdown notification if pause mode is + // triggered while in locked mode countdown. + if (enter_pause_mode_) { + notifications_manager_->StopProcessingNotification( + kOnTaskEnterLockedModeNotificationId); + notifications_manager_->ClearNotification( + kOnTaskEnterLockedModeNotificationId); + EnterLockedMode(); + } return; } lock_in_progress_ = lock_window;
diff --git a/chromeos/ui/frame/BUILD.gn b/chromeos/ui/frame/BUILD.gn index 492345d..e40ba2e6 100644 --- a/chromeos/ui/frame/BUILD.gn +++ b/chromeos/ui/frame/BUILD.gn
@@ -26,8 +26,6 @@ "desks/move_to_desks_menu_delegate.h", "desks/move_to_desks_menu_model.cc", "desks/move_to_desks_menu_model.h", - "frame_color_metrics_helper.cc", - "frame_color_metrics_helper.h", "frame_header.cc", "frame_header.h", "frame_utils.cc",
diff --git a/chromeos/ui/frame/default_frame_header.cc b/chromeos/ui/frame/default_frame_header.cc index 08d2f6e..2e784484 100644 --- a/chromeos/ui/frame/default_frame_header.cc +++ b/chromeos/ui/frame/default_frame_header.cc
@@ -72,7 +72,6 @@ : FrameHeader(target_widget, header_view) { DCHECK(caption_button_container); SetCaptionButtonContainer(caption_button_container); - InitializeFrameColorMetricsHelper(); } DefaultFrameHeader::~DefaultFrameHeader() = default; @@ -111,7 +110,6 @@ if (updated) { StartTransitionAnimation(kDefaultFrameColorChangeAnimationDuration); - frame_color_metrics_helper_->UpdateFrameColorChangesCount(); } if (ShouldApplyDynamicColor(GetTargetWindow())) { @@ -184,11 +182,4 @@ return mode() == MODE_ACTIVE ? active_frame_color_ : inactive_frame_color_; } -void DefaultFrameHeader::InitializeFrameColorMetricsHelper() { - aura::Window* window = GetTargetWindow(); - CHECK(window); - frame_color_metrics_helper_ = std::make_unique<FrameColorMetricsHelper>( - window->GetProperty(chromeos::kAppTypeKey)); -} - } // namespace chromeos
diff --git a/chromeos/ui/frame/default_frame_header.h b/chromeos/ui/frame/default_frame_header.h index 8f89c4bb6..10f5ba6 100644 --- a/chromeos/ui/frame/default_frame_header.h +++ b/chromeos/ui/frame/default_frame_header.h
@@ -5,13 +5,10 @@ #ifndef CHROMEOS_UI_FRAME_DEFAULT_FRAME_HEADER_H_ #define CHROMEOS_UI_FRAME_DEFAULT_FRAME_HEADER_H_ -#include <memory> - #include "base/compiler_specific.h" // override #include "base/component_export.h" #include "base/gtest_prod_util.h" #include "chromeos/ui/base/chromeos_ui_constants.h" -#include "chromeos/ui/frame/frame_color_metrics_helper.h" #include "chromeos/ui/frame/frame_header.h" namespace ash { @@ -58,17 +55,10 @@ // Returns the window of the target widget. aura::Window* GetTargetWindow(); - // This function should be only called once, i.e., one instance of - // default_frame_header should own only one `frame_color_metrics_helper_` - // throughout its lifetime. - void InitializeFrameColorMetricsHelper(); - SkColor active_frame_color_ = chromeos::kDefaultFrameColor; SkColor inactive_frame_color_ = chromeos::kDefaultFrameColor; int width_in_pixels_ = -1; - - std::unique_ptr<FrameColorMetricsHelper> frame_color_metrics_helper_; }; } // namespace chromeos
diff --git a/chromeos/ui/frame/frame_color_metrics_helper.cc b/chromeos/ui/frame/frame_color_metrics_helper.cc deleted file mode 100644 index 6e18f70..0000000 --- a/chromeos/ui/frame/frame_color_metrics_helper.cc +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromeos/ui/frame/frame_color_metrics_helper.h" - -#include "base/check.h" -#include "base/functional/bind.h" -#include "base/functional/callback_forward.h" -#include "base/metrics/histogram_functions.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/strcat.h" -#include "base/time/time.h" -#include "chromeos/ui/base/app_types.h" - -namespace { - -constexpr char kArcHistogramName[] = "ArcApp"; -constexpr char kBrowserHistogramName[] = "Browser"; -constexpr char kChromeAppHistogramName[] = "ChromeApp"; -constexpr char kSystemAppHistogramName[] = "SystemApp"; -constexpr char kCrostiniAppHistogramName[] = "CrostiniApp"; - -// The tracing duration for frame color changes. -constexpr base::TimeDelta kFrameColorTracingTime = base::Seconds(3); - -} // namespace - -namespace chromeos { - -FrameColorMetricsHelper::FrameColorMetricsHelper(chromeos::AppType app_type) - : app_type_(app_type) { - StartTracing(); -} - -FrameColorMetricsHelper::~FrameColorMetricsHelper() = default; - -void FrameColorMetricsHelper::UpdateFrameColorChangesCount() { - frame_color_change_count_++; -} - -// static -std::string FrameColorMetricsHelper::GetFrameColorChangeHistogramName( - chromeos::AppType app_type) { - std::string app_type_str_; - switch (app_type) { - case chromeos::AppType::ARC_APP: - app_type_str_ = kArcHistogramName; - break; - case chromeos::AppType::BROWSER: - app_type_str_ = kBrowserHistogramName; - break; - case chromeos::AppType::CHROME_APP: - app_type_str_ = kChromeAppHistogramName; - break; - case chromeos::AppType::SYSTEM_APP: - app_type_str_ = kSystemAppHistogramName; - break; - case chromeos::AppType::CROSTINI_APP: - app_type_str_ = kCrostiniAppHistogramName; - break; - default: - app_type_str_ = "Others"; - } - return base::StrCat({"Ash.Frame.ColorChangeCount.", app_type_str_}); -} - -void FrameColorMetricsHelper::StartTracing() { - CHECK(!frame_start_timer_.IsRunning()); - frame_start_timer_.Start( - FROM_HERE, kFrameColorTracingTime, - base::BindOnce(&FrameColorMetricsHelper::FinalizeFrameColorTracing, - weak_ptr_factory_.GetWeakPtr())); -} - -void FrameColorMetricsHelper::FinalizeFrameColorTracing() { - frame_start_timer_.Stop(); - RecordFrameColorChangeCount(); -} - -void FrameColorMetricsHelper::RecordFrameColorChangeCount() { - const auto histogram_name = GetFrameColorChangeHistogramName(app_type_); - base::UmaHistogramCounts100(histogram_name, frame_color_change_count_); -} - -} // namespace chromeos
diff --git a/chromeos/ui/frame/frame_color_metrics_helper.h b/chromeos/ui/frame/frame_color_metrics_helper.h deleted file mode 100644 index da31804..0000000 --- a/chromeos/ui/frame/frame_color_metrics_helper.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROMEOS_UI_FRAME_FRAME_COLOR_METRICS_HELPER_H_ -#define CHROMEOS_UI_FRAME_FRAME_COLOR_METRICS_HELPER_H_ - -#include <string> - -#include "base/timer/timer.h" -#include "chromeos/ui/base/app_types.h" - -namespace chromeos { - -class FrameColorMetricsHelper { - public: - explicit FrameColorMetricsHelper(chromeos::AppType app_type); - FrameColorMetricsHelper(const FrameColorMetricsHelper& other) = delete; - FrameColorMetricsHelper& operator=(const FrameColorMetricsHelper&) = delete; - ~FrameColorMetricsHelper(); - - // When the frame color is changed, the count is incremented. - void UpdateFrameColorChangesCount(); - - static std::string GetFrameColorChangeHistogramName( - chromeos::AppType app_type); - - private: - // Start the timer for counting the frame color changes. - void StartTracing(); - - // When the timer expires, stop counting the frame color changes, and record - // the result in UMA. - void FinalizeFrameColorTracing(); - - void RecordFrameColorChangeCount(); - - // Timer for frame color changes counting. - base::OneShotTimer frame_start_timer_; - - const chromeos::AppType app_type_; - - uint32_t frame_color_change_count_ = 0; - - base::WeakPtrFactory<FrameColorMetricsHelper> weak_ptr_factory_{this}; -}; - -} // namespace chromeos - -#endif // CHROMEOS_UI_FRAME_FRAME_COLOR_METRICS_HELPER_H_
diff --git a/clank b/clank index 2135957..458624d 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 2135957a97f443f1db1b70e4379f0d808684e977 +Subproject commit 458624d042c10f66119db1ede7220e141e4eda26
diff --git a/components/affiliations/core/browser/affiliation_utils.cc b/components/affiliations/core/browser/affiliation_utils.cc index efeffcf5..08d192b2 100644 --- a/components/affiliations/core/browser/affiliation_utils.cc +++ b/components/affiliations/core/browser/affiliation_utils.cc
@@ -142,7 +142,8 @@ url::Component unused; bool success = url::CanonicalizeScheme( - input_uri.c_str(), input_parsed.scheme, &canonical_output, &unused); + input_parsed.scheme.as_string_view_on(input_uri.c_str()), + &canonical_output, &unused); canonical_output.push_back('/'); canonical_output.push_back('/');
diff --git a/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc b/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc index a5a8be0..243ccf6 100644 --- a/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc +++ b/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc
@@ -996,12 +996,18 @@ bool PaymentsDataManager::IsCardEligibleForBenefits( const CreditCard& card) const { - return (card.issuer_id() == kAmexCardIssuerId && + return (card.benefit_source() == kAmexCardBenefitSource && base::FeatureList::IsEnabled( features::kAutofillEnableCardBenefitsForAmericanExpress)) || - (card.issuer_id() == kBmoCardIssuerId && + (card.benefit_source() == kBmoCardBenefitSource && base::FeatureList::IsEnabled( - features::kAutofillEnableCardBenefitsForBmo)); + features::kAutofillEnableCardBenefitsForBmo)) || + (card.benefit_source() == kCurinosCardBenefitSource && + GetFlatRateBenefitByInstrumentId( + CreditCardBenefitBase::LinkedCardInstrumentId( + card.instrument_id())) && + base::FeatureList::IsEnabled( + features::kAutofillEnableFlatRateCardBenefitsFromCurinos)); } bool PaymentsDataManager::IsCardBenefitsFeatureEnabled() {
diff --git a/components/autofill/core/browser/data_model/payments/credit_card.cc b/components/autofill/core/browser/data_model/payments/credit_card.cc index b364aa58..e9c174fe 100644 --- a/components/autofill/core/browser/data_model/payments/credit_card.cc +++ b/components/autofill/core/browser/data_model/payments/credit_card.cc
@@ -37,7 +37,6 @@ #include "components/autofill/core/common/autofill_clock.h" #include "components/autofill/core/common/autofill_constants.h" #include "components/autofill/core/common/autofill_features.h" -#include "components/autofill/core/common/autofill_payments_features.h" #include "components/autofill/core/common/autofill_regexes.h" #include "components/autofill/core/common/credit_card_network_identifiers.h" #include "components/autofill/core/common/credit_card_number_validation.h"
diff --git a/components/autofill/core/browser/data_model/payments/credit_card.h b/components/autofill/core/browser/data_model/payments/credit_card.h index 769203d..6b1cd3aa 100644 --- a/components/autofill/core/browser/data_model/payments/credit_card.h +++ b/components/autofill/core/browser/data_model/payments/credit_card.h
@@ -20,6 +20,7 @@ #include "components/autofill/core/browser/data_model/usage_history_information.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/suggestions/suggestion.h" +#include "components/autofill/core/common/autofill_payments_features.h" #include "url/gurl.h" namespace autofill { @@ -518,7 +519,15 @@ product_terms_url_ = product_terms_url; } - const std::string& benefit_source() const { return benefit_source_; } + // TODO(crbug.com/416338314): Remove kAutofillEnableCardBenefitsSourceSync + // once this flag is enabled by default and no drawbacks occur. + const std::string& benefit_source() const { + return base::FeatureList::IsEnabled( + features::kAutofillEnableCardBenefitsSourceSync) + ? benefit_source_ + : issuer_id_; + } + void set_benefit_source(std::string_view benefit_source) { benefit_source_ = std::string(benefit_source); }
diff --git a/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc b/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc index 4a497fc..148be94 100644 --- a/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc +++ b/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc
@@ -102,6 +102,19 @@ } } +std::string_view GetCardBenefitSourceSuffix( + const std::string& card_benefit_source) { + if (card_benefit_source == kAmexCardBenefitSource) { + return kAmericanExpress; + } else if (card_benefit_source == kBmoCardBenefitSource) { + return kBmo; + } else if (card_benefit_source == kCurinosCardBenefitSource) { + return kCurinos; + } else { + return ""; + } +} + CardMetadataLoggingContext GetMetadataLoggingContext( base::span<const CreditCard> cards) { constexpr auto kLoggedNetworks =
diff --git a/components/autofill/core/browser/metrics/payments/card_metadata_metrics.h b/components/autofill/core/browser/metrics/payments/card_metadata_metrics.h index 1a359b2d..923b0d1b 100644 --- a/components/autofill/core/browser/metrics/payments/card_metadata_metrics.h +++ b/components/autofill/core/browser/metrics/payments/card_metadata_metrics.h
@@ -11,15 +11,18 @@ namespace autofill::autofill_metrics { -// The below issuer and network names are used for logging purposes. The issuer -// names must be consistent with the Autofill.CreditCardIssuerId in the -// autofill/histograms.xml file. +// The below issuer, network, and benefit source names are used for logging +// purposes. The issuers, networks, and benefit sources must be consistent with +// the Autofill.CreditCardIssuerId, Autofill.CreditCardNetwork, and +// Autofill.CreditCardBenefitSource respectively, in the +// tools/metrics/histograms/metadata/autofill/histograms.xml file. constexpr std::string_view kAmericanExpress = "Amex"; constexpr std::string_view kAnz = "Anz"; constexpr std::string_view kBmo = "Bmo"; constexpr std::string_view kCapitalOne = "CapitalOne"; constexpr std::string_view kChase = "Chase"; constexpr std::string_view kCiti = "Citi"; +constexpr std::string_view kCurinos = "Curinos"; constexpr std::string_view kDiscover = "Discover"; constexpr std::string_view kLloyds = "Lloyds"; constexpr std::string_view kMarqeta = "Marqeta"; @@ -117,10 +120,14 @@ int64_t selected_card_instrument_id; }; -// Get histogram suffix based on given card issuer id or network. +// Get histogram suffix based on a given card issuer id or network. std::string_view GetCardIssuerIdOrNetworkSuffix( const std::string& card_issuer_id_or_network); +// Get histogram suffix based on a given card benefit source. +std::string_view GetCardBenefitSourceSuffix( + const std::string& card_benefit_source); + // Get the CardMetadataLoggingContext for the given credit cards. CardMetadataLoggingContext GetMetadataLoggingContext( base::span<const CreditCard> cards);
diff --git a/components/autofill/core/browser/payments/constants.h b/components/autofill/core/browser/payments/constants.h index ee0e340..767ea40 100644 --- a/components/autofill/core/browser/payments/constants.h +++ b/components/autofill/core/browser/payments/constants.h
@@ -34,6 +34,12 @@ inline constexpr std::string_view kBnplZipIssuerId = "zip"; inline constexpr std::string_view kBnplAfterpayIssuerId = "afterpay"; +// Credit card benefit sources. These are server-generated values that must be +// consistent between server and client. +inline constexpr std::string_view kAmexCardBenefitSource = "amex"; +inline constexpr std::string_view kBmoCardBenefitSource = "bmo"; +inline constexpr std::string_view kCurinosCardBenefitSource = "curinos"; + // The urls to the static card art images used by Capital One cards. inline constexpr std::string_view kCapitalOneCardArtUrl = "https://www.gstatic.com/autofill/virtualcard/icon/capitalone.png";
diff --git a/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc b/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc index a1d6e31..a96b95bf 100644 --- a/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc
@@ -1034,12 +1034,16 @@ // 1. Function reference to call which creates the appropriate credit card // benefit for the unittest. // 2. Whether the flag to render benefits is enabled. -// 3. Issuer ID which is set for the credit card with benefits. +// 3. Whether the flag to sync benefits source is enabled. +// 4. Issuer ID which is set for the credit card with benefits. +// 5. Benefit source which is set for the credit card with benefits. class CreditCardOtpAuthenticatorCardBenefitsTest : public CreditCardOtpAuthenticatorTestBase, public ::testing::WithParamInterface< std::tuple<base::FunctionRef<CreditCardBenefit()>, bool, + bool, + std::string, std::string>> { public: void SetUp() override { @@ -1048,21 +1052,48 @@ {{features::kAutofillEnableCardBenefitsForAmericanExpress, IsCreditCardBenefitsEnabled()}, {features::kAutofillEnableCardBenefitsForBmo, - IsCreditCardBenefitsEnabled()}}); + IsCreditCardBenefitsEnabled()}, + {features::kAutofillEnableFlatRateCardBenefitsFromCurinos, + IsCreditCardBenefitsEnabled()}, + {features::kAutofillEnableCardBenefitsSourceSync, + IsCreditCardBenefitsSourceSyncEnabled()}}); CreateSelectedOtpChallengeOption(CardUnmaskChallengeOptionType::kSmsOtp); card_ = test::GetVirtualCard(); autofill_client().set_last_committed_primary_main_frame_url( test::GetOriginsForMerchantBenefit().begin()->GetURL()); - test::SetUpCreditCardAndBenefitData( - card_, GetBenefit(), GetIssuerId(), personal_data(), - autofill_client().GetAutofillOptimizationGuide()); + if (IsCreditCardBenefitsSourceSyncEnabled()) { + test::SetUpCreditCardAndBenefitData( + card_, /*issuer_id=*/"", GetBenefit(), GetBenefitSource(), + personal_data(), autofill_client().GetAutofillOptimizationGuide()); + } else { + test::SetUpCreditCardAndBenefitData( + card_, GetIssuerId(), GetBenefit(), /*benefit_source=*/"", + personal_data(), autofill_client().GetAutofillOptimizationGuide()); + } } CreditCardBenefit GetBenefit() const { return std::get<0>(GetParam())(); } bool IsCreditCardBenefitsEnabled() const { return std::get<1>(GetParam()); } - const std::string& GetIssuerId() const { return std::get<2>(GetParam()); } + bool IsCreditCardBenefitsSourceSyncEnabled() const { + return std::get<2>(GetParam()); + } + + const std::string& GetIssuerId() const { return std::get<3>(GetParam()); } + + const std::string& GetBenefitSource() const { + return std::get<4>(GetParam()); + } + + bool ShouldShowCardBenefits() const { + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos") { + return IsCreditCardBenefitsEnabled() && + std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit()); + } + return IsCreditCardBenefitsEnabled(); + } const CreditCard& card() { return card_; } @@ -1079,7 +1110,9 @@ &test::GetActiveCreditCardCategoryBenefit, &test::GetActiveCreditCardMerchantBenefit), ::testing::Bool(), - ::testing::Values("amex", "bmo"))); + ::testing::Bool(), + ::testing::Values("amex", "bmo"), + ::testing::Values("amex", "bmo", "curinos"))); // Checks that ClientBehaviorConstants::kShowingCardBenefits is populated as a // signal if a card benefit was shown when unmasking a credit card suggestion @@ -1091,13 +1124,12 @@ /*context_token=*/"context_token_from_previous_unmask_response", /*billing_customer_number=*/kTestBillingCustomerNumber); authenticator_->OnUnmaskPromptAccepted(/*otp=*/u"111111"); - std::vector<ClientBehaviorConstants> signals = payments_network_interface().unmask_request()->client_behavior_signals; EXPECT_EQ(std::ranges::find(signals, ClientBehaviorConstants::kShowingCardBenefits) != signals.end(), - IsCreditCardBenefitsEnabled()); + ShouldShowCardBenefits()); } } // namespace
diff --git a/components/autofill/core/browser/payments/credit_card_risk_based_authenticator_unittest.cc b/components/autofill/core/browser/payments/credit_card_risk_based_authenticator_unittest.cc index 49ae1bd..bf800c5 100644 --- a/components/autofill/core/browser/payments/credit_card_risk_based_authenticator_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_risk_based_authenticator_unittest.cc
@@ -504,12 +504,16 @@ // 1. Function reference to call which creates the appropriate credit card // benefit for the unittest. // 2. Whether the flag to render benefits is enabled. -// 3. Issuer ID which is set for the credit card with benefits. +// 3. Whether the flag to sync benefits source is enabled. +// 4. Issuer ID which is set for the credit card with benefits. +// 5. Benefit source which is set for the credit card with benefits. class CreditCardRiskBasedAuthenticatorCardBenefitsTest : public CreditCardRiskBasedAuthenticatorTest, public ::testing::WithParamInterface< std::tuple<base::FunctionRef<CreditCardBenefit()>, bool, + bool, + std::string, std::string>> { public: void SetUp() override { @@ -518,20 +522,47 @@ {{features::kAutofillEnableCardBenefitsForAmericanExpress, IsCreditCardBenefitsEnabled()}, {features::kAutofillEnableCardBenefitsForBmo, - IsCreditCardBenefitsEnabled()}}); + IsCreditCardBenefitsEnabled()}, + {features::kAutofillEnableFlatRateCardBenefitsFromCurinos, + IsCreditCardBenefitsEnabled()}, + {features::kAutofillEnableCardBenefitsSourceSync, + IsCreditCardBenefitsSourceSyncEnabled()}}); card_ = test::GetMaskedServerCard(); autofill_client()->set_last_committed_primary_main_frame_url( test::GetOriginsForMerchantBenefit().begin()->GetURL()); - test::SetUpCreditCardAndBenefitData( - card_, GetBenefit(), GetIssuerId(), personal_data(), - autofill_client()->GetAutofillOptimizationGuide()); + if (IsCreditCardBenefitsSourceSyncEnabled()) { + test::SetUpCreditCardAndBenefitData( + card_, /*issuer_id=*/"", GetBenefit(), GetBenefitSource(), + personal_data(), autofill_client()->GetAutofillOptimizationGuide()); + } else { + test::SetUpCreditCardAndBenefitData( + card_, GetIssuerId(), GetBenefit(), /*benefit_source=*/"", + personal_data(), autofill_client()->GetAutofillOptimizationGuide()); + } } CreditCardBenefit GetBenefit() const { return std::get<0>(GetParam())(); } bool IsCreditCardBenefitsEnabled() const { return std::get<1>(GetParam()); } - const std::string& GetIssuerId() const { return std::get<2>(GetParam()); } + bool IsCreditCardBenefitsSourceSyncEnabled() const { + return std::get<2>(GetParam()); + } + + const std::string& GetIssuerId() const { return std::get<3>(GetParam()); } + + const std::string& GetBenefitSource() const { + return std::get<4>(GetParam()); + } + + bool ShouldShowCardBenefits() const { + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos") { + return IsCreditCardBenefitsEnabled() && + std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit()); + } + return IsCreditCardBenefitsEnabled(); + } const CreditCard& card() { return card_; } @@ -548,7 +579,9 @@ &test::GetActiveCreditCardCategoryBenefit, &test::GetActiveCreditCardMerchantBenefit), ::testing::Bool(), - ::testing::Values("amex", "bmo"))); + ::testing::Bool(), + ::testing::Values("amex", "bmo"), + ::testing::Values("amex", "bmo", "curinos"))); // Checks that ClientBehaviorConstants::kShowingCardBenefits is populated as a // signal if a card benefit was shown when unmasking a credit card suggestion @@ -563,11 +596,10 @@ std::vector<ClientBehaviorConstants> signals = payments_network_interface()->unmask_request()->client_behavior_signals; - EXPECT_EQ(std::ranges::find(signals, ClientBehaviorConstants::kShowingCardBenefits) != signals.end(), - IsCreditCardBenefitsEnabled()); + ShouldShowCardBenefits()); } } // namespace
diff --git a/components/autofill/core/browser/payments/full_card_request_unittest.cc b/components/autofill/core/browser/payments/full_card_request_unittest.cc index 7151a1c3..ec0bb90 100644 --- a/components/autofill/core/browser/payments/full_card_request_unittest.cc +++ b/components/autofill/core/browser/payments/full_card_request_unittest.cc
@@ -794,12 +794,16 @@ // 1. Function reference to call which creates the appropriate credit card // benefit for the unittest. // 2. Whether the flag to render benefits is enabled. -// 3. Issuer ID which is set for the credit card with benefits. +// 3. Whether the flag to sync benefits source is enabled. +// 4. Issuer ID which is set for the credit card with benefits. +// 5. Benefit source which is set for the credit card with benefits. class FullCardRequestCardBenefitsTest : public FullCardRequestTest, public ::testing::WithParamInterface< std::tuple<base::FunctionRef<CreditCardBenefit()>, bool, + bool, + std::string, std::string>> { public: void SetUp() override { @@ -807,21 +811,47 @@ {{features::kAutofillEnableCardBenefitsForAmericanExpress, IsCreditCardBenefitsEnabled()}, {features::kAutofillEnableCardBenefitsForBmo, - IsCreditCardBenefitsEnabled()}}); - + IsCreditCardBenefitsEnabled()}, + {features::kAutofillEnableFlatRateCardBenefitsFromCurinos, + IsCreditCardBenefitsEnabled()}, + {features::kAutofillEnableCardBenefitsSourceSync, + IsCreditCardBenefitsSourceSyncEnabled()}}); card_ = test::GetMaskedServerCard(); autofill_client().set_last_committed_primary_main_frame_url( test::GetOriginsForMerchantBenefit().begin()->GetURL()); - test::SetUpCreditCardAndBenefitData( - card_, GetBenefit(), GetIssuerId(), personal_data(), - autofill_client().GetAutofillOptimizationGuide()); + if (IsCreditCardBenefitsSourceSyncEnabled()) { + test::SetUpCreditCardAndBenefitData( + card_, /*issuer_id=*/"", GetBenefit(), GetBenefitSource(), + personal_data(), autofill_client().GetAutofillOptimizationGuide()); + } else { + test::SetUpCreditCardAndBenefitData( + card_, GetIssuerId(), GetBenefit(), /*benefit_source=*/"", + personal_data(), autofill_client().GetAutofillOptimizationGuide()); + } } CreditCardBenefit GetBenefit() const { return std::get<0>(GetParam())(); } bool IsCreditCardBenefitsEnabled() const { return std::get<1>(GetParam()); } - const std::string& GetIssuerId() const { return std::get<2>(GetParam()); } + bool IsCreditCardBenefitsSourceSyncEnabled() const { + return std::get<2>(GetParam()); + } + + const std::string& GetIssuerId() const { return std::get<3>(GetParam()); } + + const std::string& GetBenefitSource() const { + return std::get<4>(GetParam()); + } + + bool ShouldShowCardBenefits() const { + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos") { + return IsCreditCardBenefitsEnabled() && + std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit()); + } + return IsCreditCardBenefitsEnabled(); + } const CreditCard& card() { return card_; } @@ -838,7 +868,9 @@ &test::GetActiveCreditCardCategoryBenefit, &test::GetActiveCreditCardMerchantBenefit), ::testing::Bool(), - ::testing::Values("amex", "bmo"))); + ::testing::Bool(), + ::testing::Values("amex", "bmo"), + ::testing::Values("amex", "bmo", "curinos"))); // Checks that ClientBehaviorConstants::kShowingCardBenefits is populated as a // signal if a card benefit was shown when unmasking a credit card suggestion @@ -851,7 +883,7 @@ EXPECT_EQ(std::ranges::find(signals, ClientBehaviorConstants::kShowingCardBenefits) != signals.end(), - IsCreditCardBenefitsEnabled()); + ShouldShowCardBenefits()); } } // namespace autofill::payments
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc index 1873271..d401551 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc
@@ -321,21 +321,28 @@ // Params: // 1. Function reference to call which creates the appropriate credit card // benefit for the unittest. -// 2. Issuer ID which is set for the credit card with benefits. +// 2. Whether the flag to sync benefits source is enabled. +// 3. Issuer ID which is set for the credit card with benefits. +// 4. Benefit source which is set for the credit card with benefits. class AutofillCreditCardBenefitsLabelTest : public PaymentsSuggestionGeneratorTest, public ::testing::WithParamInterface< - std::tuple<base::FunctionRef<CreditCardBenefit()>, std::string>> { + std::tuple<base::FunctionRef<CreditCardBenefit()>, + bool, + std::string, + std::string>> { public: void SetUp() override { PaymentsSuggestionGeneratorTest::SetUp(); - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/ - {features::kAutofillEnableCardBenefitsForAmericanExpress, - features::kAutofillEnableCardBenefitsForBmo, - features::kAutofillEnableCardBenefitsIph, - features::kAutofillEnableNewFopDisplayDesktop}, - /*disabled_features=*/{}); + + scoped_feature_list_.InitWithFeatureStates( + {{features::kAutofillEnableCardBenefitsForAmericanExpress, true}, + {features::kAutofillEnableCardBenefitsForBmo, true}, + {features::kAutofillEnableFlatRateCardBenefitsFromCurinos, true}, + {features::kAutofillEnableCardBenefitsIph, true}, + {features::kAutofillEnableNewFopDisplayDesktop, true}, + {features::kAutofillEnableCardBenefitsSourceSync, + IsCreditCardBenefitsSourceSyncEnabled()}}); std::u16string benefit_description; int64_t instrument_id; @@ -384,12 +391,26 @@ /*guid=*/"00000000-0000-0000-0000-000000000001", /*server_id=*/"server_id1", /*instrument_id=*/instrument_id); - card_.set_issuer_id(std::get<1>(GetParam())); + if (IsCreditCardBenefitsSourceSyncEnabled()) { + card_.set_benefit_source(GetBenefitSource()); + } else { + card_.set_issuer_id(GetIssuerId()); + } payments_data().AddServerCreditCard(card_); } CreditCardBenefit GetBenefit() const { return std::get<0>(GetParam())(); } + bool IsCreditCardBenefitsSourceSyncEnabled() const { + return std::get<1>(GetParam()); + } + + const std::string& GetIssuerId() const { return std::get<2>(GetParam()); } + + const std::string& GetBenefitSource() const { + return std::get<3>(GetParam()); + } + const CreditCard& card() { return card_; } const std::u16string& expected_benefit_text() { @@ -425,30 +446,44 @@ testing::Combine(testing::Values(&test::GetActiveCreditCardFlatRateBenefit, &test::GetActiveCreditCardCategoryBenefit, &test::GetActiveCreditCardMerchantBenefit), - ::testing::Values("amex", "bmo"))); + ::testing::Bool(), + ::testing::Values("amex", "bmo"), + ::testing::Values("amex", "bmo", "curinos"))); #if !BUILDFLAG(IS_ANDROID) // Checks that for FPAN suggestions that the benefit description is displayed. TEST_P(AutofillCreditCardBenefitsLabelTest, BenefitSuggestionLabel_Fpan) { - EXPECT_THAT(CreateCreditCardSuggestionForTest( - card(), *autofill_client(), CREDIT_CARD_NUMBER, - /*virtual_card_option=*/false, - /*card_linked_offer_available=*/false) - .labels, - ElementsAre(std::vector<Suggestion::Text>{ - Suggestion::Text(expected_benefit_text())})); + Suggestion suggestion = CreateCreditCardSuggestionForTest( + card(), *autofill_client(), CREDIT_CARD_NUMBER, + /*virtual_card_option=*/false, + /*card_linked_offer_available=*/false); + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos" && + !std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) { + EXPECT_TRUE(suggestion.labels.empty()); + } else { + EXPECT_THAT(suggestion.labels, + ElementsAre(std::vector<Suggestion::Text>{ + Suggestion::Text(expected_benefit_text())})); + } } // Checks that feature is set to display the credit card benefit IPH for // FPAN suggestions with benefits labels. TEST_P(AutofillCreditCardBenefitsLabelTest, BenefitSuggestionFeatureForIph_Fpan) { - EXPECT_EQ(CreateCreditCardSuggestionForTest( - card(), *autofill_client(), CREDIT_CARD_NUMBER, - /*virtual_card_option=*/false, - /*card_linked_offer_available=*/false) - .iph_metadata.feature, - &feature_engagement::kIPHAutofillCreditCardBenefitFeature); + Suggestion suggestion = CreateCreditCardSuggestionForTest( + card(), *autofill_client(), CREDIT_CARD_NUMBER, + /*virtual_card_option=*/false, + /*card_linked_offer_available=*/false); + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos" && + !std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) { + EXPECT_EQ(suggestion.iph_metadata.feature, nullptr); + } else { + EXPECT_EQ(suggestion.iph_metadata.feature, + &feature_engagement::kIPHAutofillCreditCardBenefitFeature); + } } // Checks that feature is set to display the virtual card IPH for @@ -499,13 +534,19 @@ // as a label. TEST_P(AutofillCreditCardBenefitsLabelTest, BenefitSuggestionLabel_VirtualCard) { - EXPECT_THAT(CreateCreditCardSuggestionForTest( - card(), *autofill_client(), CREDIT_CARD_NUMBER, - /*virtual_card_option=*/true, - /*card_linked_offer_available=*/false) - .labels, - ElementsAre(std::vector<Suggestion::Text>{ - Suggestion::Text(expected_benefit_text())})); + Suggestion suggestion = CreateCreditCardSuggestionForTest( + card(), *autofill_client(), CREDIT_CARD_NUMBER, + /*virtual_card_option=*/true, + /*card_linked_offer_available=*/false); + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos" && + !std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) { + EXPECT_TRUE(suggestion.labels.empty()); + } else { + EXPECT_THAT(suggestion.labels, + ElementsAre(std::vector<Suggestion::Text>{ + Suggestion::Text(expected_benefit_text())})); + } } // Checks that for merchant opt-out virtual cards suggestion the benefit @@ -544,7 +585,8 @@ disable_benefits.InitWithFeatures( /*enabled_features=*/{}, /*disabled_features=*/{ features::kAutofillEnableCardBenefitsForAmericanExpress, - features::kAutofillEnableCardBenefitsForBmo}); + features::kAutofillEnableCardBenefitsForBmo, + features::kAutofillEnableFlatRateCardBenefitsFromCurinos}); DoBenefitSuggestionLabel_MetadataLoggingContextTest(); } @@ -612,17 +654,26 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndDisableFeature( features::kAutofillEnableNewFopDisplayDesktop); - EXPECT_THAT( - CreateCreditCardSuggestionForTest(card(), *autofill_client(), - CREDIT_CARD_NUMBER, - /*virtual_card_option=*/false, - /*card_linked_offer_available=*/false) - .labels, - ElementsAre( - std::vector<Suggestion::Text>{ - Suggestion::Text(expected_benefit_text())}, - std::vector<Suggestion::Text>{Suggestion::Text(card().GetInfo( - CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, /*app_locale=*/"en-US"))})); + Suggestion suggestion = CreateCreditCardSuggestionForTest( + card(), *autofill_client(), CREDIT_CARD_NUMBER, + /*virtual_card_option=*/false, + /*card_linked_offer_available=*/false); + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos" && + !std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) { + EXPECT_THAT(suggestion.labels, + ElementsAre(std::vector<Suggestion::Text>{Suggestion::Text( + card().GetInfo(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, + /*app_locale=*/"en-US"))})); + } else { + EXPECT_THAT( + suggestion.labels, + ElementsAre( + std::vector<Suggestion::Text>{ + Suggestion::Text(expected_benefit_text())}, + std::vector<Suggestion::Text>{Suggestion::Text(card().GetInfo( + CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, /*app_locale=*/"en-US"))})); + } } // Checks that for virtual cards suggestion the benefit description is shown @@ -632,19 +683,27 @@ base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndDisableFeature( features::kAutofillEnableNewFopDisplayDesktop); - - EXPECT_THAT( - CreateCreditCardSuggestionForTest(card(), *autofill_client(), - CREDIT_CARD_NUMBER, - /*virtual_card_option=*/true, - /*card_linked_offer_available=*/false) - .labels, - ElementsAre( - std::vector<Suggestion::Text>{ - Suggestion::Text(expected_benefit_text())}, - std::vector<Suggestion::Text>{ - Suggestion::Text(l10n_util::GetStringUTF16( - IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE))})); + Suggestion suggestion = CreateCreditCardSuggestionForTest( + card(), *autofill_client(), CREDIT_CARD_NUMBER, + /*virtual_card_option=*/true, + /*card_linked_offer_available=*/false); + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos" && + !std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) { + EXPECT_THAT(suggestion.labels, + ElementsAre(std::vector<Suggestion::Text>{ + Suggestion::Text(l10n_util::GetStringUTF16( + IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE))})); + } else { + EXPECT_THAT( + suggestion.labels, + ElementsAre( + std::vector<Suggestion::Text>{ + Suggestion::Text(expected_benefit_text())}, + std::vector<Suggestion::Text>{ + Suggestion::Text(l10n_util::GetStringUTF16( + IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE))})); + } } // Checks that for merchant opt-out virtual cards suggestion the benefit @@ -659,18 +718,28 @@ autofill_client()->GetAutofillOptimizationGuide()), ShouldBlockFormFieldSuggestion) .WillByDefault(testing::Return(true)); - EXPECT_THAT( - CreateCreditCardSuggestionForTest(virtual_card, *autofill_client(), - CREDIT_CARD_NUMBER, - /*virtual_card_option=*/true, - /*card_linked_offer_available=*/false) - .labels, - ElementsAre( - std::vector<Suggestion::Text>{ - Suggestion::Text(expected_benefit_text())}, - std::vector< - Suggestion::Text>{Suggestion::Text(l10n_util::GetStringUTF16( - IDS_AUTOFILL_VIRTUAL_CARD_DISABLED_SUGGESTION_OPTION_VALUE))})); + Suggestion suggestion = CreateCreditCardSuggestionForTest( + virtual_card, *autofill_client(), CREDIT_CARD_NUMBER, + /*virtual_card_option=*/true, + /*card_linked_offer_available=*/false); + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos" && + !std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) { + EXPECT_THAT( + suggestion.labels, + ElementsAre(std::vector<Suggestion::Text>{ + Suggestion::Text(l10n_util::GetStringUTF16( + IDS_AUTOFILL_VIRTUAL_CARD_DISABLED_SUGGESTION_OPTION_VALUE))})); + } else { + EXPECT_THAT( + suggestion.labels, + ElementsAre( + std::vector<Suggestion::Text>{ + Suggestion::Text(expected_benefit_text())}, + std::vector< + Suggestion::Text>{Suggestion::Text(l10n_util::GetStringUTF16( + IDS_AUTOFILL_VIRTUAL_CARD_DISABLED_SUGGESTION_OPTION_VALUE))})); + } } // Checks that the merchant benefit description is not displayed for suggestions @@ -770,13 +839,24 @@ cards, *autofill_client(), *credit_card_form_event_logger_); EXPECT_EQ(suggestions[0].type, SuggestionType::kCreditCardEntry); - EXPECT_THAT(suggestions[0], - EqualLabels({{expected_benefit_text()}, - {card().GetInfo(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, - app_locale())}})); - EXPECT_TRUE(suggestions[0] - .GetPayload<Suggestion::PaymentsPayload>() - .should_display_terms_available); + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos" && + !std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) { + EXPECT_THAT(suggestions[0], + EqualLabels({{card().GetInfo(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, + app_locale())}})); + EXPECT_FALSE(suggestions[0] + .GetPayload<Suggestion::PaymentsPayload>() + .should_display_terms_available); + } else { + EXPECT_THAT(suggestions[0], + EqualLabels({{expected_benefit_text()}, + {card().GetInfo(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, + app_locale())}})); + EXPECT_TRUE(suggestions[0] + .GetPayload<Suggestion::PaymentsPayload>() + .should_display_terms_available); + } } TEST_P(AutofillCreditCardBenefitsLabelTest, @@ -798,14 +878,25 @@ cards, *autofill_client(), *credit_card_form_event_logger_); EXPECT_EQ(suggestions[0].type, SuggestionType::kVirtualCreditCardEntry); - EXPECT_THAT( - suggestions[0], - EqualLabels({{expected_benefit_text()}, - {l10n_util::GetStringUTF16( - IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE)}})); - EXPECT_TRUE(suggestions[0] - .GetPayload<Suggestion::PaymentsPayload>() - .should_display_terms_available); + if (IsCreditCardBenefitsSourceSyncEnabled() && + GetBenefitSource() == "curinos" && + !std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) { + EXPECT_THAT(suggestions[0], + EqualLabels({{l10n_util::GetStringUTF16( + IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE)}})); + EXPECT_FALSE(suggestions[0] + .GetPayload<Suggestion::PaymentsPayload>() + .should_display_terms_available); + } else { + EXPECT_THAT( + suggestions[0], + EqualLabels({{expected_benefit_text()}, + {l10n_util::GetStringUTF16( + IDS_AUTOFILL_VIRTUAL_CARD_SUGGESTION_OPTION_VALUE)}})); + EXPECT_TRUE(suggestions[0] + .GetPayload<Suggestion::PaymentsPayload>() + .should_display_terms_available); + } } // Checks that the merchant benefit description is not displayed for suggestions
diff --git a/components/autofill/core/browser/test_utils/autofill_test_utils.cc b/components/autofill/core/browser/test_utils/autofill_test_utils.cc index 03db465..bec4287 100644 --- a/components/autofill/core/browser/test_utils/autofill_test_utils.cc +++ b/components/autofill/core/browser/test_utils/autofill_test_utils.cc
@@ -689,8 +689,9 @@ void SetUpCreditCardAndBenefitData( CreditCard& card, - const CreditCardBenefit& benefit, const std::string& issuer_id, + const CreditCardBenefit& benefit, + const std::string& benefit_source, TestPersonalDataManager& personal_data, AutofillOptimizationGuide* optimization_guide) { std::visit( @@ -716,6 +717,7 @@ benefit); personal_data.payments_data_manager().AddCreditCardBenefitForTest(benefit); card.set_issuer_id(issuer_id); + card.set_benefit_source(benefit_source); personal_data.test_payments_data_manager().AddServerCreditCard(card); }
diff --git a/components/autofill/core/browser/test_utils/autofill_test_utils.h b/components/autofill/core/browser/test_utils/autofill_test_utils.h index c3e01c6..ca3e11a 100644 --- a/components/autofill/core/browser/test_utils/autofill_test_utils.h +++ b/components/autofill/core/browser/test_utils/autofill_test_utils.h
@@ -231,12 +231,14 @@ // benefit. base::flat_set<url::Origin> GetOriginsForMerchantBenefit(); -// Adds `card` with a set `benefit` and `issuer_id` to `personal_data`. Also -// configures a category benefit with the `optimization_guide`. +// Adds `card` with a set `issuer_id`, `benefit` and `benefit_source` to +// `personal_data`. Also configures a category benefit with the +// `optimization_guide`. void SetUpCreditCardAndBenefitData( CreditCard& card, - const CreditCardBenefit& benefit, const std::string& issuer_id, + const CreditCardBenefit& benefit, + const std::string& benefit_source, TestPersonalDataManager& personal_data, AutofillOptimizationGuide* optimization_guide);
diff --git a/components/collaboration/internal/collaboration_controller.cc b/components/collaboration/internal/collaboration_controller.cc index 86e2701..65f540ec 100644 --- a/components/collaboration/internal/collaboration_controller.cc +++ b/components/collaboration/internal/collaboration_controller.cc
@@ -457,9 +457,10 @@ private: void FinishAndTransition() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - RecordLatency(GetLogger(), - metrics::CollaborationServiceStep::kAuthenticationSuccess, - base::Time::Now() - start_time_); + RecordLatency( + GetLogger(), + metrics::CollaborationServiceStep::kAuthenticationInitToSuccess, + base::Time::Now() - start_time_); controller_->delegate()->NotifySignInAndSyncStatusChange(); controller_->TransitionTo(StateId::kWaitingForServicesToInitialize); } @@ -513,9 +514,10 @@ void OnProcessingFinishedWithSuccess() override { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - RecordLatency(GetLogger(), - metrics::CollaborationServiceStep::kServicesInitialized, - base::Time::Now() - start_time_); + RecordLatency( + GetLogger(), + metrics::CollaborationServiceStep::kWaitingForServicesInitialization, + base::Time::Now() - start_time_); controller_->TransitionTo(StateId::kCheckingFlowRequirements); }
diff --git a/components/collaboration/internal/collaboration_controller_unittest.cc b/components/collaboration/internal/collaboration_controller_unittest.cc index 7f59111..1b9c44c 100644 --- a/components/collaboration/internal/collaboration_controller_unittest.cc +++ b/components/collaboration/internal/collaboration_controller_unittest.cc
@@ -11,6 +11,7 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" #include "base/test/task_environment.h" +#include "base/time/time.h" #include "components/collaboration/internal/metrics.h" #include "components/collaboration/public/collaboration_controller_delegate.h" #include "components/collaboration/public/collaboration_flow_type.h" @@ -133,6 +134,9 @@ TEST_F(CollaborationControllerTest, FullJoinFlowAllStates) { base::HistogramTester histogram_tester; + base::TimeDelta authentication_time = base::Milliseconds(10); + base::TimeDelta service_initialization_time = base::Milliseconds(11); + base::TimeDelta tab_group_fetch_time = base::Milliseconds(12); RunLoop run_loop; @@ -176,6 +180,7 @@ .WillOnce(SaveArg<0>(&sync_observer)); // 3. Authenticating -> WaitingForServicesToInitialize state. + task_environment_.FastForwardBy(authentication_time); std::move(authentication_ui_calback).Run(Outcome::kSuccess); EXPECT_EQ(controller_->GetStateForTesting(), StateId::kWaitingForServicesToInitialize); @@ -189,6 +194,7 @@ // 4. WaitingForServicesToInitialize -> CheckingFlowRequirementsState -> // AddingUserToGroup state. + task_environment_.FastForwardBy(service_initialization_time); sync_observer->OnInitialized(); EXPECT_EQ(controller_->GetStateForTesting(), StateId::kAddingUserToGroup); @@ -234,6 +240,7 @@ StateId::kWaitingForSyncAndDataSharingGroup); // Simulate added in both tab group and data_sharing group. + task_environment_.FastForwardBy(tab_group_fetch_time); base::OnceCallback<void(Outcome)> promote_ui_callback; EXPECT_CALL(*collaboration_service_, GetCurrentUserRoleForGroup(kGroupId)) .WillOnce(Return(data_sharing::MemberRole::kMember)); @@ -262,6 +269,15 @@ histogram_tester.ExpectBucketCount( "CollaborationService.JoinFlow", metrics::CollaborationServiceJoinEvent::kOpenedNewGroup, 1); + histogram_tester.ExpectTimeBucketCount( + "CollaborationService.Latency.AuthenticationInitToSuccess", + authentication_time, 1); + histogram_tester.ExpectTimeBucketCount( + "CollaborationService.Latency.WaitingForServicesInitialization", + service_initialization_time, 1); + histogram_tester.ExpectTimeBucketCount( + "CollaborationService.Latency.TabGroupFetchedAfterPeopleGroupJoined", + tab_group_fetch_time, 1); } TEST_F(CollaborationControllerTest, JoinFlowManagedDevice) { @@ -677,6 +693,7 @@ TEST_F(CollaborationControllerTest, FullShareFlowAllStates) { base::HistogramTester histogram_tester; + base::TimeDelta url_ready_time = base::Milliseconds(10); // Start Share flow. tab_groups::LocalTabGroupID local_id = @@ -730,6 +747,7 @@ GroupData(kGroupId, /*display_name=*/"", /*members=*/{}, /*former_members=*/{}, kAccessToken); std::move(group_data_callback).Run(group_data); + task_environment_.FastForwardBy(url_ready_time); std::move(tab_group_sharing_callback) .Run(tab_groups::TabGroupSyncService::TabGroupSharingResult::kSuccess); EXPECT_EQ(controller_->GetStateForTesting(), StateId::kSharingTabGroupUrl); @@ -752,6 +770,9 @@ histogram_tester.ExpectBucketCount( "CollaborationService.ShareOrManageFlow", metrics::CollaborationServiceShareOrManageEvent::kUrlReadyToShare, 1); + histogram_tester.ExpectTimeBucketCount( + "CollaborationService.Latency.LinkReadyAfterGroupCreation", + url_ready_time, 1); } TEST_F(CollaborationControllerTest, CheckingFlowRequirementsManageFlow) {
diff --git a/components/collaboration/internal/metrics.cc b/components/collaboration/internal/metrics.cc index 2204b64..5a8c354 100644 --- a/components/collaboration/internal/metrics.cc +++ b/components/collaboration/internal/metrics.cc
@@ -7,6 +7,7 @@ #include <string_view> #include "base/metrics/histogram_functions.h" +#include "base/strings/strcat.h" #include "base/strings/stringprintf.h" #include "components/collaboration/public/collaboration_flow_entry_point.h" #include "components/data_sharing/public/logger.h" @@ -269,10 +270,10 @@ switch (step) { case CollaborationServiceStep::kUnknown: return "Unknown"; - case CollaborationServiceStep::kAuthenticationSuccess: - return "AuthenticationSuccess"; - case CollaborationServiceStep::kServicesInitialized: - return "ServicesInitialized"; + case CollaborationServiceStep::kAuthenticationInitToSuccess: + return "AuthenticationInitToSuccess"; + case CollaborationServiceStep::kWaitingForServicesInitialization: + return "WaitingForServicesInitialization"; case CollaborationServiceStep::kLinkReadyAfterGroupCreation: return "LinkReadyAfterGroupCreation"; case CollaborationServiceStep::kTabGroupFetchedAfterPeopleGroupJoined: @@ -379,7 +380,11 @@ void RecordLatency(data_sharing::Logger* logger, CollaborationServiceStep step, base::TimeDelta duration) { - base::UmaHistogramMediumTimes("CollaborationService.Latency", duration); + std::string histogram_name = + base::StrCat({"CollaborationService.Latency.", + CollaborationServiceStepToString(step)}); + + base::UmaHistogramMediumTimes(histogram_name, duration); DATA_SHARING_LOG(logger_common::mojom::LogSource::CollaborationService, logger, CreateLatencyLogToString(step, duration)); }
diff --git a/components/collaboration/internal/metrics.h b/components/collaboration/internal/metrics.h index 1ef7823..9ee32aa8 100644 --- a/components/collaboration/internal/metrics.h +++ b/components/collaboration/internal/metrics.h
@@ -96,19 +96,14 @@ }; // LINT.ThenChange(//tools/metrics/histograms/metadata/collaboration_service/enums.xml:CollaborationServiceShareOrManageEvent) -// Steps in a collaboration flow that has user wait time. -// These values are persisted to logs. Entries should not be renumbered and -// number values should never be reused. -// LINT.IfChange(CollaborationServiceStep) enum class CollaborationServiceStep { kUnknown = 0, - kAuthenticationSuccess = 1, - kServicesInitialized = 2, + kAuthenticationInitToSuccess = 1, + kWaitingForServicesInitialization = 2, kLinkReadyAfterGroupCreation = 3, kTabGroupFetchedAfterPeopleGroupJoined = 4, kMaxValue = kTabGroupFetchedAfterPeopleGroupJoined, }; -// LINT.ThenChange(//tools/metrics/histograms/metadata/collaboration_service/enums.xml:CollaborationServiceStep) void RecordJoinEvent(data_sharing::Logger* logger, CollaborationServiceJoinEvent event);
diff --git a/components/enterprise/client_certificates/core/BUILD.gn b/components/enterprise/client_certificates/core/BUILD.gn index 97fc7fd..56ef7430 100644 --- a/components/enterprise/client_certificates/core/BUILD.gn +++ b/components/enterprise/client_certificates/core/BUILD.gn
@@ -108,6 +108,12 @@ "upload_client_error.cc", ] + if (is_win) { + public += [ "win/windows_software_private_key_factory.h" ] + + sources += [ "win/windows_software_private_key_factory.cc" ] + } + public_deps = [ "//base", "//components/enterprise/client_certificates/proto:db_client_certs", @@ -190,6 +196,10 @@ "unexportable_private_key_unittest.cc", ] + if (is_win) { + sources += [ "win/windows_software_private_key_factory_unittest.cc" ] + } + deps = [ ":cloud_management_delegate", ":core",
diff --git a/components/enterprise/client_certificates/core/features.cc b/components/enterprise/client_certificates/core/features.cc index c1e64cf5..9262a96 100644 --- a/components/enterprise/client_certificates/core/features.cc +++ b/components/enterprise/client_certificates/core/features.cc
@@ -4,6 +4,10 @@ #include "components/enterprise/client_certificates/core/features.h" +#if BUILDFLAG(IS_WIN) +#include "crypto/features.h" +#endif // BUILDFLAG(IS_WIN) + namespace client_certificates::features { BASE_FEATURE(kManagedClientCertificateForUserEnabled, @@ -30,4 +34,17 @@ return base::FeatureList::IsEnabled(kManagedUserClientCertificateInPrefs); } +#if BUILDFLAG(IS_WIN) +BASE_FEATURE(kWindowsSoftwareKeysEnabled, + "WindowsSoftwareKeysEnabled", + base::FEATURE_ENABLED_BY_DEFAULT); + +bool AreWindowsSoftwareKeysEnabled() { + // Windows Software keys depend on a fix in the //crypto layer. + return base::FeatureList::IsEnabled( + crypto::features::kIsHardwareBackedFixEnabled) && + base::FeatureList::IsEnabled(kWindowsSoftwareKeysEnabled); +} +#endif // BUILDFLAG(IS_WIN) + } // namespace client_certificates::features
diff --git a/components/enterprise/client_certificates/core/features.h b/components/enterprise/client_certificates/core/features.h index 5a63a68..8ae7dfd 100644 --- a/components/enterprise/client_certificates/core/features.h +++ b/components/enterprise/client_certificates/core/features.h
@@ -6,6 +6,7 @@ #define COMPONENTS_ENTERPRISE_CLIENT_CERTIFICATES_CORE_FEATURES_H_ #include "base/feature_list.h" +#include "build/build_config.h" namespace client_certificates::features { @@ -29,6 +30,14 @@ // Return true if the managed user certificate should be stored in prefs. bool IsManagedUserClientCertificateInPrefsEnabled(); +#if BUILDFLAG(IS_WIN) +// Controls whether Windows software keys are enabled or not. +BASE_DECLARE_FEATURE(kWindowsSoftwareKeysEnabled); + +// Return true if Windows software keys are enabled. +bool AreWindowsSoftwareKeysEnabled(); +#endif // BUILDFLAG(IS_WIN) + } // namespace client_certificates::features #endif // COMPONENTS_ENTERPRISE_CLIENT_CERTIFICATES_CORE_FEATURES_H_
diff --git a/components/enterprise/client_certificates/core/key_upload_client.cc b/components/enterprise/client_certificates/core/key_upload_client.cc index d407025..9a373be 100644 --- a/components/enterprise/client_certificates/core/key_upload_client.cc +++ b/components/enterprise/client_certificates/core/key_upload_client.cc
@@ -37,6 +37,7 @@ case PrivateKeySource::kUnexportableKey: return BPKUR::CHROME_BROWSER_HW_KEY; case PrivateKeySource::kSoftwareKey: + case PrivateKeySource::kOsSoftwareKey: return BPKUR::CHROME_BROWSER_OS_KEY; } }
diff --git a/components/enterprise/client_certificates/core/private_key_factory.cc b/components/enterprise/client_certificates/core/private_key_factory.cc index 1c3d09a..8b578364 100644 --- a/components/enterprise/client_certificates/core/private_key_factory.cc +++ b/components/enterprise/client_certificates/core/private_key_factory.cc
@@ -15,6 +15,18 @@ namespace client_certificates { +namespace { + +// List of all the key sources ordered by security (i.e. first entry yields most +// secure key source). +constexpr std::array<PrivateKeySource, 3> kKeySourcesOrderedBySecurity = { + PrivateKeySource::kUnexportableKey, + PrivateKeySource::kOsSoftwareKey, + PrivateKeySource::kSoftwareKey, +}; + +} // namespace + PrivateKeyFactory::PrivateKeyFactory() = default; PrivateKeyFactory::~PrivateKeyFactory() = default; @@ -52,21 +64,14 @@ PrivateKeyFactory::PrivateKeyCallback callback) { // Go through the supported key sources in order of most secure to least, and // delegate the key creation to that sub factory. - if (sub_factories_.contains(PrivateKeySource::kUnexportableKey)) { - sub_factories_[PrivateKeySource::kUnexportableKey]->CreatePrivateKey( - base::BindOnce(&PrivateKeyFactoryImpl::OnPrivateKeyCreated, - weak_factory_.GetWeakPtr(), - PrivateKeySource::kUnexportableKey, - std::move(callback))); - return; - } - - if (sub_factories_.contains(PrivateKeySource::kSoftwareKey)) { - sub_factories_[PrivateKeySource::kSoftwareKey]->CreatePrivateKey( - base::BindOnce(&PrivateKeyFactoryImpl::OnPrivateKeyCreated, - weak_factory_.GetWeakPtr(), - PrivateKeySource::kSoftwareKey, std::move(callback))); - return; + for (size_t i = 0U; i < kKeySourcesOrderedBySecurity.size(); i++) { + PrivateKeySource source = kKeySourcesOrderedBySecurity[i]; + if (sub_factories_.contains(source)) { + sub_factories_[source]->CreatePrivateKey(base::BindOnce( + &PrivateKeyFactoryImpl::OnPrivateKeyCreated, + weak_factory_.GetWeakPtr(), source, std::move(callback))); + return; + } } std::move(callback).Run(nullptr);
diff --git a/components/enterprise/client_certificates/core/private_key_factory_unittest.cc b/components/enterprise/client_certificates/core/private_key_factory_unittest.cc index 4e16028..9dd2ae1 100644 --- a/components/enterprise/client_certificates/core/private_key_factory_unittest.cc +++ b/components/enterprise/client_certificates/core/private_key_factory_unittest.cc
@@ -113,8 +113,31 @@ EXPECT_FALSE(test_future.Get()); } +TEST(PrivateKeyFactoryTest, CreatePrivateKey_OsSoftwareAndSoftware) { + auto os_software_factory = CreateMockedFactory(); + auto software_factory = CreateMockedFactory(); + + EXPECT_CALL(*os_software_factory, CreatePrivateKey(_)) + .WillOnce(Invoke([](PrivateKeyFactory::PrivateKeyCallback callback) { + std::move(callback).Run(base::MakeRefCounted<MockPrivateKey>()); + })); + + PrivateKeyFactory::PrivateKeyFactoriesMap map; + map.insert_or_assign(PrivateKeySource::kOsSoftwareKey, + std::move(os_software_factory)); + map.insert_or_assign(PrivateKeySource::kSoftwareKey, + std::move(software_factory)); + auto factory = PrivateKeyFactory::Create(std::move(map)); + + base::test::TestFuture<scoped_refptr<PrivateKey>> test_future; + factory->CreatePrivateKey(test_future.GetCallback()); + + EXPECT_TRUE(test_future.Get()); +} + TEST(PrivateKeyFactoryTest, CreatePrivateKey_AllSources) { auto unexportable_factory = CreateMockedFactory(); + auto os_software_factory = CreateMockedFactory(); auto software_factory = CreateMockedFactory(); EXPECT_CALL(*unexportable_factory, CreatePrivateKey(_)) @@ -123,6 +146,8 @@ })); PrivateKeyFactory::PrivateKeyFactoriesMap map; + map.insert_or_assign(PrivateKeySource::kOsSoftwareKey, + std::move(os_software_factory)); map.insert_or_assign(PrivateKeySource::kSoftwareKey, std::move(software_factory)); map.insert_or_assign(PrivateKeySource::kUnexportableKey, @@ -137,6 +162,7 @@ TEST(PrivateKeyFactoryTest, CreatePrivateKey_AllSources_UnexportableFail) { auto unexportable_factory = CreateMockedFactory(); + auto os_software_factory = CreateMockedFactory(); auto software_factory = CreateMockedFactory(); EXPECT_CALL(*unexportable_factory, CreatePrivateKey(_)) @@ -150,6 +176,8 @@ })); PrivateKeyFactory::PrivateKeyFactoriesMap map; + map.insert_or_assign(PrivateKeySource::kOsSoftwareKey, + std::move(os_software_factory)); map.insert_or_assign(PrivateKeySource::kSoftwareKey, std::move(software_factory)); map.insert_or_assign(PrivateKeySource::kUnexportableKey, @@ -164,6 +192,7 @@ TEST(PrivateKeyFactoryTest, CreatePrivateKey_AllSources_AllFail) { auto unexportable_factory = CreateMockedFactory(); + auto os_software_factory = CreateMockedFactory(); auto software_factory = CreateMockedFactory(); EXPECT_CALL(*unexportable_factory, CreatePrivateKey(_)) @@ -177,6 +206,8 @@ })); PrivateKeyFactory::PrivateKeyFactoriesMap map; + map.insert_or_assign(PrivateKeySource::kOsSoftwareKey, + std::move(os_software_factory)); map.insert_or_assign(PrivateKeySource::kSoftwareKey, std::move(software_factory)); map.insert_or_assign(PrivateKeySource::kUnexportableKey, @@ -191,6 +222,7 @@ TEST(PrivateKeyFactoryTest, LoadPrivateKey_AllSources_Unexportable) { auto unexportable_factory = CreateMockedFactory(); + auto os_software_factory = CreateMockedFactory(); auto software_factory = CreateMockedFactory(); client_certificates_pb::PrivateKey serialized_private_key; @@ -208,6 +240,8 @@ })); PrivateKeyFactory::PrivateKeyFactoriesMap map; + map.insert_or_assign(PrivateKeySource::kOsSoftwareKey, + std::move(os_software_factory)); map.insert_or_assign(PrivateKeySource::kSoftwareKey, std::move(software_factory)); map.insert_or_assign(PrivateKeySource::kUnexportableKey, @@ -222,6 +256,7 @@ TEST(PrivateKeyFactoryTest, LoadPrivateKeyFromDict_AllSources_Unexportable) { auto unexportable_factory = CreateMockedFactory(); + auto os_software_factory = CreateMockedFactory(); auto software_factory = CreateMockedFactory(); base::Value::Dict serialized_private_key; @@ -234,12 +269,49 @@ Invoke([&unexportable_source]( const base::Value::Dict& serialized_private_key_param, PrivateKeyFactory::PrivateKeyCallback callback) { - EXPECT_EQ(unexportable_source, - *serialized_private_key_param.FindInt(kKeySource)); + EXPECT_EQ(*serialized_private_key_param.FindInt(kKeySource), + unexportable_source); std::move(callback).Run(base::MakeRefCounted<MockPrivateKey>()); })); PrivateKeyFactory::PrivateKeyFactoriesMap map; + map.insert_or_assign(PrivateKeySource::kOsSoftwareKey, + std::move(os_software_factory)); + map.insert_or_assign(PrivateKeySource::kSoftwareKey, + std::move(software_factory)); + map.insert_or_assign(PrivateKeySource::kUnexportableKey, + std::move(unexportable_factory)); + auto factory = PrivateKeyFactory::Create(std::move(map)); + + base::test::TestFuture<scoped_refptr<PrivateKey>> test_future; + factory->LoadPrivateKeyFromDict(serialized_private_key, + test_future.GetCallback()); + + EXPECT_TRUE(test_future.Get()); +} + +TEST(PrivateKeyFactoryTest, LoadPrivateKeyFromDict_AllSources_OsSoftware) { + auto unexportable_factory = CreateMockedFactory(); + auto os_software_factory = CreateMockedFactory(); + auto software_factory = CreateMockedFactory(); + + base::Value::Dict serialized_private_key; + int expected_source = static_cast<int>(PrivateKeySource::kOsSoftwareKey); + serialized_private_key.Set(kKeySource, expected_source); + + EXPECT_CALL(*os_software_factory, LoadPrivateKeyFromDict(_, _)) + .WillOnce( + Invoke([&expected_source]( + const base::Value::Dict& serialized_private_key_param, + PrivateKeyFactory::PrivateKeyCallback callback) { + EXPECT_EQ(*serialized_private_key_param.FindInt(kKeySource), + expected_source); + std::move(callback).Run(base::MakeRefCounted<MockPrivateKey>()); + })); + + PrivateKeyFactory::PrivateKeyFactoriesMap map; + map.insert_or_assign(PrivateKeySource::kOsSoftwareKey, + std::move(os_software_factory)); map.insert_or_assign(PrivateKeySource::kSoftwareKey, std::move(software_factory)); map.insert_or_assign(PrivateKeySource::kUnexportableKey,
diff --git a/components/enterprise/client_certificates/core/private_key_types.cc b/components/enterprise/client_certificates/core/private_key_types.cc index 616dd69..05786c38b 100644 --- a/components/enterprise/client_certificates/core/private_key_types.cc +++ b/components/enterprise/client_certificates/core/private_key_types.cc
@@ -13,6 +13,8 @@ return PrivateKeySource::kUnexportableKey; case client_certificates_pb::PrivateKey::PRIVATE_SOFTWARE_KEY: return PrivateKeySource::kSoftwareKey; + case client_certificates_pb::PrivateKey::PRIVATE_OS_SOFTWARE_KEY: + return PrivateKeySource::kOsSoftwareKey; default: return std::nullopt; } @@ -25,6 +27,8 @@ return client_certificates_pb::PrivateKey::PRIVATE_UNEXPORTABLE_KEY; case PrivateKeySource::kSoftwareKey: return client_certificates_pb::PrivateKey::PRIVATE_SOFTWARE_KEY; + case PrivateKeySource::kOsSoftwareKey: + return client_certificates_pb::PrivateKey::PRIVATE_OS_SOFTWARE_KEY; } } @@ -34,6 +38,8 @@ return PrivateKeySource::kUnexportableKey; case 1: return PrivateKeySource::kSoftwareKey; + case 2: + return PrivateKeySource::kOsSoftwareKey; default: return std::nullopt; }
diff --git a/components/enterprise/client_certificates/core/private_key_types.h b/components/enterprise/client_certificates/core/private_key_types.h index aebfaae..c9cae715 100644 --- a/components/enterprise/client_certificates/core/private_key_types.h +++ b/components/enterprise/client_certificates/core/private_key_types.h
@@ -23,7 +23,10 @@ // mechanism. kSoftwareKey = 1, - kMaxValue = kSoftwareKey + // Key created by the operating system that is not hardware-backed. + kOsSoftwareKey = 2, + + kMaxValue = kOsSoftwareKey }; // Converts a `proto_key_source` from the proto values to the C++ enum values.
diff --git a/components/enterprise/client_certificates/core/unexportable_private_key.cc b/components/enterprise/client_certificates/core/unexportable_private_key.cc index 0bf4d8a9..4a62044 100644 --- a/components/enterprise/client_certificates/core/unexportable_private_key.cc +++ b/components/enterprise/client_certificates/core/unexportable_private_key.cc
@@ -14,7 +14,13 @@ UnexportablePrivateKey::UnexportablePrivateKey( std::unique_ptr<crypto::UnexportableSigningKey> key) - : PrivateKey(PrivateKeySource::kUnexportableKey, + : UnexportablePrivateKey(std::move(key), + PrivateKeySource::kUnexportableKey) {} + +UnexportablePrivateKey::UnexportablePrivateKey( + std::unique_ptr<crypto::UnexportableSigningKey> key, + PrivateKeySource key_source) + : PrivateKey(key_source, SSLKeyConverter::Get()->ConvertUnexportableKeySlowly(*key)), key_(std::move(key)) { CHECK(key_);
diff --git a/components/enterprise/client_certificates/core/unexportable_private_key.h b/components/enterprise/client_certificates/core/unexportable_private_key.h index d5dc4700..5205d0b 100644 --- a/components/enterprise/client_certificates/core/unexportable_private_key.h +++ b/components/enterprise/client_certificates/core/unexportable_private_key.h
@@ -19,9 +19,16 @@ class UnexportablePrivateKey : public PrivateKey { public: + // Wraps `key` and associates it with PrivateKeySource::kUnexportableKey. explicit UnexportablePrivateKey( std::unique_ptr<crypto::UnexportableSigningKey> key); + // Not all crypto::UnexportableSigningKey are TPM-backed, so allow + // reusing this class by enabling the association of `key` with parameterized + // `key_source`. + UnexportablePrivateKey(std::unique_ptr<crypto::UnexportableSigningKey> key, + PrivateKeySource key_source); + // PrivateKey: std::optional<std::vector<uint8_t>> SignSlowly( base::span<const uint8_t> data) const override;
diff --git a/components/enterprise/client_certificates/core/unexportable_private_key_factory_unittest.cc b/components/enterprise/client_certificates/core/unexportable_private_key_factory_unittest.cc index c7248e6..f565fbc 100644 --- a/components/enterprise/client_certificates/core/unexportable_private_key_factory_unittest.cc +++ b/components/enterprise/client_certificates/core/unexportable_private_key_factory_unittest.cc
@@ -24,6 +24,8 @@ ASSERT_TRUE(loaded_key); EXPECT_NE(key, loaded_key); EXPECT_EQ(key->GetAlgorithm(), loaded_key->GetAlgorithm()); + EXPECT_EQ(key->GetSource(), loaded_key->GetSource()); + EXPECT_EQ(key->GetSource(), PrivateKeySource::kUnexportableKey); ASSERT_THAT(key->GetSubjectPublicKeyInfo(), testing::ElementsAreArray(loaded_key->GetSubjectPublicKeyInfo())); ASSERT_TRUE(key->GetSSLPrivateKey());
diff --git a/components/enterprise/client_certificates/core/unexportable_private_key_unittest.cc b/components/enterprise/client_certificates/core/unexportable_private_key_unittest.cc index a88faeb6..db300dfb 100644 --- a/components/enterprise/client_certificates/core/unexportable_private_key_unittest.cc +++ b/components/enterprise/client_certificates/core/unexportable_private_key_unittest.cc
@@ -50,4 +50,36 @@ EXPECT_GT(dict_key.FindString(kKey)->size(), 0U); } +TEST(UnexportablePrivateKeyTest, SupportedCreateKeySoftware) { + ScopedSSLKeyConverter scoped_converter; + auto provider = crypto::GetUnexportableKeyProvider(/*config=*/{}); + ASSERT_TRUE(provider); + + // The mock only works with the ECDSA_SHA256 algorithm. + std::array<crypto::SignatureVerifier::SignatureAlgorithm, 1> + kAcceptableAlgorithms = {crypto::SignatureVerifier::ECDSA_SHA256}; + auto unexportable_key = + provider->GenerateSigningKeySlowly(kAcceptableAlgorithms); + ASSERT_TRUE(unexportable_key); + + auto private_key = base::MakeRefCounted<UnexportablePrivateKey>( + std::move(unexportable_key), PrivateKeySource::kOsSoftwareKey); + + auto spki_bytes = private_key->GetSubjectPublicKeyInfo(); + EXPECT_GT(spki_bytes.size(), 0U); + EXPECT_EQ(private_key->GetAlgorithm(), + crypto::SignatureVerifier::ECDSA_SHA256); + EXPECT_TRUE(private_key->SignSlowly(spki_bytes).has_value()); + + auto proto_key = private_key->ToProto(); + EXPECT_EQ(proto_key.source(), + client_certificates_pb::PrivateKey::PRIVATE_OS_SOFTWARE_KEY); + EXPECT_GT(proto_key.wrapped_key().size(), 0U); + + auto dict_key = private_key->ToDict(); + EXPECT_EQ(*dict_key.FindInt(kKeySource), + static_cast<int>(PrivateKeySource::kOsSoftwareKey)); + EXPECT_GT(dict_key.FindString(kKey)->size(), 0U); +} + } // namespace client_certificates
diff --git a/components/enterprise/client_certificates/core/win/windows_software_private_key_factory.cc b/components/enterprise/client_certificates/core/win/windows_software_private_key_factory.cc new file mode 100644 index 0000000..8f197fd --- /dev/null +++ b/components/enterprise/client_certificates/core/win/windows_software_private_key_factory.cc
@@ -0,0 +1,133 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/enterprise/client_certificates/core/win/windows_software_private_key_factory.h" + +#include <array> +#include <optional> +#include <utility> +#include <vector> + +#include "base/base64.h" +#include "base/check.h" +#include "base/functional/bind.h" +#include "base/location.h" +#include "base/memory/ptr_util.h" +#include "base/task/task_traits.h" +#include "base/task/thread_pool.h" +#include "components/enterprise/client_certificates/core/constants.h" +#include "components/enterprise/client_certificates/core/private_key.h" +#include "components/enterprise/client_certificates/core/private_key_types.h" +#include "components/enterprise/client_certificates/core/unexportable_private_key.h" +#include "crypto/unexportable_key.h" +#include "net/ssl/ssl_private_key.h" + +namespace client_certificates { + +namespace { + +scoped_refptr<UnexportablePrivateKey> CreateKey() { + auto provider = crypto::GetMicrosoftSoftwareUnexportableKeyProvider(); + if (!provider) { + return nullptr; + } + + static constexpr std::array<crypto::SignatureVerifier::SignatureAlgorithm, 2> + kAcceptableAlgorithms = {crypto::SignatureVerifier::ECDSA_SHA256, + crypto::SignatureVerifier::RSA_PKCS1_SHA256}; + auto key = provider->GenerateSigningKeySlowly(kAcceptableAlgorithms); + + if (!key) { + return nullptr; + } + + return base::MakeRefCounted<UnexportablePrivateKey>( + std::move(key), PrivateKeySource::kOsSoftwareKey); +} + +scoped_refptr<UnexportablePrivateKey> LoadKeyFromWrapped( + const std::vector<uint8_t>& wrapped_key) { + auto provider = crypto::GetMicrosoftSoftwareUnexportableKeyProvider(); + if (!provider) { + return nullptr; + } + + auto key = provider->FromWrappedSigningKeySlowly(wrapped_key); + if (!key) { + return nullptr; + } + + return base::MakeRefCounted<UnexportablePrivateKey>( + std::move(key), PrivateKeySource::kOsSoftwareKey); +} + +} // namespace + +// static +std::unique_ptr<WindowsSoftwarePrivateKeyFactory> +WindowsSoftwarePrivateKeyFactory::TryCreate() { + auto provider = crypto::GetMicrosoftSoftwareUnexportableKeyProvider(); + + if (!provider) { + // OS software keys are not supported. + return nullptr; + } + + return base::WrapUnique<WindowsSoftwarePrivateKeyFactory>( + new WindowsSoftwarePrivateKeyFactory()); +} + +WindowsSoftwarePrivateKeyFactory::WindowsSoftwarePrivateKeyFactory() = default; + +WindowsSoftwarePrivateKeyFactory::~WindowsSoftwarePrivateKeyFactory() = default; + +void WindowsSoftwarePrivateKeyFactory::CreatePrivateKey( + PrivateKeyCallback callback) { + base::ThreadPool::PostTaskAndReplyWithResult(FROM_HERE, {base::MayBlock()}, + base::BindOnce(CreateKey), + std::move(callback)); +} + +void WindowsSoftwarePrivateKeyFactory::LoadPrivateKey( + const client_certificates_pb::PrivateKey& serialized_private_key, + PrivateKeyCallback callback) { + auto private_key_source = ToPrivateKeySource(serialized_private_key.source()); + CHECK(private_key_source.has_value()); + CHECK(private_key_source.value() == PrivateKeySource::kOsSoftwareKey); + + const auto& wrapped_key_str = serialized_private_key.wrapped_key(); + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce( + LoadKeyFromWrapped, + std::vector<uint8_t>(wrapped_key_str.begin(), wrapped_key_str.end())), + std::move(callback)); +} + +void WindowsSoftwarePrivateKeyFactory::LoadPrivateKeyFromDict( + const base::Value::Dict& serialized_private_key, + PrivateKeyCallback callback) { + std::optional<int> source = serialized_private_key.FindInt(kKeySource); + auto* encoded_wrapped_private_key = serialized_private_key.FindString(kKey); + + // Supposed to have been already checked by the parent factory. + CHECK(source); + auto source_enum = ToPrivateKeySource(source.value()); + CHECK(source_enum); + + CHECK(encoded_wrapped_private_key); + std::string decoded_wrapped_private_key; + if (!base::Base64Decode(*encoded_wrapped_private_key, + &decoded_wrapped_private_key)) { + std::move(callback).Run(nullptr); + return; + } + + client_certificates_pb::PrivateKey private_key_proto; + private_key_proto.set_source(ToProtoKeySource(source_enum.value())); + private_key_proto.set_wrapped_key(std::move(decoded_wrapped_private_key)); + LoadPrivateKey(private_key_proto, std::move(callback)); +} + +} // namespace client_certificates
diff --git a/components/enterprise/client_certificates/core/win/windows_software_private_key_factory.h b/components/enterprise/client_certificates/core/win/windows_software_private_key_factory.h new file mode 100644 index 0000000..1447960 --- /dev/null +++ b/components/enterprise/client_certificates/core/win/windows_software_private_key_factory.h
@@ -0,0 +1,41 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_ENTERPRISE_CLIENT_CERTIFICATES_CORE_WIN_WINDOWS_SOFTWARE_PRIVATE_KEY_FACTORY_H_ +#define COMPONENTS_ENTERPRISE_CLIENT_CERTIFICATES_CORE_WIN_WINDOWS_SOFTWARE_PRIVATE_KEY_FACTORY_H_ + +#include <memory> + +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "components/enterprise/client_certificates/core/private_key_factory.h" + +namespace client_certificates { + +class WindowsSoftwarePrivateKeyFactory : public PrivateKeyFactory { + public: + // Will return a factory instance only if the creation of + // software keys via the OS is supported on the current device. + // Otherwise, will return nullptr. + static std::unique_ptr<WindowsSoftwarePrivateKeyFactory> TryCreate(); + + ~WindowsSoftwarePrivateKeyFactory() override; + + // PrivateKeyFactory: + void CreatePrivateKey(PrivateKeyCallback callback) override; + void LoadPrivateKey( + const client_certificates_pb::PrivateKey& serialized_private_key, + PrivateKeyCallback callback) override; + void LoadPrivateKeyFromDict(const base::Value::Dict& serialized_private_key, + PrivateKeyCallback callback) override; + + private: + WindowsSoftwarePrivateKeyFactory(); + + base::WeakPtrFactory<WindowsSoftwarePrivateKeyFactory> weak_factory_{this}; +}; + +} // namespace client_certificates + +#endif // COMPONENTS_ENTERPRISE_CLIENT_CERTIFICATES_CORE_WIN_WINDOWS_SOFTWARE_PRIVATE_KEY_FACTORY_H_
diff --git a/components/enterprise/client_certificates/core/win/windows_software_private_key_factory_unittest.cc b/components/enterprise/client_certificates/core/win/windows_software_private_key_factory_unittest.cc new file mode 100644 index 0000000..3f1c5da --- /dev/null +++ b/components/enterprise/client_certificates/core/win/windows_software_private_key_factory_unittest.cc
@@ -0,0 +1,92 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/enterprise/client_certificates/core/win/windows_software_private_key_factory.h" + +#include "base/memory/scoped_refptr.h" +#include "base/test/task_environment.h" +#include "base/test/test_future.h" +#include "components/enterprise/client_certificates/core/constants.h" +#include "components/enterprise/client_certificates/core/private_key.h" +#include "components/enterprise/client_certificates/core/private_key_types.h" +#include "components/enterprise/client_certificates/core/scoped_ssl_key_converter.h" +#include "net/ssl/ssl_private_key.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace client_certificates { + +namespace { + +void ValidatePrivateKey(scoped_refptr<PrivateKey> key, + scoped_refptr<PrivateKey> loaded_key) { + ASSERT_TRUE(loaded_key); + EXPECT_NE(key, loaded_key); + EXPECT_EQ(key->GetAlgorithm(), loaded_key->GetAlgorithm()); + EXPECT_EQ(key->GetSource(), loaded_key->GetSource()); + EXPECT_EQ(key->GetSource(), PrivateKeySource::kOsSoftwareKey); + ASSERT_THAT(key->GetSubjectPublicKeyInfo(), + testing::ElementsAreArray(loaded_key->GetSubjectPublicKeyInfo())); + ASSERT_TRUE(key->GetSSLPrivateKey()); +} + +} // namespace + +TEST(WindowsSoftwarePrivateKeyFactoryTest, SupportedCreateKey_LoadKey) { + base::test::TaskEnvironment task_environment; + ScopedSSLKeyConverter scoped_converter; + + auto factory = WindowsSoftwarePrivateKeyFactory::TryCreate(); + + ASSERT_TRUE(factory); + + base::test::TestFuture<scoped_refptr<PrivateKey>> create_key_future; + factory->CreatePrivateKey(create_key_future.GetCallback()); + + auto private_key = create_key_future.Get(); + ASSERT_TRUE(private_key); + + base::test::TestFuture<scoped_refptr<PrivateKey>> load_key_future; + auto proto_key = private_key->ToProto(); + factory->LoadPrivateKey(std::move(proto_key), load_key_future.GetCallback()); + ValidatePrivateKey(private_key, load_key_future.Get()); +} + +TEST(WindowsSoftwarePrivateKeyFactoryTest, SupportedCreateKey_LoadKeyFromDict) { + base::test::TaskEnvironment task_environment; + ScopedSSLKeyConverter scoped_converter; + + auto factory = WindowsSoftwarePrivateKeyFactory::TryCreate(); + + ASSERT_TRUE(factory); + + base::test::TestFuture<scoped_refptr<PrivateKey>> create_key_future; + factory->CreatePrivateKey(create_key_future.GetCallback()); + + auto private_key = create_key_future.Get(); + ASSERT_TRUE(private_key); + + base::test::TestFuture<scoped_refptr<PrivateKey>> load_key_future; + auto dict_key = private_key->ToDict(); + factory->LoadPrivateKeyFromDict(dict_key, load_key_future.GetCallback()); + ValidatePrivateKey(private_key, load_key_future.Get()); + + base::test::TestFuture<scoped_refptr<PrivateKey>> + load_key_fails_future_invalid_key; + dict_key.Set(kKey, ""); + dict_key.Set(kKeySource, static_cast<int>(PrivateKeySource::kOsSoftwareKey)); + factory->LoadPrivateKeyFromDict( + dict_key, load_key_fails_future_invalid_key.GetCallback()); + EXPECT_FALSE(load_key_fails_future_invalid_key.Get()); +} + +TEST(WindowsSoftwarePrivateKeyFactoryTest, UnsupportedCreateKey) { + ScopedSSLKeyConverter scoped_converter(/*supports_unexportable=*/false); + + auto factory = WindowsSoftwarePrivateKeyFactory::TryCreate(); + + EXPECT_FALSE(factory); +} + +} // namespace client_certificates
diff --git a/components/enterprise/client_certificates/proto/client_certificates_database.proto b/components/enterprise/client_certificates/proto/client_certificates_database.proto index de8c64e9..c7da767 100644 --- a/components/enterprise/client_certificates/proto/client_certificates_database.proto +++ b/components/enterprise/client_certificates/proto/client_certificates_database.proto
@@ -16,6 +16,8 @@ PRIVATE_UNEXPORTABLE_KEY = 1; // Chrome Browser with the key stored at OS level. PRIVATE_SOFTWARE_KEY = 2; + // Chrome Browser with the key stored in OS key storage. + PRIVATE_OS_SOFTWARE_KEY = 3; } // Represents the source of the private key, which will dictate how
diff --git a/components/neterror/resources/BUILD.gn b/components/neterror/resources/BUILD.gn index c3c4cf66..b265794 100644 --- a/components/neterror/resources/BUILD.gn +++ b/components/neterror/resources/BUILD.gn
@@ -15,7 +15,7 @@ "dino_game/cloud.ts", "dino_game/constants.ts", "dino_game/dimensions.ts", - "dino_game/distance_meter.js", + "dino_game/distance_meter.ts", "dino_game/generated_sound_fx.ts", "dino_game/game_over_panel.js", "dino_game/horizon_line.ts",
diff --git a/components/neterror/resources/dino_game/distance_meter.js b/components/neterror/resources/dino_game/distance_meter.js deleted file mode 100644 index 10046a7ca..0000000 --- a/components/neterror/resources/dino_game/distance_meter.js +++ /dev/null
@@ -1,418 +0,0 @@ -// Copyright 2024 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {IS_HIDPI, IS_RTL} from './constants.js'; -import {Runner} from './offline.js'; -import {getTimeStamp} from './utils.js'; - -export class DistanceMeter { - /** - * Handles displaying the distance meter. - * @param {!HTMLCanvasElement} canvas - * @param {Object} spritePos Image position in sprite. - * @param {number} canvasWidth - */ - constructor(canvas, spritePos, canvasWidth) { - this.canvas = canvas; - this.canvasCtx = - /** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d')); - this.image = Runner.imageSprite; - this.spritePos = spritePos; - this.x = 0; - this.y = 5; - - this.currentDistance = 0; - this.maxScore = 0; - this.highScore = '0'; - this.container = null; - - this.digits = []; - this.achievement = false; - this.defaultString = ''; - this.flashTimer = 0; - this.flashIterations = 0; - this.invertTrigger = false; - this.flashingRafId = null; - this.highScoreBounds = {}; - this.highScoreFlashing = false; - - this.config = DistanceMeter.config; - this.maxScoreUnits = this.config.MAX_DISTANCE_UNITS; - this.canvasWidth = canvasWidth; - this.init(canvasWidth); - } - - - /** - * Initialise the distance meter to '00000'. - * @param {number} width Canvas width in px. - */ - init(width) { - let maxDistanceStr = ''; - - this.calcXPos(width); - this.maxScore = this.maxScoreUnits; - for (let i = 0; i < this.maxScoreUnits; i++) { - this.draw(i, 0); - this.defaultString += '0'; - maxDistanceStr += '9'; - } - - this.maxScore = parseInt(maxDistanceStr, 10); - } - - /** - * Calculate the xPos in the canvas. - * @param {number} canvasWidth - */ - calcXPos(canvasWidth) { - this.x = canvasWidth - - (DistanceMeter.dimensions.DEST_WIDTH * (this.maxScoreUnits + 1)); - } - - /** - * Draw a digit to canvas. - * @param {number} digitPos Position of the digit. - * @param {number} value Digit value 0-9. - * @param {boolean=} opt_highScore Whether drawing the high score. - */ - draw(digitPos, value, opt_highScore) { - let sourceWidth = DistanceMeter.dimensions.WIDTH; - let sourceHeight = DistanceMeter.dimensions.HEIGHT; - let sourceX = DistanceMeter.dimensions.WIDTH * value; - let sourceY = 0; - - const targetX = digitPos * DistanceMeter.dimensions.DEST_WIDTH; - const targetY = this.y; - const targetWidth = DistanceMeter.dimensions.WIDTH; - const targetHeight = DistanceMeter.dimensions.HEIGHT; - - // For high DPI we 2x source values. - if (IS_HIDPI) { - sourceWidth *= 2; - sourceHeight *= 2; - sourceX *= 2; - } - - sourceX += this.spritePos.x; - sourceY += this.spritePos.y; - - this.canvasCtx.save(); - - if (IS_RTL) { - if (opt_highScore) { - this.canvasCtx.translate( - this.canvasWidth - - (DistanceMeter.dimensions.WIDTH * (this.maxScoreUnits + 3)), - this.y); - } else { - this.canvasCtx.translate( - this.canvasWidth - DistanceMeter.dimensions.WIDTH, this.y); - } - this.canvasCtx.scale(-1, 1); - } else { - const highScoreX = - this.x - (this.maxScoreUnits * 2) * DistanceMeter.dimensions.WIDTH; - if (opt_highScore) { - this.canvasCtx.translate(highScoreX, this.y); - } else { - this.canvasCtx.translate(this.x, this.y); - } - } - - this.canvasCtx.drawImage( - this.image, - sourceX, - sourceY, - sourceWidth, - sourceHeight, - targetX, - targetY, - targetWidth, - targetHeight, - ); - - this.canvasCtx.restore(); - } - - /** - * Covert pixel distance to a 'real' distance. - * @param {number} distance Pixel distance ran. - * @return {number} The 'real' distance ran. - */ - getActualDistance(distance) { - return distance ? Math.round(distance * this.config.COEFFICIENT) : 0; - } - - /** - * Update the distance meter. - * @param {number} distance - * @param {number} deltaTime - * @return {boolean} Whether the achievement sound fx should be played. - */ - update(deltaTime, distance) { - let paint = true; - let playSound = false; - - if (!this.achievement) { - distance = this.getActualDistance(distance); - // Score has gone beyond the initial digit count. - if (distance > this.maxScore && - this.maxScoreUnits === this.config.MAX_DISTANCE_UNITS) { - this.maxScoreUnits++; - this.maxScore = parseInt(this.maxScore + '9', 10); - } else { - this.distance = 0; - } - - if (distance > 0) { - // Achievement unlocked. - if (distance % this.config.ACHIEVEMENT_DISTANCE === 0) { - // Flash score and play sound. - this.achievement = true; - this.flashTimer = 0; - playSound = true; - } - - // Create a string representation of the distance with leading 0. - const distanceStr = - (this.defaultString + distance).substr(-this.maxScoreUnits); - this.digits = distanceStr.split(''); - } else { - this.digits = this.defaultString.split(''); - } - } else { - // Control flashing of the score on reaching achievement. - if (this.flashIterations <= this.config.FLASH_ITERATIONS) { - this.flashTimer += deltaTime; - - if (this.flashTimer < this.config.FLASH_DURATION) { - paint = false; - } else if (this.flashTimer > this.config.FLASH_DURATION * 2) { - this.flashTimer = 0; - this.flashIterations++; - } - } else { - this.achievement = false; - this.flashIterations = 0; - this.flashTimer = 0; - } - } - - // Draw the digits if not flashing. - if (paint) { - for (let i = this.digits.length - 1; i >= 0; i--) { - this.draw(i, parseInt(this.digits[i], 10)); - } - } - - this.drawHighScore(); - return playSound; - } - - /** - * Draw the high score. - */ - drawHighScore() { - if (parseInt(this.highScore, 10) > 0) { - this.canvasCtx.save(); - this.canvasCtx.globalAlpha = .8; - for (let i = this.highScore.length - 1; i >= 0; i--) { - this.draw(i, parseInt(this.highScore[i], 10), true); - } - this.canvasCtx.restore(); - } - } - - /** - * Set the highscore as a array string. - * Position of char in the sprite: H - 10, I - 11. - * @param {number} distance Distance ran in pixels. - */ - setHighScore(distance) { - distance = this.getActualDistance(distance); - const highScoreStr = - (this.defaultString + distance).substr(-this.maxScoreUnits); - - this.highScore = ['10', '11', ''].concat(highScoreStr.split('')); - } - - - /** - * Whether a clicked is in the high score area. - * @param {Event} e Event object. - * @return {boolean} Whether the click was in the high score bounds. - */ - hasClickedOnHighScore(e) { - let x = 0; - let y = 0; - - if (e.touches) { - // Bounds for touch differ from pointer. - const canvasBounds = this.canvas.getBoundingClientRect(); - x = e.touches[0].clientX - canvasBounds.left; - y = e.touches[0].clientY - canvasBounds.top; - } else { - x = e.offsetX; - y = e.offsetY; - } - - this.highScoreBounds = this.getHighScoreBounds(); - return x >= this.highScoreBounds.x && - x <= this.highScoreBounds.x + this.highScoreBounds.width && - y >= this.highScoreBounds.y && - y <= this.highScoreBounds.y + this.highScoreBounds.height; - } - - /** - * Get the bounding box for the high score. - * @return {Object} Object with x, y, width and height properties. - */ - getHighScoreBounds() { - return { - x: (this.x - (this.maxScoreUnits * 2) * DistanceMeter.dimensions.WIDTH) - - DistanceMeter.config.HIGH_SCORE_HIT_AREA_PADDING, - y: this.y, - width: DistanceMeter.dimensions.WIDTH * (this.highScore.length + 1) + - DistanceMeter.config.HIGH_SCORE_HIT_AREA_PADDING, - height: DistanceMeter.dimensions.HEIGHT + - (DistanceMeter.config.HIGH_SCORE_HIT_AREA_PADDING * 2), - }; - } - - /** - * Animate flashing the high score to indicate ready for resetting. - * The flashing stops following this.config.FLASH_ITERATIONS x 2 flashes. - */ - flashHighScore() { - const now = getTimeStamp(); - const deltaTime = now - (this.frameTimeStamp || now); - let paint = true; - this.frameTimeStamp = now; - - // Reached the max number of flashes. - if (this.flashIterations > this.config.FLASH_ITERATIONS * 2) { - this.cancelHighScoreFlashing(); - return; - } - - this.flashTimer += deltaTime; - - if (this.flashTimer < this.config.FLASH_DURATION) { - paint = false; - } else if (this.flashTimer > this.config.FLASH_DURATION * 2) { - this.flashTimer = 0; - this.flashIterations++; - } - - if (paint) { - this.drawHighScore(); - } else { - this.clearHighScoreBounds(); - } - // Frame update. - this.flashingRafId = requestAnimationFrame(this.flashHighScore.bind(this)); - } - - /** - * Draw empty rectangle over high score. - */ - clearHighScoreBounds() { - this.canvasCtx.save(); - this.canvasCtx.fillStyle = '#fff'; - this.canvasCtx.rect( - this.highScoreBounds.x, this.highScoreBounds.y, - this.highScoreBounds.width, this.highScoreBounds.height); - this.canvasCtx.fill(); - this.canvasCtx.restore(); - } - - /** - * Starts the flashing of the high score. - */ - startHighScoreFlashing() { - this.highScoreFlashing = true; - this.flashHighScore(); - } - - /** - * Whether high score is flashing. - * @return {boolean} - */ - isHighScoreFlashing() { - return this.highScoreFlashing; - } - - /** - * Stop flashing the high score. - */ - cancelHighScoreFlashing() { - if (this.flashingRafId) { - cancelAnimationFrame(this.flashingRafId); - } - this.flashIterations = 0; - this.flashTimer = 0; - this.highScoreFlashing = false; - this.clearHighScoreBounds(); - this.drawHighScore(); - } - - /** - * Clear the high score. - */ - resetHighScore() { - this.setHighScore(0); - this.cancelHighScoreFlashing(); - } - - /** - * Reset the distance meter back to '00000'. - */ - reset() { - this.update(0, 0); - this.achievement = false; - } -} - -/** - * @enum {number} - */ -DistanceMeter.dimensions = { - WIDTH: 10, - HEIGHT: 13, - DEST_WIDTH: 11, -}; - - -/** - * Y positioning of the digits in the sprite sheet. - * X position is always 0. - * @type {Array<number>} - */ -DistanceMeter.yPos = [0, 13, 27, 40, 53, 67, 80, 93, 107, 120]; - - -/** - * Distance meter config. - * @enum {number} - */ -DistanceMeter.config = { - // Number of digits. - MAX_DISTANCE_UNITS: 5, - - // Distance that causes achievement animation. - ACHIEVEMENT_DISTANCE: 100, - - // Used for conversion from pixel distance to a scaled unit. - COEFFICIENT: 0.025, - - // Flash duration in milliseconds. - FLASH_DURATION: 1000 / 4, - - // Flash iterations for achievement animation. - FLASH_ITERATIONS: 3, - - // Padding around the high score hit area. - HIGH_SCORE_HIT_AREA_PADDING: 4, -}; \ No newline at end of file
diff --git a/components/neterror/resources/dino_game/distance_meter.ts b/components/neterror/resources/dino_game/distance_meter.ts new file mode 100644 index 0000000..41d6f7b --- /dev/null +++ b/components/neterror/resources/dino_game/distance_meter.ts
@@ -0,0 +1,416 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {assert} from 'chrome://resources/js/assert.js'; + +import {IS_HIDPI, IS_RTL} from './constants.js'; +import type {CollisionBox} from './offline_sprite_definitions.js'; +import type {SpritePosition} from './sprite_position.js'; +import {getRunnerImageSprite, getTimeStamp} from './utils.js'; + +/** + * Dimensions of each individual character in pixels. + */ +enum Dimensions { + WIDTH = 10, + HEIGHT = 13, + DEST_WIDTH = 11, +} + +/** + * Distance meter config. + */ +enum Config { + // Number of digits. + MAX_DISTANCE_UNITS = 5, + + // Distance that causes achievement animation. + ACHIEVEMENT_DISTANCE = 100, + + // Used for conversion from pixel distance to a scaled unit. + COEFFICIENT = 0.025, + + // Flash duration in milliseconds. + FLASH_DURATION = 1000 / 4, + + // Flash iterations for achievement animation. + FLASH_ITERATIONS = 3, + + // Padding around the high score hit area. + HIGH_SCORE_HIT_AREA_PADDING = 4, +} + +export class DistanceMeter { + achievement: boolean = false; + + private canvas: HTMLCanvasElement; + private canvasCtx: CanvasRenderingContext2D; + private image: CanvasImageSource; + private spritePos: SpritePosition; + private x: number = 0; + private y: number = 5; + private maxScore: number = 0; + private highScore: string = '0'; + private digits: string[] = []; + private defaultString: string = ''; + private flashTimer: number = 0; + private flashIterations: number = 0; + private flashingRafId: number|null = null; + private highScoreBounds: CollisionBox|null = null; + private highScoreFlashing: boolean = false; + private maxScoreUnits: number = Config.MAX_DISTANCE_UNITS; + private canvasWidth: number; + private frameTimeStamp?: number; + + /** + * Handles displaying the distance meter. + */ + constructor( + canvas: HTMLCanvasElement, spritePos: SpritePosition, + canvasWidth: number) { + this.canvas = canvas; + const canvasContext = canvas.getContext('2d'); + assert(canvasContext); + this.canvasCtx = canvasContext; + const runnerImageSprite = getRunnerImageSprite(); + assert(runnerImageSprite); + this.image = runnerImageSprite; + this.spritePos = spritePos; + + this.canvasWidth = canvasWidth; + this.init(canvasWidth); + } + + + /** + * Initialise the distance meter to '00000'. + * @param width Canvas width in px. + */ + private init(width: number) { + let maxDistanceStr = ''; + + this.calcXpos(width); + this.maxScore = this.maxScoreUnits; + for (let i = 0; i < this.maxScoreUnits; i++) { + this.draw(i, 0); + this.defaultString += '0'; + maxDistanceStr += '9'; + } + + this.maxScore = parseInt(maxDistanceStr, 10); + } + + /** + * Calculate the xPos in the canvas. + */ + calcXpos(canvasWidth: number) { + this.x = canvasWidth - (Dimensions.DEST_WIDTH * (this.maxScoreUnits + 1)); + } + + /** + * Draw a digit to canvas. + * @param digitPos Position of the digit. + * @param value Digit value 0-9. + * @param highScore Whether drawing the high score. + */ + private draw(digitPos: number, value: number, highScore?: boolean) { + let sourceWidth = Dimensions.WIDTH; + let sourceHeight = Dimensions.HEIGHT; + let sourceX = Dimensions.WIDTH * value; + let sourceY = 0; + + const targetX = digitPos * Dimensions.DEST_WIDTH; + const targetY = this.y; + const targetWidth = Dimensions.WIDTH; + const targetHeight = Dimensions.HEIGHT; + + // For high DPI we 2x source values. + if (IS_HIDPI) { + sourceWidth *= 2; + sourceHeight *= 2; + sourceX *= 2; + } + + sourceX += this.spritePos.x; + sourceY += this.spritePos.y; + + this.canvasCtx.save(); + + if (IS_RTL) { + const translateX = highScore ? + this.canvasWidth - (Dimensions.WIDTH * (this.maxScoreUnits + 3)) : + this.canvasWidth - Dimensions.WIDTH; + this.canvasCtx.translate(translateX, this.y); + this.canvasCtx.scale(-1, 1); + } else { + const highScoreX = this.x - (this.maxScoreUnits * 2) * Dimensions.WIDTH; + this.canvasCtx.translate(highScore ? highScoreX : this.x, this.y); + } + + this.canvasCtx.drawImage( + this.image, + sourceX, + sourceY, + sourceWidth, + sourceHeight, + targetX, + targetY, + targetWidth, + targetHeight, + ); + + this.canvasCtx.restore(); + } + + /** + * Covert pixel distance to a 'real' distance. + * @param distance Pixel distance ran. + * @return The 'real' distance ran. + */ + getActualDistance(distance: number): number { + return distance ? Math.round(distance * Config.COEFFICIENT) : 0; + } + + /** + * Update the distance meter. + * @return Whether the achievement sound fx should be played. + */ + update(deltaTime: number, distance: number): boolean { + let paint = true; + let playSound = false; + + if (!this.achievement) { + distance = this.getActualDistance(distance); + // Score has gone beyond the initial digit count. + if (distance > this.maxScore && + this.maxScoreUnits === Config.MAX_DISTANCE_UNITS) { + this.maxScoreUnits++; + this.maxScore = parseInt(this.maxScore + '9', 10); + } + + if (distance > 0) { + // Achievement unlocked. + if (distance % Config.ACHIEVEMENT_DISTANCE === 0) { + // Flash score and play sound. + this.achievement = true; + this.flashTimer = 0; + playSound = true; + } + + // Create a string representation of the distance with leading 0. + const distanceStr = + (this.defaultString + distance).substr(-this.maxScoreUnits); + this.digits = distanceStr.split(''); + } else { + this.digits = this.defaultString.split(''); + } + } else { + // Control flashing of the score on reaching achievement. + if (this.flashIterations <= Config.FLASH_ITERATIONS) { + this.flashTimer += deltaTime; + + if (this.flashTimer < Config.FLASH_DURATION) { + paint = false; + } else if (this.flashTimer > Config.FLASH_DURATION * 2) { + this.flashTimer = 0; + this.flashIterations++; + } + } else { + this.achievement = false; + this.flashIterations = 0; + this.flashTimer = 0; + } + } + + // Draw the digits if not flashing. + if (paint) { + for (let i = this.digits.length - 1; i >= 0; i--) { + this.draw(i, parseInt(this.digits[i]!, 10)); + } + } + + this.drawHighScore(); + return playSound; + } + + /** + * Draw the high score. + */ + private drawHighScore() { + if (this.highScore.length > 0) { + this.canvasCtx.save(); + this.canvasCtx.globalAlpha = .8; + for (let i = this.highScore.length - 1; i >= 0; i--) { + const characterToDraw = this.highScore[i]!; + // Position of characterToDraw in sprite sheet, digits 0-9 are mapped + // directly. + let characterSpritePosition = parseInt(characterToDraw, 10); + // If characterToDraw is not a digit then they must be part of the label + // "HI". The position of these characters in the sheet is: H - 10, I + // - 11. + if (isNaN(characterSpritePosition)) { + switch (characterToDraw) { + case 'H': + characterSpritePosition = 10; + break; + case 'I': + characterSpritePosition = 11; + break; + // Any other character is ignored. + default: + continue; + } + } + this.draw(i, characterSpritePosition, true); + } + this.canvasCtx.restore(); + } + } + + /** + * Set the highscore as a string. + * @param distance Distance ran in pixels. + */ + setHighScore(distance: number) { + distance = this.getActualDistance(distance); + const highScoreStr = + (this.defaultString + distance).substr(-this.maxScoreUnits); + + this.highScore = 'HI ' + highScoreStr; + } + + + /** + * Whether a clicked is in the high score area. + * @return Whether the click was in the high score bounds. + */ + hasClickedOnHighScore(e: TouchEvent|MouseEvent): boolean { + let x = 0; + let y = 0; + + if (e instanceof TouchEvent) { + // Bounds for touch differ from pointer. + const canvasBounds = this.canvas.getBoundingClientRect(); + x = e.touches[0]!.clientX - canvasBounds.left; + y = e.touches[0]!.clientY - canvasBounds.top; + } else { + x = e.offsetX; + y = e.offsetY; + } + + this.highScoreBounds = this.getHighScoreBounds(); + return x >= this.highScoreBounds.x && + x <= this.highScoreBounds.x + this.highScoreBounds.width && + y >= this.highScoreBounds.y && + y <= this.highScoreBounds.y + this.highScoreBounds.height; + } + + /** + * Get the bounding box for the high score. + */ + private getHighScoreBounds(): CollisionBox { + return { + x: (this.x - (this.maxScoreUnits * 2) * Dimensions.WIDTH) - + Config.HIGH_SCORE_HIT_AREA_PADDING, + y: this.y, + width: Dimensions.WIDTH * (this.highScore.length + 1) + + Config.HIGH_SCORE_HIT_AREA_PADDING, + height: Dimensions.HEIGHT + (Config.HIGH_SCORE_HIT_AREA_PADDING * 2), + }; + } + + /** + * Animate flashing the high score to indicate ready for resetting. + * The flashing stops following distanceMeterConfig.FLASH_ITERATIONS x 2 + * flashes. + */ + private flashHighScore() { + const now = getTimeStamp(); + const deltaTime = now - (this.frameTimeStamp || now); + let paint = true; + this.frameTimeStamp = now; + + // Reached the max number of flashes. + if (this.flashIterations > Config.FLASH_ITERATIONS * 2) { + this.cancelHighScoreFlashing(); + return; + } + + this.flashTimer += deltaTime; + + if (this.flashTimer < Config.FLASH_DURATION) { + paint = false; + } else if (this.flashTimer > Config.FLASH_DURATION * 2) { + this.flashTimer = 0; + this.flashIterations++; + } + + if (paint) { + this.drawHighScore(); + } else { + this.clearHighScoreBounds(); + } + // Frame update. + this.flashingRafId = requestAnimationFrame(this.flashHighScore.bind(this)); + } + + /** + * Draw empty rectangle over high score. + */ + private clearHighScoreBounds() { + assert(this.highScoreBounds); + this.canvasCtx.save(); + this.canvasCtx.fillStyle = '#fff'; + this.canvasCtx.rect( + this.highScoreBounds.x, this.highScoreBounds.y, + this.highScoreBounds.width, this.highScoreBounds.height); + this.canvasCtx.fill(); + this.canvasCtx.restore(); + } + + /** + * Starts the flashing of the high score. + */ + startHighScoreFlashing() { + this.highScoreFlashing = true; + this.flashHighScore(); + } + + /** + * Whether high score is flashing. + */ + isHighScoreFlashing(): boolean { + return this.highScoreFlashing; + } + + /** + * Stop flashing the high score. + */ + cancelHighScoreFlashing() { + if (this.flashingRafId) { + cancelAnimationFrame(this.flashingRafId); + } + this.flashIterations = 0; + this.flashTimer = 0; + this.highScoreFlashing = false; + this.clearHighScoreBounds(); + this.drawHighScore(); + } + + /** + * Clear the high score. + */ + resetHighScore() { + this.setHighScore(0); + this.cancelHighScoreFlashing(); + } + + /** + * Reset the distance meter back to '00000'. + */ + reset() { + this.update(0, 0); + this.achievement = false; + } +}
diff --git a/components/omnibox/browser/autocomplete_provider_client.cc b/components/omnibox/browser/autocomplete_provider_client.cc index 55928b4..a0c5423 100644 --- a/components/omnibox/browser/autocomplete_provider_client.cc +++ b/components/omnibox/browser/autocomplete_provider_client.cc
@@ -45,6 +45,10 @@ return false; } +bool AutocompleteProviderClient::IsLensEnabled() const { + return false; +} + bool AutocompleteProviderClient::in_background_state() const { return false; }
diff --git a/components/omnibox/browser/autocomplete_provider_client.h b/components/omnibox/browser/autocomplete_provider_client.h index ce250bfe..c0f3785 100644 --- a/components/omnibox/browser/autocomplete_provider_client.h +++ b/components/omnibox/browser/autocomplete_provider_client.h
@@ -217,6 +217,9 @@ // Returns true if history embeddings is enabled and user can opt in/out. virtual bool IsHistoryEmbeddingsSettingVisible() const; + // Returns true if the current profile is eligible for Lens. + virtual bool IsLensEnabled() const; + // Returns whether the app is currently in the background state (Mobile only). virtual bool in_background_state() const;
diff --git a/components/omnibox/browser/contextual_search_provider.cc b/components/omnibox/browser/contextual_search_provider.cc index bcad740..8dbf6636 100644 --- a/components/omnibox/browser/contextual_search_provider.cc +++ b/components/omnibox/browser/contextual_search_provider.cc
@@ -105,7 +105,8 @@ if (omnibox::IsOtherWebPage(input.current_page_classification()) && input.current_url().SchemeIsHTTPOrHTTPS() && (input.IsZeroSuggest() || - input.type() == metrics::OmniboxInputType::EMPTY)) { + input.type() == metrics::OmniboxInputType::EMPTY) && + client()->IsLensEnabled()) { AddPageSearchActionMatches(input); } return;
diff --git a/components/omnibox/browser/contextual_search_provider_unittest.cc b/components/omnibox/browser/contextual_search_provider_unittest.cc index 384797e..f815bab 100644 --- a/components/omnibox/browser/contextual_search_provider_unittest.cc +++ b/components/omnibox/browser/contextual_search_provider_unittest.cc
@@ -46,6 +46,8 @@ return !!match.takeover_action; }); }; + EXPECT_CALL(*client_, IsLensEnabled()).WillRepeatedly(testing::Return(true)); + { AutocompleteInput input(u"nonempty input text", metrics::OmniboxEventProto::OTHER, @@ -74,4 +76,15 @@ EXPECT_TRUE(provider_->done()); EXPECT_FALSE(has_actions()); } + // Lens action missing if Lens is disabled. + { + EXPECT_CALL(*client_, IsLensEnabled()).WillOnce(testing::Return(false)); + AutocompleteInput input(u"", metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + input.set_current_url(GURL("https://example.com")); + input.set_focus_type(metrics::OmniboxFocusType::INTERACTION_FOCUS); + provider_->Start(input, false); + EXPECT_TRUE(provider_->done()); + EXPECT_FALSE(has_actions()); + } }
diff --git a/components/omnibox/browser/mock_autocomplete_provider_client.h b/components/omnibox/browser/mock_autocomplete_provider_client.h index 19c6d8e..d2ebc3b1a9 100644 --- a/components/omnibox/browser/mock_autocomplete_provider_client.h +++ b/components/omnibox/browser/mock_autocomplete_provider_client.h
@@ -151,6 +151,7 @@ MOCK_CONST_METHOD0(IsSyncActive, bool()); MOCK_CONST_METHOD0(IsHistoryEmbeddingsEnabled, bool()); MOCK_CONST_METHOD0(IsHistoryEmbeddingsSettingVisible, bool()); + MOCK_CONST_METHOD0(IsLensEnabled, bool()); MOCK_CONST_METHOD1(GetLensSuggestInputsWhenReady, base::CallbackListSubscription( LensOverlaySuggestInputsCallback callback));
diff --git a/components/omnibox/browser/zero_suggest_provider.cc b/components/omnibox/browser/zero_suggest_provider.cc index 2284d21..937060b 100644 --- a/components/omnibox/browser/zero_suggest_provider.cc +++ b/components/omnibox/browser/zero_suggest_provider.cc
@@ -287,7 +287,13 @@ } void MaybeAddContextualUrlSuggestParam( + const AutocompleteProviderClient* client, TemplateURLRef::SearchTermsArgs& search_terms_args) { + // Do not add the contextual URL suggest param if Lens is not enabled to + // fulfill the suggestion. + if (!client->IsLensEnabled()) { + return; + } if (!search_terms_args.current_page_url.empty() && omnibox::IsOtherWebPage(search_terms_args.page_classification)) { std::string_view contextual_url_suggest_param = @@ -427,7 +433,7 @@ : std::string(); search_terms_args.lens_overlay_suggest_inputs = input.lens_overlay_suggest_inputs(); - MaybeAddContextualUrlSuggestParam(search_terms_args); + MaybeAddContextualUrlSuggestParam(client(), search_terms_args); std::unique_ptr<network::SimpleURLLoader>* prefetch_loader = nullptr; if (result_type == ResultType::kRemoteNoURL) { @@ -513,7 +519,7 @@ : std::string(); search_terms_args.lens_overlay_suggest_inputs = input.lens_overlay_suggest_inputs(); - MaybeAddContextualUrlSuggestParam(search_terms_args); + MaybeAddContextualUrlSuggestParam(client(), search_terms_args); const auto* template_url_service = client()->GetTemplateURLService(); // Create a loader for the request and take ownership of it.
diff --git a/components/omnibox/browser/zero_suggest_provider_unittest.cc b/components/omnibox/browser/zero_suggest_provider_unittest.cc index 8bf55b8..bfbc030 100644 --- a/components/omnibox/browser/zero_suggest_provider_unittest.cc +++ b/components/omnibox/browser/zero_suggest_provider_unittest.cc
@@ -3014,20 +3014,30 @@ config; config.Get().contextual_url_suggest_param = "1"; - // Web gets the param. + // Web gets the param when Lens is enabled. { + EXPECT_CALL(*client_, IsLensEnabled()).WillOnce(testing::Return(true)); GURL url = get_provider_request_url(ZeroPrefixInputForWeb(/*is_prefetch=*/false)); EXPECT_NE(url.spec().find("ctxus=1"), std::string::npos); } + // Web does not get the param when Lens is disabled. + { + EXPECT_CALL(*client_, IsLensEnabled()).WillOnce(testing::Return(false)); + GURL url = + get_provider_request_url(ZeroPrefixInputForWeb(/*is_prefetch=*/false)); + EXPECT_EQ(url.spec().find("ctxus=1"), std::string::npos); + } // NTP does not, even when enabled. { + EXPECT_CALL(*client_, IsLensEnabled()).WillOnce(testing::Return(true)); GURL url = get_provider_request_url(ZeroPrefixInputForNTP(/*is_prefetch=*/false)); EXPECT_EQ(url.spec().find("ctxus=1"), std::string::npos); } // SRP does not, even when enabled. { + EXPECT_CALL(*client_, IsLensEnabled()).WillOnce(testing::Return(true)); GURL url = get_provider_request_url(ZeroPrefixInputForSRP(/*is_prefetch=*/false)); EXPECT_EQ(url.spec().find("ctxus=1"), std::string::npos);
diff --git a/components/omnibox/common/omnibox_feature_configs.cc b/components/omnibox/common/omnibox_feature_configs.cc index 1bbf5a76..11cdf7f8 100644 --- a/components/omnibox/common/omnibox_feature_configs.cc +++ b/components/omnibox/common/omnibox_feature_configs.cc
@@ -216,6 +216,11 @@ "relevance_scoring_mode", "mixed") .Get(); + realbox_unscoped_suggestions = + base::FeatureParam<bool>(&kSearchAggregatorProvider, + "realbox_unscoped_suggestions", false) + .Get(); + scoring_max_matches_created_per_type = base::FeatureParam<size_t>(&kSearchAggregatorProvider, "scoring_max_matches_created_per_type", 40)
diff --git a/components/omnibox/common/omnibox_feature_configs.h b/components/omnibox/common/omnibox_feature_configs.h index c4dcf1b..9f49653 100644 --- a/components/omnibox/common/omnibox_feature_configs.h +++ b/components/omnibox/common/omnibox_feature_configs.h
@@ -265,6 +265,9 @@ // "server": Use server-provided scores in both scoped and unscoped mode. // "client": Use client-calculated scores in both scoped and unscoped mode. std::string relevance_scoring_mode; + // If true, show unscoped `EnterpriseSearchAggregatorProvider` suggestions in + // the NTP realbox. + bool realbox_unscoped_suggestions; // See comments in enterprise_search_aggregator_provider.cc size_t scoring_max_matches_created_per_type;
diff --git a/components/optimization_guide/core/model_execution/on_device_model_service_controller.cc b/components/optimization_guide/core/model_execution/on_device_model_service_controller.cc index aeadd81..355e260 100644 --- a/components/optimization_guide/core/model_execution/on_device_model_service_controller.cc +++ b/components/optimization_guide/core/model_execution/on_device_model_service_controller.cc
@@ -673,7 +673,8 @@ bool OnDeviceModelServiceController::Solution::IsValid() { return model_controller_ && - (adapter_->CanSkipTextSafety() || safety_checker_->client()); + (!features::ShouldUseTextSafetyClassifierModel() || + adapter_->CanSkipTextSafety() || safety_checker_->client()); } // Creates a config describing this solution;
diff --git a/components/performance_manager/BUILD.gn b/components/performance_manager/BUILD.gn index 0ded25c..ac60dfa 100644 --- a/components/performance_manager/BUILD.gn +++ b/components/performance_manager/BUILD.gn
@@ -221,6 +221,7 @@ "public/resource_attribution/resource_types.h", "public/resource_attribution/type_helpers.h", "public/resource_attribution/worker_context.h", + "public/scenarios/process_performance_scenarios.h", "public/tracing_support.h", "public/user_tuning/prefs.h", "public/user_tuning/tab_revisit_tracker.h", @@ -273,6 +274,7 @@ "scenarios/loading_scenario_observer.h", "scenarios/performance_scenario_data.cc", "scenarios/performance_scenario_data.h", + "scenarios/process_performance_scenarios.cc", "scenarios/scoped_global_scenario_memory.cc", "service_worker_context_adapter.cc", "service_worker_context_adapter.h", @@ -417,6 +419,7 @@ "scenarios/browser_performance_scenarios_unittest.cc", "scenarios/input_scenario_observer_unittest.cc", "scenarios/loading_scenario_observer_unittest.cc", + "scenarios/process_performance_scenarios_unittest.cc", "test_support/mock_graphs_unittest.cc", "user_tuning/prefs_unittest.cc", "user_tuning/tab_revisit_tracker_unittest.cc",
diff --git a/components/performance_manager/public/DEPS b/components/performance_manager/public/DEPS index f1973c8..c4d58e4 100644 --- a/components/performance_manager/public/DEPS +++ b/components/performance_manager/public/DEPS
@@ -2,4 +2,5 @@ include_rules = [ "-components/performance_manager", "+components/performance_manager/public", + "+components/performance_manager/scenario_api", ]
diff --git a/components/performance_manager/public/scenarios/process_performance_scenarios.h b/components/performance_manager/public/scenarios/process_performance_scenarios.h new file mode 100644 index 0000000..e4072b7 --- /dev/null +++ b/components/performance_manager/public/scenarios/process_performance_scenarios.h
@@ -0,0 +1,103 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_SCENARIOS_PROCESS_PERFORMANCE_SCENARIOS_H_ +#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_SCENARIOS_PROCESS_PERFORMANCE_SCENARIOS_H_ + +#include "base/observer_list.h" +#include "base/scoped_observation_traits.h" +#include "components/performance_manager/scenario_api/performance_scenarios.h" + +namespace performance_scenarios { +class MatchingScenarioObserver; +class PerformanceScenarioObserver; +} // namespace performance_scenarios + +namespace performance_manager { + +class ProcessNode; + +// Functions to let the browser process query the performance scenarios for a +// child process. These are similar to functions in +// components/performance_manager/scenario_api/performance_scenarios.h, but have +// extra performance_manager dependencies. +// +// These functions all take a ProcessNode, and read the scenario values that are +// visible for ScenarioScope::kCurrentProcess in that process. Scenario values +// that are visible for ScenarioScope::kGlobal are the same in all processes, so +// can be read in the browser process using the API in performance_scenarios.h. +// +// All functions must be called on the UI thread. They return scenario values +// directly instead of `scenario_api::SharedAtomicRef` because the browser +// process updates scenario memory on the UI thread, so it won't change +// unexpectedly. + +// Returns the current LoadingScenario for `process`. +performance_scenarios::LoadingScenario GetProcessLoadingScenario( + const ProcessNode* process); + +// Returns the current InputScenario for `process`. +performance_scenarios::InputScenario GetProcessInputScenario( + const ProcessNode* process); + +// Returns true if the current scenarios for `process` match `pattern`. +bool CurrentProcessScenariosMatch( + const ProcessNode* process, + performance_scenarios::ScenarioPattern pattern); + +// Returns a list of PerformanceScenarioObservers for `process` that will be +// notified when the scenarios for that process change. The list is only valid +// as long as the ProcessNode exists. +base::ObserverList<performance_scenarios::PerformanceScenarioObserver>& +GetScenarioObserversForProcess(const ProcessNode* process); + +// Returns a list of MatchingScenarioObservers for `process` that will be +// notified when the scenarios for that process change to start or stop +// matching a scenario pattern. The list is only valid as long as the +// ProcessNode exists. +base::ObserverList<performance_scenarios::MatchingScenarioObserver>& +GetMatchingScenarioObserversForProcess(const ProcessNode* process); + +} // namespace performance_manager + +namespace base { + +// Specialize ScopedObservation to look up the observer lists for a ProcessNode. +// These must be in the same namespace as base::ScopedObservationTraits. + +template <> +struct ScopedObservationTraits< + performance_manager::ProcessNode, + performance_scenarios::PerformanceScenarioObserver> { + static void AddObserver( + const performance_manager::ProcessNode* source, + performance_scenarios::PerformanceScenarioObserver* observer) { + GetScenarioObserversForProcess(source).AddObserver(observer); + } + static void RemoveObserver( + const performance_manager::ProcessNode* source, + performance_scenarios::PerformanceScenarioObserver* observer) { + GetScenarioObserversForProcess(source).RemoveObserver(observer); + } +}; + +template <> +struct ScopedObservationTraits< + performance_manager::ProcessNode, + performance_scenarios::MatchingScenarioObserver> { + static void AddObserver( + const performance_manager::ProcessNode* source, + performance_scenarios::MatchingScenarioObserver* observer) { + GetMatchingScenarioObserversForProcess(source).AddObserver(observer); + } + static void RemoveObserver( + const performance_manager::ProcessNode* source, + performance_scenarios::MatchingScenarioObserver* observer) { + GetMatchingScenarioObserversForProcess(source).RemoveObserver(observer); + } +}; + +} // namespace base + +#endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_SCENARIOS_PROCESS_PERFORMANCE_SCENARIOS_H_
diff --git a/components/performance_manager/scenario_api/performance_scenario_observer.cc b/components/performance_manager/scenario_api/performance_scenario_observer.cc index 9171d49..93543c0 100644 --- a/components/performance_manager/scenario_api/performance_scenario_observer.cc +++ b/components/performance_manager/scenario_api/performance_scenario_observer.cc
@@ -82,7 +82,6 @@ MatchingScenarioObserver::~MatchingScenarioObserver() = default; void MatchingScenarioObserver::NotifyIfScenarioMatchChanged( - base::PassKey<PerformanceScenarioObserverList>, ScenarioScope scope, LoadingScenario loading_scenario, InputScenario input_scenario) { @@ -149,8 +148,8 @@ last_input_scenario_ = input_scenario; } matching_observers_->Notify( - location, &MatchingScenarioObserver::NotifyIfScenarioMatchChanged, - PassKey(), scope_, loading_scenario, input_scenario); + location, &MatchingScenarioObserver::NotifyIfScenarioMatchChanged, scope_, + loading_scenario, input_scenario); } // static
diff --git a/components/performance_manager/scenario_api/performance_scenario_observer.h b/components/performance_manager/scenario_api/performance_scenario_observer.h index 8241849..fd7a1d0 100644 --- a/components/performance_manager/scenario_api/performance_scenario_observer.h +++ b/components/performance_manager/scenario_api/performance_scenario_observer.h
@@ -61,11 +61,9 @@ // Allows PerformanceScenarioObserverList to notify of scenario changes. Will // invoke OnScenarioMatchChanged if necessary. - void NotifyIfScenarioMatchChanged( - base::PassKey<PerformanceScenarioObserverList>, - ScenarioScope scope, - LoadingScenario loading_scenario, - InputScenario input_scenario); + void NotifyIfScenarioMatchChanged(ScenarioScope scope, + LoadingScenario loading_scenario, + InputScenario input_scenario); private: // Returns a reference into `last_match_notifications_` for `scope`. @@ -137,8 +135,6 @@ private: friend class base::RefCountedThreadSafe<PerformanceScenarioObserverList>; - using PassKey = base::PassKey<PerformanceScenarioObserverList>; - explicit PerformanceScenarioObserverList(ScenarioScope scope); ~PerformanceScenarioObserverList();
diff --git a/components/performance_manager/scenario_api/performance_scenarios.h b/components/performance_manager/scenario_api/performance_scenarios.h index 4a2a1a8..7950758 100644 --- a/components/performance_manager/scenario_api/performance_scenarios.h +++ b/components/performance_manager/scenario_api/performance_scenarios.h
@@ -26,6 +26,10 @@ // child processes over shared memory. Each process can view a global scenario // list over the entire browser (eg. some page is loading) or a scenario list // targeted only to that process (eg. a page hosted in this process is loading). +// +// Additional functions to let the browser process query the performance +// scenarios for a child process are in +// components/performance_manager/public/scenarios/process_performance_scenarios.h. // Scenarios indicating a page is loading, ordered from least-specific to // most-specific.
diff --git a/components/performance_manager/scenarios/browser_performance_scenarios.cc b/components/performance_manager/scenarios/browser_performance_scenarios.cc index 113169b..271b913 100644 --- a/components/performance_manager/scenarios/browser_performance_scenarios.cc +++ b/components/performance_manager/scenarios/browser_performance_scenarios.cc
@@ -31,6 +31,9 @@ namespace performance_manager { +using performance_scenarios::MatchingScenarioObserver; +using performance_scenarios::PerformanceScenarioObserver; +using performance_scenarios::PerformanceScenarioObserverList; using performance_scenarios::ScenarioScope; namespace { @@ -62,6 +65,11 @@ // a tracing track is registered. void MaybeRecordTraceEvent(Scenario old_scenario, Scenario new_scenario) const; + + // Notifies a ProcessNode's PerformanceScenarioObserver list of a switch from + // `old_scenario` to `new_scenario`. + void NotifyProcessObservers(Scenario old_scenario, + Scenario new_scenario) const; }; template <> @@ -81,6 +89,19 @@ {"AnyPageLoading", "VisiblePageLoading", "FocusedPageLoading"}); } + void NotifyProcessObservers(LoadingScenario old_scenario, + LoadingScenario new_scenario) const { + state_ptr->observers().Notify( + &PerformanceScenarioObserver::OnLoadingScenarioChanged, + ScenarioScope::kCurrentProcess, old_scenario, new_scenario); + InputScenario input_scenario = + state_ptr->shared_state().ReadOnlyRef().input.load( + std::memory_order_relaxed); + state_ptr->matching_observers().Notify( + &MatchingScenarioObserver::NotifyIfScenarioMatchChanged, + ScenarioScope::kCurrentProcess, new_scenario, input_scenario); + } + raw_ptr<PerformanceScenarioData> state_ptr; }; @@ -101,6 +122,19 @@ {"TypingTapOrScroll", "TapOrScroll", "Scroll"}); } + void NotifyProcessObservers(InputScenario old_scenario, + InputScenario new_scenario) const { + state_ptr->observers().Notify( + &PerformanceScenarioObserver::OnInputScenarioChanged, + ScenarioScope::kCurrentProcess, old_scenario, new_scenario); + LoadingScenario loading_scenario = + state_ptr->shared_state().ReadOnlyRef().loading.load( + std::memory_order_relaxed); + state_ptr->matching_observers().Notify( + &MatchingScenarioObserver::NotifyIfScenarioMatchChanged, + ScenarioScope::kCurrentProcess, loading_scenario, new_scenario); + } + raw_ptr<PerformanceScenarioData> state_ptr; }; @@ -132,7 +166,8 @@ // Sets the value for Scenario in the memory region held in `state_ptr` to // `new_scenario`. template <typename Scenario> -void SetScenarioValue(Scenario new_scenario, +void SetScenarioValue(ScenarioScope scope, + Scenario new_scenario, PerformanceScenarioData* state_ptr) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (state_ptr) { @@ -143,6 +178,19 @@ traits.ScenarioRef().exchange(new_scenario, std::memory_order_relaxed); if (old_scenario != new_scenario) { traits.MaybeRecordTraceEvent(old_scenario, new_scenario); + switch (scope) { + case ScenarioScope::kCurrentProcess: + // Notify observers for the ProcessNode holding `state_ptr`. + traits.NotifyProcessObservers(old_scenario, new_scenario); + break; + case ScenarioScope::kGlobal: + // Notify all global observers registered in the browser process. + if (auto observers = PerformanceScenarioObserverList::GetForScope( + ScenarioScope::kGlobal)) { + observers->NotifyIfScenarioChanged(); + } + break; + } } } } @@ -154,19 +202,8 @@ base::WeakPtr<ProcessNode> process_node = PerformanceManager::GetProcessNodeForRenderProcessHost(host); CHECK(process_node); - SetScenarioValue(scenario, GetSharedStateForProcessNode(process_node.get())); -} - -template <typename Scenario> -void SetGlobalScenarioValue(Scenario scenario) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - SetScenarioValue(scenario, GetGlobalSharedState()); - // Notify kGlobal observers in the browser process. - if (auto observers = - performance_scenarios::PerformanceScenarioObserverList::GetForScope( - ScenarioScope::kGlobal)) { - observers->NotifyIfScenarioChanged(); - } + SetScenarioValue(ScenarioScope::kCurrentProcess, scenario, + GetSharedStateForProcessNode(process_node.get())); } } // namespace @@ -209,12 +246,13 @@ void SetLoadingScenarioForProcessNode(LoadingScenario scenario, const ProcessNode* process_node) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - SetScenarioValue(scenario, GetSharedStateForProcessNode(process_node)); + SetScenarioValue(ScenarioScope::kCurrentProcess, scenario, + GetSharedStateForProcessNode(process_node)); } void SetGlobalLoadingScenario(LoadingScenario scenario) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - SetGlobalScenarioValue(scenario); + SetScenarioValue(ScenarioScope::kGlobal, scenario, GetGlobalSharedState()); } void SetInputScenarioForProcess(InputScenario scenario, @@ -226,12 +264,13 @@ void SetInputScenarioForProcessNode(InputScenario scenario, const ProcessNode* process_node) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - SetScenarioValue(scenario, GetSharedStateForProcessNode(process_node)); + SetScenarioValue(ScenarioScope::kCurrentProcess, scenario, + GetSharedStateForProcessNode(process_node)); } void SetGlobalInputScenario(InputScenario scenario) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - SetGlobalScenarioValue(scenario); + SetScenarioValue(ScenarioScope::kGlobal, scenario, GetGlobalSharedState()); } } // namespace performance_manager
diff --git a/components/performance_manager/scenarios/performance_scenario_data.h b/components/performance_manager/scenarios/performance_scenario_data.h index df9e723..9e448d3 100644 --- a/components/performance_manager/scenarios/performance_scenario_data.h +++ b/components/performance_manager/scenarios/performance_scenario_data.h
@@ -9,9 +9,11 @@ #include <optional> #include "base/memory/structured_shared_memory.h" +#include "base/observer_list.h" #include "base/types/optional_util.h" #include "components/performance_manager/graph/node_inline_data.h" #include "components/performance_manager/scenario_api/performance_scenario_memory_forward.h" +#include "components/performance_manager/scenario_api/performance_scenario_observer.h" #include "third_party/perfetto/include/perfetto/tracing/track.h" namespace base { @@ -31,6 +33,10 @@ public: using SharedScenarioState = base::StructuredSharedMemory<performance_scenarios::ScenarioState>; + using MatchingScenarioObserver = + performance_scenarios::MatchingScenarioObserver; + using PerformanceScenarioObserver = + performance_scenarios::PerformanceScenarioObserver; // Returns the data for `process_node`, creating it if it doesn't already // exist. If the data is newly created and `mapper` is non-null, it will be @@ -61,6 +67,22 @@ return shared_state_.value(); } + // Returns observer lists for changes to the scenario state of the + // ProcessNode. + base::ObserverList<PerformanceScenarioObserver>& observers() { + return *observers_; + } + const base::ObserverList<PerformanceScenarioObserver>& observers() const { + return *observers_; + } + base::ObserverList<MatchingScenarioObserver>& matching_observers() { + return *matching_observers_; + } + const base::ObserverList<MatchingScenarioObserver>& matching_observers() + const { + return *matching_observers_; + } + // Returns tracing tracks to log trace events when updating scenarios in the // shared memory region, or nullptr if EnsureTracingTracks() wasn't called. const perfetto::NamedTrack* loading_tracing_track() const { @@ -86,10 +108,19 @@ std::optional<SharedScenarioState> shared_state_; // Additional data associated with the region. + // Tracing tracks must be stored in a heap-allocated struct because NamedTrack // is non-copyable and non-movable. std::unique_ptr<TracingTracks> tracing_tracks_ = std::make_unique<TracingTracks>(); + + // Observers for changes to the scenario state of a specific ProcessNode. Held + // in unique_ptr because ObserverList isn't movable. + std::unique_ptr<base::ObserverList<PerformanceScenarioObserver>> observers_ = + std::make_unique<base::ObserverList<PerformanceScenarioObserver>>(); + std::unique_ptr<base::ObserverList<MatchingScenarioObserver>> + matching_observers_ = + std::make_unique<base::ObserverList<MatchingScenarioObserver>>(); }; } // namespace performance_manager
diff --git a/components/performance_manager/scenarios/process_performance_scenarios.cc b/components/performance_manager/scenarios/process_performance_scenarios.cc new file mode 100644 index 0000000..573e6281 --- /dev/null +++ b/components/performance_manager/scenarios/process_performance_scenarios.cc
@@ -0,0 +1,60 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/performance_manager/public/scenarios/process_performance_scenarios.h" + +#include <atomic> + +#include "components/performance_manager/public/graph/process_node.h" +#include "components/performance_manager/scenario_api/performance_scenario_memory.h" +#include "components/performance_manager/scenarios/performance_scenario_data.h" + +namespace performance_manager { + +namespace { + +using performance_scenarios::InputScenario; +using performance_scenarios::LoadingScenario; +using performance_scenarios::MatchingScenarioObserver; +using performance_scenarios::PerformanceScenarioObserver; +using performance_scenarios::ScenarioState; + +const ScenarioState& GetScenarioStateForProcess(const ProcessNode* process) { + static constinit ScenarioState kDummyScenarioState; + const auto& data = PerformanceScenarioData::GetOrCreate(process); + return data.HasSharedState() ? data.shared_state().ReadOnlyRef() + : kDummyScenarioState; +} + +} // namespace + +LoadingScenario GetProcessLoadingScenario(const ProcessNode* process) { + return GetScenarioStateForProcess(process).loading.load( + std::memory_order_relaxed); +} + +InputScenario GetProcessInputScenario(const ProcessNode* process) { + return GetScenarioStateForProcess(process).input.load( + std::memory_order_relaxed); +} + +bool CurrentProcessScenariosMatch( + const ProcessNode* process, + performance_scenarios::ScenarioPattern pattern) { + return performance_scenarios::ScenariosMatch( + GetProcessLoadingScenario(process), GetProcessInputScenario(process), + pattern); +} + +base::ObserverList<performance_scenarios::PerformanceScenarioObserver>& +GetScenarioObserversForProcess(const ProcessNode* process) { + return PerformanceScenarioData::GetOrCreate(process).observers(); +} + +base::ObserverList<performance_scenarios::MatchingScenarioObserver>& +GetMatchingScenarioObserversForProcess(const ProcessNode* process) { + return PerformanceScenarioData::GetOrCreate(process).matching_observers(); +} + +} // namespace performance_manager
diff --git a/components/performance_manager/scenarios/process_performance_scenarios_unittest.cc b/components/performance_manager/scenarios/process_performance_scenarios_unittest.cc new file mode 100644 index 0000000..ceff87d --- /dev/null +++ b/components/performance_manager/scenarios/process_performance_scenarios_unittest.cc
@@ -0,0 +1,272 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/performance_manager/public/scenarios/process_performance_scenarios.h" + +#include <optional> + +#include "base/containers/span.h" +#include "base/memory/platform_shared_memory_handle.h" +#include "base/memory/shared_memory_mapper.h" +#include "base/scoped_observation.h" +#include "components/performance_manager/embedder/scoped_global_scenario_memory.h" +#include "components/performance_manager/graph/process_node_impl.h" +#include "components/performance_manager/public/graph/graph.h" +#include "components/performance_manager/scenario_api/performance_scenario_observer.h" +#include "components/performance_manager/scenario_api/performance_scenarios.h" +#include "components/performance_manager/scenarios/browser_performance_scenarios.h" +#include "components/performance_manager/scenarios/performance_scenario_data.h" +#include "components/performance_manager/test_support/graph_test_harness.h" +#include "components/performance_manager/test_support/mock_graphs.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace performance_manager { + +namespace { + +using performance_scenarios::InputScenario; +using performance_scenarios::LoadingScenario; +using performance_scenarios::MatchingScenarioObserver; +using performance_scenarios::PerformanceScenarioObserver; +using performance_scenarios::ScenarioScope; + +class LenientMockPerformanceScenarioObserver + : public PerformanceScenarioObserver { + public: + MOCK_METHOD(void, + OnLoadingScenarioChanged, + (ScenarioScope scope, + LoadingScenario old_scenario, + LoadingScenario new_scenario), + (override)); + MOCK_METHOD(void, + OnInputScenarioChanged, + (ScenarioScope scope, + InputScenario old_scenario, + InputScenario new_scenario), + (override)); +}; + +using MockPerformanceScenarioObserver = + ::testing::StrictMock<LenientMockPerformanceScenarioObserver>; + +class LenientMockMatchingScenarioObserver : public MatchingScenarioObserver { + public: + explicit LenientMockMatchingScenarioObserver( + performance_scenarios::ScenarioPattern pattern) + : MatchingScenarioObserver(pattern) {} + + MOCK_METHOD(void, + OnScenarioMatchChanged, + (ScenarioScope scope, bool matches_pattern), + (override)); +}; + +using MockMatchingScenarioObserver = + ::testing::StrictMock<LenientMockMatchingScenarioObserver>; + +// A fake SharedMemoryMapper that fails to map in memory. +class FailingSharedMemoryMapper final : public base::SharedMemoryMapper { + public: + FailingSharedMemoryMapper() = default; + ~FailingSharedMemoryMapper() = default; + + std::optional<base::span<uint8_t>> Map( + base::subtle::PlatformSharedMemoryHandle handle, + bool write_allowed, + uint64_t offset, + size_t size) final { + return std::nullopt; + } + + void Unmap(base::span<uint8_t> mapping) final {} +}; + +class ProcessPerformanceScenariosTest : public GraphTestHarness { + private: + // Always map global memory. Per-process memory will be mapped automatically + // as process nodes are created. + ScopedGlobalScenarioMemory scoped_global_scenario_memory_; +}; + +} // namespace + +TEST_F(ProcessPerformanceScenariosTest, LoadingScenario) { + MockSinglePageWithMultipleProcessesGraph mock_graph(graph()); + + EXPECT_EQ(GetProcessLoadingScenario(mock_graph.process.get()), + LoadingScenario::kNoPageLoading); + EXPECT_EQ(GetProcessLoadingScenario(mock_graph.other_process.get()), + LoadingScenario::kNoPageLoading); + + MockPerformanceScenarioObserver mock_observer; + base::ScopedObservation<ProcessNode, PerformanceScenarioObserver> observation( + &mock_observer); + observation.Observe(mock_graph.process.get()); + + MockMatchingScenarioObserver mock_matching_observer( + performance_scenarios::kDefaultIdleScenarios); + base::ScopedObservation<ProcessNode, MatchingScenarioObserver> + matching_observation(&mock_matching_observer); + matching_observation.Observe(mock_graph.process.get()); + + // Changing to kBackgroundPageLoading should invoke the + // PerformanceScenarioObserver but not the MatchingScenarioObserver, since it + // still matches kDefaultIdleScenarios. + EXPECT_CALL(mock_observer, OnLoadingScenarioChanged( + ScenarioScope::kCurrentProcess, + LoadingScenario::kNoPageLoading, + LoadingScenario::kBackgroundPageLoading)); + + SetLoadingScenarioForProcessNode(LoadingScenario::kBackgroundPageLoading, + mock_graph.process.get()); + EXPECT_EQ(GetProcessLoadingScenario(mock_graph.process.get()), + LoadingScenario::kBackgroundPageLoading); + ::testing::Mock::VerifyAndClearExpectations(&mock_observer); + ::testing::Mock::VerifyAndClearExpectations(&mock_matching_observer); + + // Observers shouldn't be notified if the scenario doesn't change. + SetLoadingScenarioForProcessNode(LoadingScenario::kBackgroundPageLoading, + mock_graph.process.get()); + EXPECT_EQ(GetProcessLoadingScenario(mock_graph.process.get()), + LoadingScenario::kBackgroundPageLoading); + ::testing::Mock::VerifyAndClearExpectations(&mock_observer); + ::testing::Mock::VerifyAndClearExpectations(&mock_matching_observer); + + // Observer shouldn't be notified for changes to a different process, or for + // global changes. + SetLoadingScenarioForProcessNode(LoadingScenario::kVisiblePageLoading, + mock_graph.other_process.get()); + SetGlobalLoadingScenario(LoadingScenario::kFocusedPageLoading); + EXPECT_EQ(GetProcessLoadingScenario(mock_graph.other_process.get()), + LoadingScenario::kVisiblePageLoading); + ::testing::Mock::VerifyAndClearExpectations(&mock_observer); + ::testing::Mock::VerifyAndClearExpectations(&mock_matching_observer); + + // Changing to kVisiblePageLoading should notify both observers since the + // scenario no longer matches kDefaultIdleScenarios. + EXPECT_CALL(mock_observer, + OnLoadingScenarioChanged(ScenarioScope::kCurrentProcess, + LoadingScenario::kBackgroundPageLoading, + LoadingScenario::kVisiblePageLoading)); + EXPECT_CALL(mock_matching_observer, + OnScenarioMatchChanged(ScenarioScope::kCurrentProcess, false)); + + SetLoadingScenarioForProcessNode(LoadingScenario::kVisiblePageLoading, + mock_graph.process.get()); + EXPECT_EQ(GetProcessLoadingScenario(mock_graph.process.get()), + LoadingScenario::kVisiblePageLoading); + ::testing::Mock::VerifyAndClearExpectations(&mock_observer); + ::testing::Mock::VerifyAndClearExpectations(&mock_matching_observer); +} + +TEST_F(ProcessPerformanceScenariosTest, InputScenario) { + MockSinglePageWithMultipleProcessesGraph mock_graph(graph()); + + EXPECT_EQ(GetProcessInputScenario(mock_graph.process.get()), + InputScenario::kNoInput); + EXPECT_EQ(GetProcessInputScenario(mock_graph.other_process.get()), + InputScenario::kNoInput); + + MockPerformanceScenarioObserver mock_observer; + base::ScopedObservation<ProcessNode, PerformanceScenarioObserver> observation( + &mock_observer); + observation.Observe(mock_graph.process.get()); + + MockMatchingScenarioObserver mock_matching_observer( + performance_scenarios::kDefaultIdleScenarios); + base::ScopedObservation<ProcessNode, MatchingScenarioObserver> + matching_observation(&mock_matching_observer); + matching_observation.Observe(mock_graph.process.get()); + + // Changing to kTyping should notify both observers since the scenario no + // longer matches kDefaultIdleScenarios. + EXPECT_CALL( + mock_observer, + OnInputScenarioChanged(ScenarioScope::kCurrentProcess, + InputScenario::kNoInput, InputScenario::kTyping)); + EXPECT_CALL(mock_matching_observer, + OnScenarioMatchChanged(ScenarioScope::kCurrentProcess, false)); + + SetInputScenarioForProcessNode(InputScenario::kTyping, + mock_graph.process.get()); + EXPECT_EQ(GetProcessInputScenario(mock_graph.process.get()), + InputScenario::kTyping); + ::testing::Mock::VerifyAndClearExpectations(&mock_observer); + ::testing::Mock::VerifyAndClearExpectations(&mock_matching_observer); + + // Observers shouldn't be notified if the scenario doesn't change. + SetInputScenarioForProcessNode(InputScenario::kTyping, + mock_graph.process.get()); + EXPECT_EQ(GetProcessInputScenario(mock_graph.process.get()), + InputScenario::kTyping); + ::testing::Mock::VerifyAndClearExpectations(&mock_observer); + ::testing::Mock::VerifyAndClearExpectations(&mock_matching_observer); + + // Observer shouldn't be notified for changes to a different process, or for + // global changes. + SetInputScenarioForProcessNode(InputScenario::kTap, + mock_graph.other_process.get()); + SetGlobalInputScenario(InputScenario::kScroll); + EXPECT_EQ(GetProcessInputScenario(mock_graph.other_process.get()), + InputScenario::kTap); + ::testing::Mock::VerifyAndClearExpectations(&mock_observer); + ::testing::Mock::VerifyAndClearExpectations(&mock_matching_observer); + + // Changing to kTap should invoke the PerformanceScenarioObserver but not the + // MatchingScenarioObserver, since it still doesn't match + // kDefaultIdleScenarios. + EXPECT_CALL(mock_observer, OnInputScenarioChanged( + ScenarioScope::kCurrentProcess, + InputScenario::kTyping, InputScenario::kTap)); + + SetInputScenarioForProcessNode(InputScenario::kTap, mock_graph.process.get()); + EXPECT_EQ(GetProcessInputScenario(mock_graph.process.get()), + InputScenario::kTap); + ::testing::Mock::VerifyAndClearExpectations(&mock_observer); + ::testing::Mock::VerifyAndClearExpectations(&mock_matching_observer); +} + +TEST_F(ProcessPerformanceScenariosTest, NoMemory) { + MockSinglePageInSingleProcessGraph mock_graph(graph()); + + // First access to the PerformanceScenarioData uses a failing mapper. + FailingSharedMemoryMapper failing_mapper; + EXPECT_FALSE(PerformanceScenarioData::Exists(mock_graph.process.get())); + auto& data = PerformanceScenarioData::GetOrCreate(mock_graph.process.get(), + &failing_mapper); + EXPECT_FALSE(data.HasSharedState()); + + // Reading the process scenario should return default values when memory + // mapping failed. + EXPECT_EQ(GetProcessLoadingScenario(mock_graph.process.get()), + LoadingScenario::kNoPageLoading); + EXPECT_EQ(GetProcessInputScenario(mock_graph.process.get()), + InputScenario::kNoInput); + + // Writing to process state should do nothing. Observers should not be + // notified. + MockPerformanceScenarioObserver mock_observer; + base::ScopedObservation<ProcessNode, PerformanceScenarioObserver> observation( + &mock_observer); + observation.Observe(mock_graph.process.get()); + + MockMatchingScenarioObserver mock_matching_observer( + performance_scenarios::kDefaultIdleScenarios); + base::ScopedObservation<ProcessNode, MatchingScenarioObserver> + matching_observation(&mock_matching_observer); + matching_observation.Observe(mock_graph.process.get()); + + SetLoadingScenarioForProcessNode(LoadingScenario::kVisiblePageLoading, + mock_graph.process.get()); + SetInputScenarioForProcessNode(InputScenario::kTyping, + mock_graph.process.get()); + EXPECT_EQ(GetProcessLoadingScenario(mock_graph.process.get()), + LoadingScenario::kNoPageLoading); + EXPECT_EQ(GetProcessInputScenario(mock_graph.process.get()), + InputScenario::kNoInput); +} + +} // namespace performance_manager
diff --git a/components/permissions/notifications_engagement_service.h b/components/permissions/notifications_engagement_service.h index 19b0e83..fcdadca 100644 --- a/components/permissions/notifications_engagement_service.h +++ b/components/permissions/notifications_engagement_service.h
@@ -46,6 +46,8 @@ static std::map<std::pair<ContentSettingsPattern, ContentSettingsPattern>, int> GetNotificationCountMapPerPatternPair(const HostContentSettingsMap* hcsm); + static int GetDailyAverageNotificationCount( + const base::Value::Dict& engagement); static std::string GetBucketLabel(base::Time time); static std::optional<base::Time> ParsePeriodBeginFromBucketLabel( @@ -58,8 +60,6 @@ static int GetDailyAverageNotificationCount( const ContentSettingPatternSource& setting); - static int GetDailyAverageNotificationCount( - const base::Value::Dict& engagement); raw_ptr<PrefService> pref_service_; raw_ptr<content::BrowserContext> browser_context_;
diff --git a/components/signin/core/browser/signin_metrics_service.cc b/components/signin/core/browser/signin_metrics_service.cc index ff3e6ce5..6fc2827 100644 --- a/components/signin/core/browser/signin_metrics_service.cc +++ b/components/signin/core/browser/signin_metrics_service.cc
@@ -189,6 +189,8 @@ kHistorySyncOptinExpansionPillOnInactivity: case signin_metrics::AccessPoint::kHistorySyncEducationalTip: case signin_metrics::AccessPoint::kManagedProfileAutoSigninIos: + case signin_metrics::AccessPoint::kNonModalSigninPasswordPromo: + case signin_metrics::AccessPoint::kNonModalSigninBookmarkPromo: return; }
diff --git a/components/signin/public/base/signin_metrics.cc b/components/signin/public/base/signin_metrics.cc index 8f64c95..11672776 100644 --- a/components/signin/public/base/signin_metrics.cc +++ b/components/signin/public/base/signin_metrics.cc
@@ -592,6 +592,14 @@ base::RecordAction(base::UserMetricsAction( "Signin_Signin_FromHistorySyncOptinExpansionPillOnInactivity")); break; + case AccessPoint::kNonModalSigninPasswordPromo: + base::RecordAction(base::UserMetricsAction( + "Signin_Signin_FromNonModalSigninPasswordPromo")); + break; + case AccessPoint::kNonModalSigninBookmarkPromo: + base::RecordAction(base::UserMetricsAction( + "Signin_Signin_FromNonModalSigninBookmarkPromo")); + break; } } @@ -766,6 +774,8 @@ case AccessPoint::kHistorySyncOptinExpansionPillOnInactivity: case AccessPoint::kHistorySyncEducationalTip: case AccessPoint::kManagedProfileAutoSigninIos: + case AccessPoint::kNonModalSigninPasswordPromo: + case AccessPoint::kNonModalSigninBookmarkPromo: NOTREACHED() << "Signin_Impression_From* user actions are not recorded " "for access point " << static_cast<int>(access_point);
diff --git a/components/signin/public/base/signin_metrics.h b/components/signin/public/base/signin_metrics.h index ec8b288..31eaaee 100644 --- a/components/signin/public/base/signin_metrics.h +++ b/components/signin/public/base/signin_metrics.h
@@ -284,10 +284,14 @@ // iOS only: The user switched to a managed account for the first time, and // the corresponding profile was automatically signed in. kManagedProfileAutoSigninIos = 82, + // iOS only: Access point for the contextual non modal sign-in password promo. + kNonModalSigninPasswordPromo = 83, + // iOS only: Access point for the contextual non modal sign-in bookmark promo. + kNonModalSigninBookmarkPromo = 84, // Add values above this line with a corresponding label to the // "SigninAccessPoint" enum in // tools/metrics/histograms/metadata/signin/enums.xml. - kMaxValue = kManagedProfileAutoSigninIos, // This must be last. + kMaxValue = kNonModalSigninBookmarkPromo, // This must be last. }; // LINT.ThenChange(/tools/metrics/histograms/metadata/signin/enums.xml)
diff --git a/components/signin/public/base/signin_metrics_unittest.cc b/components/signin/public/base/signin_metrics_unittest.cc index 48f9e9a..788db859 100644 --- a/components/signin/public/base/signin_metrics_unittest.cc +++ b/components/signin/public/base/signin_metrics_unittest.cc
@@ -50,6 +50,8 @@ AccessPoint::kProductSpecifications, AccessPoint::kAddressBubble, AccessPoint::kGlicLaunchButton, + AccessPoint::kNonModalSigninPasswordPromo, + AccessPoint::kNonModalSigninBookmarkPromo, }; const AccessPoint kAccessPointsThatSupportImpression[] = { @@ -234,6 +236,10 @@ return "HistorySyncEducationalTip"; case AccessPoint::kManagedProfileAutoSigninIos: return "ManagedProfileAutoSigninIos"; + case AccessPoint::kNonModalSigninPasswordPromo: + return "NonModalSigninPasswordPromo"; + case AccessPoint::kNonModalSigninBookmarkPromo: + return "NonModalSigninBookmarkPromo"; } } };
diff --git a/components/url_formatter/url_fixer.cc b/components/url_formatter/url_fixer.cc index 38f97710..2bd6afe 100644 --- a/components/url_formatter/url_fixer.cc +++ b/components/url_formatter/url_fixer.cc
@@ -414,7 +414,7 @@ // brackets are not in the whitelist. url::StdStringCanonOutput canon_scheme_output(canon_scheme); url::Component canon_scheme_component; - if (!url::CanonicalizeScheme(text.data(), *scheme_component, + if (!url::CanonicalizeScheme(scheme_component->as_string_view_on(text.data()), &canon_scheme_output, &canon_scheme_component)) { return false; }
diff --git a/components/url_pattern/url_pattern_util.cc b/components/url_pattern/url_pattern_util.cc index 6e56c10..cad3fcf 100644 --- a/components/url_pattern/url_pattern_util.cc +++ b/components/url_pattern/url_pattern_util.cc
@@ -49,9 +49,7 @@ url::RawCanonOutputT<char> canon_output; url::Component component; - bool result = url::CanonicalizeScheme( - input.data(), url::Component(0, base::checked_cast<int>(input.size())), - &canon_output, &component); + bool result = url::CanonicalizeScheme(input, &canon_output, &component); if (!result) { return base::unexpected(absl::InvalidArgumentError(
diff --git a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm index e2b524c9..d1426068 100644 --- a/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm +++ b/content/app_shim_remote_cocoa/render_widget_host_view_cocoa.mm
@@ -481,7 +481,7 @@ NSRect textRectInViewCoordinates = [self convertRect:textRectInWindowCoordinates fromView:nil]; - NSUInteger capturedChangeCounter = _availableTextChangeCounter; + ui::TextInputType capturedTextInputType = _textInputType; [self.spellChecker showCorrectionIndicatorOfType:NSCorrectionIndicatorTypeDefault @@ -492,13 +492,13 @@ completionHandler:^(NSString* acceptedString) { [self didAcceptReplacementString:acceptedString forTextCheckingResult:candidateResult - withChangeNumber:capturedChangeCounter]; + withTextInputType:capturedTextInputType]; }]; } - (void)didAcceptReplacementString:(NSString*)acceptedString forTextCheckingResult:(NSTextCheckingResult*)correction - withChangeNumber:(NSUInteger)changeNumber { + withTextInputType:(ui::TextInputType)textInputType { // TODO: Keep NSSpellChecker up to date on the user's response via // -recordResponse:toCorrection:forWord:language:inSpellDocumentWithTag:. // Call it to report whether they initially accepted or rejected the @@ -507,6 +507,12 @@ if (acceptedString == nil) return; + // If the text input type is different now than when we set up the callback, + // the text replacement operation is stale and can be ignored. + if (textInputType != _textInputType) { + return; + } + NSRange availableTextRange = NSMakeRange(_availableTextOffset, _availableText.length()); @@ -529,18 +535,6 @@ language:nil]) return; - // Gather some info in case -doubleClickAtIndex: throws an exception. - // This change will eventually be reverted. - NSString* info = [NSString - stringWithFormat:@"%lu == %lu %lu %@ %@ %@ %@", changeNumber, - _availableTextChangeCounter, attString.string.length, - NSStringFromRange(availableTextRange), - NSStringFromRange(correction.range), - NSStringFromRange(trailingRange), - NSStringFromRange(trailingRangeInAvailableText)]; - SCOPED_CRASH_KEY_STRING256("RenderWidgetHostViewCocoa", "didAcceptTR", - base::SysNSStringToUTF8(info)); - if ([attString doubleClickAtIndex:trailingRangeInAvailableText.location] .location < trailingRangeInAvailableText.location) return;
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.h b/content/browser/accessibility/dump_accessibility_tree_browsertest.h index 3e010e4..b6fa1d75 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.h +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.h
@@ -27,6 +27,9 @@ // See content/test/data/accessibility/readme.md for an overview. // +// Use tools/accessibility/rebase_dump_accessibility_tree_tests.py to +// update test expectations. +// // This test takes a snapshot of the platform BrowserAccessibility tree and // tests it against an expected baseline. //
diff --git a/content/browser/preloading/prefetch/prefetch_service.h b/content/browser/preloading/prefetch/prefetch_service.h index de3d3dc..7779198 100644 --- a/content/browser/preloading/prefetch/prefetch_service.h +++ b/content/browser/preloading/prefetch/prefetch_service.h
@@ -107,15 +107,6 @@ virtual PrefetchOriginProber* GetPrefetchOriginProber() const; virtual void PrefetchUrl(base::WeakPtr<PrefetchContainer> prefetch_container); - // Finds the prefetch (if any) that can be used to serve a navigation to - // |url|, and then calls |on_prefetch_to_serve_ready| with that prefetch. - using OnPrefetchToServeReady = - base::OnceCallback<void(PrefetchContainer::Reader prefetch_to_serve)>; - void GetPrefetchToServe(const PrefetchContainer::Key& key, - base::WeakPtr<PrefetchServingPageMetricsContainer> - serving_page_metrics_container, - PrefetchMatchResolver& prefetch_match_resolver); - // Copies any cookies in the isolated network context associated with // |prefetch_container| to the default network context. virtual void CopyIsolatedCookies(const PrefetchContainer::Reader& reader);
diff --git a/content/browser/renderer_host/navigation_controller_impl.cc b/content/browser/renderer_host/navigation_controller_impl.cc index e2bc8ad0b..06dfcf6 100644 --- a/content/browser/renderer_host/navigation_controller_impl.cc +++ b/content/browser/renderer_host/navigation_controller_impl.cc
@@ -123,6 +123,12 @@ namespace content { namespace { +// Feature to skip a redundant NavigationRequest creation for bfcache +// activations, per https://crbug.com/417251428. +BASE_FEATURE(kSkipExtraBfcacheNavigationRequest, + "SkipExtraBfcacheNavigationRequest", + base::FEATURE_ENABLED_BY_DEFAULT); + // Invoked when entries have been pruned, or removed. For example, if the // current entries are [google, digg, yahoo], with the current entry google, // and the user types in cnet, then digg and yahoo are pruned. @@ -3317,29 +3323,49 @@ // Navigate immediately if the document is in the BackForwardCache. if (back_forward_cache_.GetOrEvictEntry(nav_entry_id).has_value()) { TRACE_EVENT0("navigation", "BackForwardCache_CreateNavigationRequest"); - DCHECK_EQ(reload_type, ReloadType::NONE); - auto navigation_request = CreateNavigationRequestFromEntry( - root, pending_entry_, pending_entry_->GetFrameEntry(root), - ReloadType::NONE, false /* is_same_document_history_load */, - false /* is_history_navigation_in_new_child */, initiator_frame_token, - initiator_process_id); - base::WeakPtr<NavigationRequest> request = navigation_request->GetWeakPtr(); - root->navigator().Navigate(std::move(navigation_request), ReloadType::NONE); + CHECK_EQ(reload_type, ReloadType::NONE); + base::WeakPtr<NavigationRequest> request; - for (auto& unused_request : same_document_loads) { - unused_request->set_navigation_discard_reason( - NavigationDiscardReason::kNeverStarted); - } - for (auto& unused_request : different_document_loads) { - unused_request->set_navigation_discard_reason( - NavigationDiscardReason::kNeverStarted); + // Skip a redundant NavigationRequest creation, per + // https://crbug.com/417251428. + if (base::FeatureList::IsEnabled(kSkipExtraBfcacheNavigationRequest)) { + // If the BackForwardCache can handle this request, it must be for a main + // frame, cross-document, non-reload request. This means there is only one + // item in `different_document_loads` and no `same_document_loads`. + CHECK_EQ(different_document_loads.size(), 1u); + CHECK(same_document_loads.empty()); + request = different_document_loads.at(0)->GetWeakPtr(); + root->navigator().Navigate(std::move(different_document_loads.at(0)), + ReloadType::NONE); + } else { + // The legacy approach creates a new NavigationRequest for the entry and + // discards any previously created NavigationRequests, even though the new + // request is identical to the sole existing request. + // TODO(crbug.com/417251428): Remove this path once we measure the impact. + auto navigation_request = CreateNavigationRequestFromEntry( + root, pending_entry_, pending_entry_->GetFrameEntry(root), + ReloadType::NONE, false /* is_same_document_history_load */, + false /* is_history_navigation_in_new_child */, initiator_frame_token, + initiator_process_id); + request = navigation_request->GetWeakPtr(); + root->navigator().Navigate(std::move(navigation_request), + ReloadType::NONE); + + for (auto& unused_request : same_document_loads) { + unused_request->set_navigation_discard_reason( + NavigationDiscardReason::kNeverStarted); + } + for (auto& unused_request : different_document_loads) { + unused_request->set_navigation_discard_reason( + NavigationDiscardReason::kNeverStarted); + } } - std::vector<base::WeakPtr<NavigationRequest>> bf_cache_request; + std::vector<base::WeakPtr<NavigationRequest>> bf_cache_requests; if (request) { - bf_cache_request.push_back(std::move(request)); + bf_cache_requests.push_back(std::move(request)); } - return bf_cache_request; + return bf_cache_requests; } // History navigation might try to reuse a specific BrowsingInstance, already
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 36a213d..a5f8882 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -15891,7 +15891,7 @@ base::Value::Dict body; if (base::FeatureList::IsEnabled( blink::features::kCrashReportingAPIMoreContextData)) { - body.Set("is_top_level", IsOutermostMainFrame() ? "true" : "false"); + body.Set("is_top_level", IsOutermostMainFrame() ? true : false); body.Set("visibility_state", GetVisibilityState() == PageVisibilityState::kVisible ? "visible" : "hidden");
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index d71195a..569bc28 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -68,7 +68,6 @@ using blink::mojom::FederatedAuthRequestResult; using blink::mojom::IdentityProviderConfig; using blink::mojom::IdentityProviderConfigPtr; -using blink::mojom::IdentityProviderGetParametersPtr; using blink::mojom::IdentityProviderRequestOptions; using blink::mojom::IdentityProviderRequestOptionsPtr; using blink::mojom::RegisterIdpStatus; @@ -319,48 +318,7 @@ std::vector<IdentityProviderGetParametersPtr> idp_get_params_ptrs, MediationRequirement requirement, RequestTokenCallback callback) { - // idp_get_params_ptrs sent from the renderer should be of size 1. - if (idp_get_params_ptrs.size() != 1u) { - ReportBadMessageAndDeleteThis("idp_get_params_ptrs should be of size 1."); - return; - } - // This could only happen with a compromised renderer process. We ensure that - // the provider list size is > 0 on the renderer side at the beginning of - // parsing |IdentityCredentialRequestOptions|. - for (auto& idp_get_params_ptr : idp_get_params_ptrs) { - if (idp_get_params_ptr->providers.size() == 0) { - ReportBadMessageAndDeleteThis("The provider list should not be empty."); - return; - } - if (idp_get_params_ptr->providers.size() > 10u) { - ReportBadMessageAndDeleteThis( - "The provider list should not be greater than 10."); - return; - } - if (idp_get_params_ptr->mode == RpMode::kActive && - requirement == MediationRequirement::kSilent) { - ReportBadMessageAndDeleteThis( - "mediation: silent is not supported in active mode."); - return; - } - } - - if (requirement == MediationRequirement::kConditional && - !IsFedCmAutofillEnabled()) { - // The conditional mediation parameter can only be used when delegation - // is enabled while it is under development. - // - // TODO(crbug.com/380367784): handle all of the many cases in which a - // conditional mediation may interact with other features. - ReportBadMessageAndDeleteThis( - "Conditional mediation is not supported when both autofill and " - "delegation are disabled."); - return; - } - - if (render_frame_host().IsNestedWithinFencedFrame()) { - ReportBadMessageAndDeleteThis( - "FedCM should not be allowed in fenced frame trees."); + if (ShouldTerminateRequest(idp_get_params_ptrs, requirement)) { return; } @@ -409,12 +367,7 @@ std::move(callback).Run(RequestTokenStatus::kError, std::nullopt, "", /*error=*/nullptr, /*is_auto_selected=*/false); - fedcm_metrics_.reset(); - // If there's an existing auth request token callback, we will need to - // record metrics for it once it is resolved. - if (auth_request_token_callback_) { - MaybeCreateFedCmMetrics(); - } + HandleMetricsForPotentialConcurrentRequests(); return; } @@ -427,19 +380,14 @@ std::move(callback).Run(RequestTokenStatus::kError, std::nullopt, "", /*error=*/nullptr, /*is_auto_selected=*/false); - fedcm_metrics_.reset(); - // If there's an existing auth request token callback, we will need to - // record metrics for it once it is resolved. - if (auth_request_token_callback_) { - MaybeCreateFedCmMetrics(); - } + HandleMetricsForPotentialConcurrentRequests(); return; } had_transient_user_activation_ = render_frame_host().HasTransientUserActivation(); - MaybeCreateFedCmMetrics(); + // Store the previous `idp_order_` value from this class. Note that this is {} // unless there is a pending request from the same RFH. In particular, this is // still {} if there is a pending request but from a different RFH. @@ -450,84 +398,13 @@ idp_order_.push_back(idp_ptr->config->config_url); } } - - if (HasPendingRequest()) { - FederatedAuthRequestImpl* pending_request = - webid::GetPageData(render_frame_host().GetPage()) - ->PendingWebIdentityRequest(); - - RpMode pending_request_rp_mode = pending_request->GetRpMode(); - RpMode new_request_rp_mode = idp_get_params_ptrs[0]->mode; - fedcm_metrics_->RecordMultipleRequestsRpMode( - pending_request_rp_mode, new_request_rp_mode, idp_order_); - - bool can_replace_pending_request = - had_transient_user_activation_ && - new_request_rp_mode == RpMode::kActive && - pending_request_rp_mode != RpMode::kActive; - if (!can_replace_pending_request) { - // Cancel this new request. - fedcm_metrics_->RecordRequestTokenStatus( - TokenStatus::kTooManyRequests, requirement, idp_order_, - /*num_idps_mismatch=*/0, - /*selected_idp_config_url=*/std::nullopt, - (idp_get_params_ptrs[0]->mode == blink::mojom::RpMode::kActive) - ? RpMode::kActive - : RpMode::kPassive, - /*use_other_account_result=*/std::nullopt, - /*verifying_dialog_result=*/std::nullopt, - api_permission_delegate_->AreThirdPartyCookiesEnabledInSettings() - ? FedCmThirdPartyCookiesStatus::kEnabledInSettings - : FedCmThirdPartyCookiesStatus::kDisabledInSettings, - webid::ComputeRequesterFrameType(render_frame_host(), origin(), - GetEmbeddingOrigin()), - /*has_signin_account=*/std::nullopt); - - AddDevToolsIssue( - blink::mojom::FederatedAuthRequestResult::kTooManyRequests); - AddConsoleErrorMessage( - blink::mojom::FederatedAuthRequestResult::kTooManyRequests); - - std::move(callback).Run(RequestTokenStatus::kErrorTooManyRequests, - std::nullopt, "", /*error=*/nullptr, - /*is_auto_selected=*/false); - - // Since multiple `get` calls is not yet supported, if one IdP invokes the - // API while another request from different IdPs is in-flight, the new API - // call will be rejected. The two requests may be from different RFHs so - // we should calculate properly. - if (old_idp_order.empty()) { - fedcm_metrics_->RecordMultipleRequestsFromDifferentIdPs( - idp_order_ != pending_request->idp_order_); - } else { - fedcm_metrics_->RecordMultipleRequestsFromDifferentIdPs(idp_order_ != - old_idp_order); - } - - // Reset to record kErrorTooManyRequests but recreate to continue - // recording for the pending request. - fedcm_metrics_.reset(); - MaybeCreateFedCmMetrics(); - idp_order_ = std::move(old_idp_order); - return; - } - - // Cancel the pending request before starting the new active flow request. - // Set the old values before completing in case the pending request - // corresponds to one in this object. - std::vector<GURL> new_idp_order = std::move(idp_order_); - idp_order_ = std::move(old_idp_order); - pending_request->CompleteRequestWithError( - FederatedAuthRequestResult::kReplacedByActiveMode, - TokenStatus::kReplacedByActiveMode, - /*should_delay_callback=*/false); - CHECK(!auth_request_token_callback_); - - // Some members were reset to false during CleanUp when replacing a passive - // flow from the same frame so we need to set them again. - had_transient_user_activation_ = true; - MaybeCreateFedCmMetrics(); - idp_order_ = std::move(new_idp_order); + if (HasPendingRequest() && + HandlePendingRequestAndCancelNewRequest( + old_idp_order, idp_get_params_ptrs, requirement)) { + std::move(callback).Run(RequestTokenStatus::kErrorTooManyRequests, + std::nullopt, "", /*error=*/nullptr, + /*is_auto_selected=*/false); + return; } should_complete_request_immediately_ = should_complete_request_immediately; @@ -667,6 +544,7 @@ rp_context, rp_mode, format)); } } + if (any_idp_has_parameters || any_idp_has_custom_scopes) { FedCmRpParameters parameters; if (any_idp_has_custom_scopes && any_idp_has_parameters) { @@ -1045,12 +923,7 @@ } std::move(callback).Run(status); disconnect_request_.reset(); - fedcm_metrics_.reset(); - // If there's an existing auth request token callback, we will need to record - // metrics for it once it is resolved. - if (auth_request_token_callback_) { - MaybeCreateFedCmMetrics(); - } + HandleMetricsForPotentialConcurrentRequests(); } void FederatedAuthRequestImpl::OnClientMetadataResponseReceived( @@ -3335,6 +3208,145 @@ return IsFedCmShowFilteredAccountsEnabled() || accounts_remaining > 0u; } +void FederatedAuthRequestImpl::HandleMetricsForPotentialConcurrentRequests() { + // Record UKM for the request that's completed, either successfully or with + // errors. + // TODO(crbug.com/417784830): fedcm_metrics_ should be bound to each request. + // Otherwise UKMs in a single flow may be recorded in different events. + fedcm_metrics_.reset(); + // If there's an existing auth request token callback, we will need to + // record metrics for it once it is resolved. + if (auth_request_token_callback_) { + MaybeCreateFedCmMetrics(); + } +} + +bool FederatedAuthRequestImpl::ShouldTerminateRequest( + const std::vector<IdentityProviderGetParametersPtr>& idp_get_params_ptrs, + const MediationRequirement& requirement) { + // idp_get_params_ptrs sent from the renderer should be of size 1. + if (idp_get_params_ptrs.size() != 1u) { + ReportBadMessageAndDeleteThis("idp_get_params_ptrs should be of size 1."); + return true; + } + // This could only happen with a compromised renderer process. We ensure that + // the provider list size is > 0 on the renderer side at the beginning of + // parsing |IdentityCredentialRequestOptions|. + for (const auto& idp_get_params_ptr : idp_get_params_ptrs) { + if (idp_get_params_ptr->providers.size() == 0) { + ReportBadMessageAndDeleteThis("The provider list should not be empty."); + return true; + } + if (idp_get_params_ptr->providers.size() > 10u) { + ReportBadMessageAndDeleteThis( + "The provider list should not be greater than 10."); + return true; + } + if (idp_get_params_ptr->mode == RpMode::kActive && + requirement == MediationRequirement::kSilent) { + ReportBadMessageAndDeleteThis( + "mediation: silent is not supported in active mode."); + return true; + } + } + + if (requirement == MediationRequirement::kConditional && + !IsFedCmAutofillEnabled()) { + // The conditional mediation parameter can only be used when delegation + // is enabled while it is under development. + // + // TODO(crbug.com/380367784): handle all of the many cases in which a + // conditional mediation may interact with other features. + ReportBadMessageAndDeleteThis( + "Conditional mediation is not supported when both autofill and " + "delegation are disabled."); + return true; + } + + if (render_frame_host().IsNestedWithinFencedFrame()) { + ReportBadMessageAndDeleteThis( + "FedCM should not be allowed in fenced frame trees."); + return true; + } + + return false; +} + +bool FederatedAuthRequestImpl::HandlePendingRequestAndCancelNewRequest( + const std::vector<GURL>& old_idp_order, + const std::vector<IdentityProviderGetParametersPtr>& idp_get_params_ptrs, + const MediationRequirement& requirement) { + FederatedAuthRequestImpl* pending_request = + webid::GetPageData(render_frame_host().GetPage()) + ->PendingWebIdentityRequest(); + + RpMode pending_request_rp_mode = pending_request->GetRpMode(); + RpMode new_request_rp_mode = idp_get_params_ptrs[0]->mode; + fedcm_metrics_->RecordMultipleRequestsRpMode(pending_request_rp_mode, + new_request_rp_mode, idp_order_); + + bool can_replace_pending_request = had_transient_user_activation_ && + new_request_rp_mode == RpMode::kActive && + pending_request_rp_mode != RpMode::kActive; + if (!can_replace_pending_request) { + // Cancel this new request. + fedcm_metrics_->RecordRequestTokenStatus( + TokenStatus::kTooManyRequests, requirement, idp_order_, + /*num_idps_mismatch=*/0, + /*selected_idp_config_url=*/std::nullopt, + (idp_get_params_ptrs[0]->mode == blink::mojom::RpMode::kActive) + ? RpMode::kActive + : RpMode::kPassive, + /*use_other_account_result=*/std::nullopt, + /*verifying_dialog_result=*/std::nullopt, + api_permission_delegate_->AreThirdPartyCookiesEnabledInSettings() + ? FedCmThirdPartyCookiesStatus::kEnabledInSettings + : FedCmThirdPartyCookiesStatus::kDisabledInSettings, + webid::ComputeRequesterFrameType(render_frame_host(), origin(), + GetEmbeddingOrigin()), + /*has_signin_account=*/std::nullopt); + + AddDevToolsIssue( + blink::mojom::FederatedAuthRequestResult::kTooManyRequests); + AddConsoleErrorMessage( + blink::mojom::FederatedAuthRequestResult::kTooManyRequests); + + // Since multiple `get` calls is not yet supported, if one IdP invokes the + // API while another request from different IdPs is in-flight, the new API + // call will be rejected. The two requests may be from different RFHs so + // we should calculate properly. + if (old_idp_order.empty()) { + fedcm_metrics_->RecordMultipleRequestsFromDifferentIdPs( + idp_order_ != pending_request->idp_order_); + } else { + fedcm_metrics_->RecordMultipleRequestsFromDifferentIdPs(idp_order_ != + old_idp_order); + } + idp_order_ = std::move(old_idp_order); + HandleMetricsForPotentialConcurrentRequests(); + return true; + } + + // Cancel the pending request before starting the new active flow request. + // Set the old values before completing in case the pending request + // corresponds to one in this object. + std::vector<GURL> new_idp_order = std::move(idp_order_); + idp_order_ = std::move(old_idp_order); + pending_request->CompleteRequestWithError( + FederatedAuthRequestResult::kReplacedByActiveMode, + TokenStatus::kReplacedByActiveMode, + /*should_delay_callback=*/false); + CHECK(!auth_request_token_callback_); + + // Some members were reset to false during CleanUp when replacing a passive + // flow from the same frame so we need to set them again. + had_transient_user_activation_ = true; + MaybeCreateFedCmMetrics(); + idp_order_ = std::move(new_idp_order); + + return false; +} + RelyingPartyData FederatedAuthRequestImpl::CreateRpData() const { // We want to show the iframe origin if any IDP requests it. bool show_iframe_origin = false;
diff --git a/content/browser/webid/federated_auth_request_impl.h b/content/browser/webid/federated_auth_request_impl.h index 00a3a3c..e17bd57 100644 --- a/content/browser/webid/federated_auth_request_impl.h +++ b/content/browser/webid/federated_auth_request_impl.h
@@ -52,6 +52,7 @@ class FederatedIdentityPermissionContextDelegate; class RenderFrameHost; +using blink::mojom::IdentityProviderGetParametersPtr; using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>; using IdentityRequestAccountPtr = scoped_refptr<content::IdentityRequestAccount>; @@ -389,6 +390,27 @@ blink::mojom::FederatedAuthRequestResult result); void SendSuccessfulTokenRequestMetrics(const GURL& idp_config_url); + // When two APIs that are associated with the same frame, hence + // fedcm_metrics_, are triggered concurrently, we need to reset + // `fedcm_metrics` to record UKM for the first request when it's completed and + // recreate one for the second if needed. + void HandleMetricsForPotentialConcurrentRequests(); + + // Validates the input from the renderer and signals to terminate the request + // if needed. + bool ShouldTerminateRequest( + const std::vector<IdentityProviderGetParametersPtr>& idp_get_params_ptrs, + const MediationRequirement& requirement); + + // If a new request is associated with active mode, it can replace the pending + // request with passive mode. Otherwise a new request will be cancelled when + // there's a pending request. Returns `true` if the new request needs to be + // cancelled. + bool HandlePendingRequestAndCancelNewRequest( + const std::vector<GURL>& old_idp_order, + const std::vector<IdentityProviderGetParametersPtr>& idps, + const MediationRequirement& requirement); + void CleanUp(); std::unique_ptr<IdpNetworkRequestManager> CreateNetworkManager();
diff --git a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt index f016086..a31c4136 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
@@ -148,37 +148,6 @@ # Same with prefer-hardware crbug.com/371802469 [ amd-0x7340 angle-opengl asan graphite-disabled mac ] WebCodecs_Encode_camera_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -# Flaky crashes that started when upgrading to Mac 15.4 -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_ContentHint_hvc1.1.6.L123.00_detail [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_ContentHint_hvc1.1.6.L123.00_motion [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodeColorSpace_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodeDecode_arraybuffer_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodeDecode_camera_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodeDecode_capture_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodeDecode_hw_decoder_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodeDecode_offscreen_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodeDecode_sw_decoder_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_Encode_arraybuffer_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_Encode_camera_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_Encode_capture_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_Encode_hw_decoder_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_Encode_offscreen_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_Encode_sw_decoder_hvc1.1.6.L123.00_prefer-hardware [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodingFramerateResolutions_1920x1080_120_hvc1.1.6.L186.B0_prefer-hardware_quality [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodingFramerateResolutions_1920x1080_30_hvc1.1.6.L186.B0_prefer-hardware_quality [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodingFramerateResolutions_1920x1080_60_hvc1.1.6.L186.B0_prefer-hardware_quality [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodingFramerateResolutions_3840x2160_120_hvc1.1.6.L186.B0_prefer-hardware_quality [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodingFramerateResolutions_3840x2160_30_hvc1.1.6.L186.B0_prefer-hardware_quality [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodingFramerateResolutions_3840x2160_60_hvc1.1.6.L186.B0_prefer-hardware_quality [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodingModes_offscreen_hvc1.1.6.L123.00_prefer-hardware_constant_quality [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodingRateControl_hvc1.1.6.L123.00_prefer-hardware_constant_1500000 [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodingRateControl_hvc1.1.6.L123.00_prefer-hardware_variable_1500000 [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_EncodingRateControl_hvc1.1.6.L123.00_prefer-hardware_variable_2000000 [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_FrameSizeChange_hvc1.1.6.L123.00_arraybuffer [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_FrameSizeChange_hvc1.1.6.L123.00_capture [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_FrameSizeChange_hvc1.1.6.L123.00_hw_decoder [ Failure ] -crbug.com/416294710 [ sequoia intel-0x3e9b ] WebCodecs_FrameSizeChange_hvc1.1.6.L123.00_offscreen [ Failure ] - crbug.com/389978730 [ win11 nvidia-0x2783 ] WebCodecs_EncodeColorSpace_av01.0.04M.08_prefer-hardware [ Failure ] # Win/AMD RX 7600 Failures
diff --git a/extensions/common/api/extension_action/action_info.cc b/extensions/common/api/extension_action/action_info.cc index be3b3ee..6f71f1ef 100644 --- a/extensions/common/api/extension_action/action_info.cc +++ b/extensions/common/api/extension_action/action_info.cc
@@ -163,22 +163,13 @@ } if (!url_str->empty()) { - GURL popup_url = Extension::GetResourceURL(extension->url(), *url_str); - + GURL popup_url = extension->GetResourceURL(*url_str); if (!popup_url.is_valid()) { *error = errors::kInvalidActionDefaultPopup; return nullptr; } - // Check popup is only for this extension. - if (extension->origin().IsSameOriginWith(popup_url)) { - result->default_popup_url = popup_url; - } else { - install_warnings->emplace_back( - extensions::manifest_errors::kInvalidExtensionOriginPopup, - GetManifestKeyForActionType(type), - extensions::manifest_keys::kActionDefaultPopup); - } + result->default_popup_url = popup_url; } else { // An empty string is treated as having no popup. DCHECK(result->default_popup_url.is_empty());
diff --git a/extensions/common/extension.cc b/extensions/common/extension.cc index 6563b56..f82aaf92 100644 --- a/extensions/common/extension.cc +++ b/extensions/common/extension.cc
@@ -308,9 +308,14 @@ // static GURL Extension::GetResourceURL(const GURL& extension_url, - std::string_view relative_path) { + std::string_view relative_url) { DCHECK(extension_url.SchemeIs(kExtensionScheme)); - return extension_url.Resolve(relative_path); + GURL resolved = extension_url.Resolve(relative_url); + if (!url::IsSameOriginWith(resolved, extension_url)) { + return GURL(); + } + + return resolved; } bool Extension::ResourceMatches(const URLPatternSet& pattern_set,
diff --git a/extensions/common/extension.h b/extensions/common/extension.h index 0235f821..ec776e62 100644 --- a/extensions/common/extension.h +++ b/extensions/common/extension.h
@@ -160,13 +160,21 @@ // See Type definition in Manifest. Manifest::Type GetType() const; - // Returns an absolute url to a resource inside of an extension. The + // Returns an absolute URL to a resource inside of an extension. The // `extension_url` argument should be the url() from an Extension object. The - // `relative_path` can be untrusted user input. The returned URL will either - // be invalid() or a child of `extension_url`. + // `relative_url` can be untrusted user input. The returned URL will either be + // invalid() or a child of `extension_url`. + // + // Note that `relative_url` is treated as a URL-encoded string, e.g. "%21.txt" + // will refer to the "!.txt" file. Any query or fragment components in + // `relative_url` are included in the returned URL. + // + // `relative_url` may be an absolute URL as long as it is a child of + // `extension_url`. + // // NOTE: Static so that it can be used from multiple threads. static GURL GetResourceURL(const GURL& extension_url, - std::string_view relative_path); + std::string_view relative_url); GURL GetResourceURL(std::string_view relative_path) const { return GetResourceURL(url(), relative_path); }
diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h index 4869978..8dc058a0 100644 --- a/extensions/common/manifest_constants.h +++ b/extensions/common/manifest_constants.h
@@ -368,9 +368,9 @@ "Empty 'export.allowlist' implies any extension can import this module."; inline constexpr char kInvalidExportAllowlistString[] = "Invalid value for 'export.allowlist[*]'."; -inline constexpr char kInvalidExtensionOriginPopup[] = - "The default_popup path specified in the manifest is invalid. Ensure it is " - "a path to a file in this extension."; +inline constexpr char kInvalidExtensionPopupPath[] = + "The specified popup path is invalid. Ensure it is a path to a file in " + "this extension."; inline constexpr char16_t kInvalidFileAccessList[] = u"Invalid value for 'file_access'."; inline constexpr char kInvalidFileAccessValue[] = @@ -426,7 +426,7 @@ inline constexpr char kInvalidImportVersion[] = "Invalid value for 'import[*].minimum_version'."; inline constexpr char kInvalidImportRepeatedImport[] = - "There are multiple occurences of the same extension ID in 'import'. Only " + "There are multiple occurrences of the same extension ID in 'import'. Only " "one version will be installed."; inline constexpr char kInvalidInputComponents[] = "Invalid value for 'input_components'"; @@ -436,7 +436,8 @@ "Invalid value for 'input_components[*].layouts[*]"; inline constexpr char kInvalidInputComponentName[] = "Invalid value for 'input_components[*].name"; -inline constexpr char kInvalidInputView[] = "Invalid value for 'input_view'."; +inline constexpr char kInvalidInputView[] = + "Invalid value for 'input_components[*].input_view'."; inline constexpr char16_t kInvalidIsolation[] = u"Invalid value for 'app.isolation'."; inline constexpr char kInvalidIsolationValue[] = @@ -532,7 +533,8 @@ u"Invalid value for 'oauth2.client_id'."; inline constexpr char16_t kInvalidOfflineEnabled[] = u"Invalid value for 'offline_enabled'."; -inline constexpr char kInvalidOptionsPage[] = "Invalid value for '*'."; +inline constexpr char kInvalidOptionsPage[] = + "Invalid value for 'input_components[*].options_page'."; inline constexpr char16_t kInvalidOptionsPageExpectUrlInPackage[] = u"Invalid value for 'options_page'. Value must be a relative path."; inline constexpr char16_t kInvalidOptionsPageInHostedApp[] =
diff --git a/extensions/common/manifest_handlers/extension_action_handler_unittest.cc b/extensions/common/manifest_handlers/extension_action_handler_unittest.cc index 134db6ee..84556f9 100644 --- a/extensions/common/manifest_handlers/extension_action_handler_unittest.cc +++ b/extensions/common/manifest_handlers/extension_action_handler_unittest.cc
@@ -197,7 +197,8 @@ scoped_refptr<Extension> LoadExtensionWithDefaultPopup( const char* popup_file_name, int manifest_version, - TestExtensionDir* test_extension_dir) { + TestExtensionDir* test_extension_dir, + std::string* error) { const char* action_key = ActionInfo::GetManifestKeyForActionType(GetParam()); @@ -211,11 +212,9 @@ manifest_version, action_key, popup_file_name)); test_extension_dir->WriteFile(FILE_PATH_LITERAL("popup.html"), ""); - std::string error; scoped_refptr<Extension> extension(file_util::LoadExtension( test_extension_dir->UnpackedPath(), mojom::ManifestLocation::kUnpacked, - Extension::NO_FLAGS, &error)); - EXPECT_EQ(error, ""); + Extension::NO_FLAGS, error)); return extension; } }; @@ -334,11 +333,25 @@ constexpr char valid_popup_file_name[] = "popup.html"; TestExtensionDir test_extension_dir = TestExtensionDir(); int manifest_version = GetManifestVersionForActionType(GetParam()); + std::string error; scoped_refptr<Extension> test_extension = LoadExtensionWithDefaultPopup( - valid_popup_file_name, manifest_version, &test_extension_dir); - ASSERT_TRUE(test_extension); - EXPECT_FALSE(warnings_test_util::HasInstallWarning( - test_extension, manifest_errors::kInvalidExtensionOriginPopup)); + valid_popup_file_name, manifest_version, &test_extension_dir, &error); + ASSERT_TRUE(test_extension) << error; + + std::vector<InstallWarning> warnings; + if (GetParam() == ActionInfo::Type::kBrowser) { + warnings.emplace_back("Unrecognized manifest key 'browser_action'."); + } + if (manifest_version == 2) { + warnings.emplace_back(manifest_errors::kManifestV2IsDeprecatedWarning); + } + EXPECT_EQ(warnings, test_extension->install_warnings()); + + const ActionInfo* action_info = + GetActionInfoOfType(*test_extension, GetParam()); + ASSERT_TRUE(action_info); + EXPECT_EQ(test_extension->GetResourceURL("popup.html"), + action_info->default_popup_url); } // Tests success when default_popup is empty. @@ -346,11 +359,24 @@ constexpr char empty_popup_file_name[] = ""; TestExtensionDir test_extension_dir = TestExtensionDir(); int manifest_version = GetManifestVersionForActionType(GetParam()); + std::string error; scoped_refptr<Extension> test_extension = LoadExtensionWithDefaultPopup( - empty_popup_file_name, manifest_version, &test_extension_dir); - ASSERT_TRUE(test_extension); - EXPECT_FALSE(warnings_test_util::HasInstallWarning( - test_extension, manifest_errors::kInvalidExtensionOriginPopup)); + empty_popup_file_name, manifest_version, &test_extension_dir, &error); + ASSERT_TRUE(test_extension) << error; + + std::vector<InstallWarning> warnings; + if (GetParam() == ActionInfo::Type::kBrowser) { + warnings.emplace_back("Unrecognized manifest key 'browser_action'."); + } + if (manifest_version == 2) { + warnings.emplace_back(manifest_errors::kManifestV2IsDeprecatedWarning); + } + EXPECT_EQ(warnings, test_extension->install_warnings()); + + const ActionInfo* action_info = + GetActionInfoOfType(*test_extension, GetParam()); + ASSERT_TRUE(action_info); + EXPECT_TRUE(action_info->default_popup_url.is_empty()); } // Tests warning when the default_popup seems to be for another extension. @@ -359,12 +385,13 @@ "chrome-extension://abcdefghijklmnopqrstuvwxyzabcdef/popup.html"; TestExtensionDir test_extension_dir = TestExtensionDir(); int manifest_version = GetManifestVersionForActionType(GetParam()); - scoped_refptr<Extension> test_extension = - LoadExtensionWithDefaultPopup(other_extension_specified_popup_file_name, - manifest_version, &test_extension_dir); - ASSERT_TRUE(test_extension); - EXPECT_TRUE(warnings_test_util::HasInstallWarning( - test_extension, manifest_errors::kInvalidExtensionOriginPopup)); + std::string error; + scoped_refptr<Extension> test_extension = LoadExtensionWithDefaultPopup( + other_extension_specified_popup_file_name, manifest_version, + &test_extension_dir, &error); + ASSERT_FALSE(test_extension); + ASSERT_EQ(base::UTF16ToUTF8(manifest_errors::kInvalidActionDefaultPopup), + error); } // Tests warning when the default_popup doesn't exist on file system. @@ -372,11 +399,27 @@ constexpr char nonexistent_popup_file_name[] = "nonexistent_popup.html"; TestExtensionDir test_extension_dir = TestExtensionDir(); int manifest_version = GetManifestVersionForActionType(GetParam()); + std::string error; scoped_refptr<Extension> test_extension = LoadExtensionWithDefaultPopup( - nonexistent_popup_file_name, manifest_version, &test_extension_dir); - ASSERT_TRUE(test_extension); - EXPECT_TRUE(warnings_test_util::HasInstallWarning( - test_extension, manifest_errors::kNonexistentDefaultPopup)); + nonexistent_popup_file_name, manifest_version, &test_extension_dir, + &error); + ASSERT_TRUE(test_extension) << error; + + std::vector<InstallWarning> warnings; + if (GetParam() == ActionInfo::Type::kBrowser) { + warnings.emplace_back("Unrecognized manifest key 'browser_action'."); + } + if (manifest_version == 2) { + warnings.emplace_back(manifest_errors::kManifestV2IsDeprecatedWarning); + } + warnings.emplace_back(manifest_errors::kNonexistentDefaultPopup); + EXPECT_EQ(warnings, test_extension->install_warnings()); + + const ActionInfo* action_info = + GetActionInfoOfType(*test_extension, GetParam()); + ASSERT_TRUE(action_info); + EXPECT_EQ(test_extension->GetResourceURL("nonexistent_popup.html"), + action_info->default_popup_url); } // Test the handling of the default_state key.
diff --git a/extensions/common/manifest_handlers/webview_info.cc b/extensions/common/manifest_handlers/webview_info.cc index 2e1318ba..0aede66 100644 --- a/extensions/common/manifest_handlers/webview_info.cc +++ b/extensions/common/manifest_handlers/webview_info.cc
@@ -169,13 +169,10 @@ return false; } - GURL pattern_url = - Extension::GetResourceURL(extension->url(), item.GetString()); + GURL pattern_url = extension->GetResourceURL(item.GetString()); // If passed a non-relative URL (like http://example.com), - // Extension::GetResourceURL() will return that URL directly. (See - // https://crbug.com/1135236). Check if this happened by comparing the - // host. - if (pattern_url.host_piece() != extension->id()) { + // Extension::GetResourceURL() will return an invalid URL. + if (!pattern_url.is_valid()) { // NOTE: Warning instead of error because there are existing apps that // have this bug, and we don't want to hard-error on them. // https://crbug.com/856948.
diff --git a/extensions/renderer/api/core_extensions_renderer_api_provider.cc b/extensions/renderer/api/core_extensions_renderer_api_provider.cc index 3ed51366..75b5db9f4 100644 --- a/extensions/renderer/api/core_extensions_renderer_api_provider.cc +++ b/extensions/renderer/api/core_extensions_renderer_api_provider.cc
@@ -164,7 +164,6 @@ } js_resources[] = { {"appView", IDR_APP_VIEW_JS}, {"appViewElement", IDR_APP_VIEW_ELEMENT_JS}, - {"appViewDeny", IDR_APP_VIEW_DENY_JS}, {"entryIdManager", IDR_ENTRY_ID_MANAGER}, {"extensionOptions", IDR_EXTENSION_OPTIONS_JS}, {"extensionOptionsElement", IDR_EXTENSION_OPTIONS_ELEMENT_JS}, @@ -175,6 +174,10 @@ {"fileEntryBindingUtil", IDR_FILE_ENTRY_BINDING_UTIL_JS}, {"fileSystem", IDR_FILE_SYSTEM_CUSTOM_BINDINGS_JS}, +#if BUILDFLAG(ENABLE_PLATFORM_APPS) + {"appViewDeny", IDR_APP_VIEW_DENY_JS}, +#endif + #if BUILDFLAG(ENABLE_GUEST_VIEW) {"guestView", IDR_GUEST_VIEW_JS}, {"guestViewAttributes", IDR_GUEST_VIEW_ATTRIBUTES_JS},
diff --git a/ios/chrome/browser/authentication/ui_bundled/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_mediator.mm b/ios/chrome/browser/authentication/ui_bundled/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_mediator.mm index e0e171bb..4d84506 100644 --- a/ios/chrome/browser/authentication/ui_bundled/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_mediator.mm +++ b/ios/chrome/browser/authentication/ui_bundled/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_mediator.mm
@@ -156,6 +156,8 @@ kHistorySyncOptinExpansionPillOnInactivity: case signin_metrics::AccessPoint::kHistorySyncEducationalTip: case signin_metrics::AccessPoint::kManagedProfileAutoSigninIos: + case signin_metrics::AccessPoint::kNonModalSigninPasswordPromo: + case signin_metrics::AccessPoint::kNonModalSigninBookmarkPromo: // Nothing prevents instantiating ConsistencyDefaultAccountViewController // with an arbitrary entry point, API-wise. In doubt, no label is a good, // generic default that fits all entry points.
diff --git a/ios/chrome/browser/authentication/ui_bundled/signin_promo/coordinator/non_modal_signin_promo_coordinator.mm b/ios/chrome/browser/authentication/ui_bundled/signin_promo/coordinator/non_modal_signin_promo_coordinator.mm index df11d06..149dd42 100644 --- a/ios/chrome/browser/authentication/ui_bundled/signin_promo/coordinator/non_modal_signin_promo_coordinator.mm +++ b/ios/chrome/browser/authentication/ui_bundled/signin_promo/coordinator/non_modal_signin_promo_coordinator.mm
@@ -238,12 +238,23 @@ [self hideBannerUI]; + // Select the appropriate access point based on promo type + signin_metrics::AccessPoint accessPoint; + switch (_promoType) { + case SignInPromoType::kPassword: + accessPoint = signin_metrics::AccessPoint::kNonModalSigninPasswordPromo; + break; + case SignInPromoType::kBookmark: + accessPoint = signin_metrics::AccessPoint::kNonModalSigninBookmarkPromo; + break; + } + id<ApplicationCommands> handler = HandlerForProtocol( self.browser->GetCommandDispatcher(), ApplicationCommands); ShowSigninCommand* const showSigninCommand = [[ShowSigninCommand alloc] initWithOperation:AuthenticationOperation::kSheetSigninAndHistorySync identity:nil - accessPoint:signin_metrics::AccessPoint::kNtpSignedOutIcon + accessPoint:accessPoint promoAction:signin_metrics::PromoAction:: PROMO_ACTION_NO_SIGNIN_PROMO completion:nil];
diff --git a/ios/chrome/browser/authentication/ui_bundled/signin_promo_view_mediator.mm b/ios/chrome/browser/authentication/ui_bundled/signin_promo_view_mediator.mm index a1e7759..736495a8 100644 --- a/ios/chrome/browser/authentication/ui_bundled/signin_promo_view_mediator.mm +++ b/ios/chrome/browser/authentication/ui_bundled/signin_promo_view_mediator.mm
@@ -138,6 +138,8 @@ kHistorySyncOptinExpansionPillOnInactivity: case signin_metrics::AccessPoint::kHistorySyncEducationalTip: case signin_metrics::AccessPoint::kManagedProfileAutoSigninIos: + case signin_metrics::AccessPoint::kNonModalSigninPasswordPromo: + case signin_metrics::AccessPoint::kNonModalSigninBookmarkPromo: return false; } } @@ -236,6 +238,8 @@ kHistorySyncOptinExpansionPillOnInactivity: case signin_metrics::AccessPoint::kHistorySyncEducationalTip: case signin_metrics::AccessPoint::kManagedProfileAutoSigninIos: + case signin_metrics::AccessPoint::kNonModalSigninPasswordPromo: + case signin_metrics::AccessPoint::kNonModalSigninBookmarkPromo: NOTREACHED() << "Unexpected value for access point " << static_cast<int>(access_point); } @@ -335,6 +339,8 @@ kHistorySyncOptinExpansionPillOnInactivity: case signin_metrics::AccessPoint::kHistorySyncEducationalTip: case signin_metrics::AccessPoint::kManagedProfileAutoSigninIos: + case signin_metrics::AccessPoint::kNonModalSigninPasswordPromo: + case signin_metrics::AccessPoint::kNonModalSigninBookmarkPromo: NOTREACHED() << "Unexpected value for access point " << static_cast<int>(access_point); } @@ -423,6 +429,8 @@ kHistorySyncOptinExpansionPillOnInactivity: case signin_metrics::AccessPoint::kHistorySyncEducationalTip: case signin_metrics::AccessPoint::kManagedProfileAutoSigninIos: + case signin_metrics::AccessPoint::kNonModalSigninPasswordPromo: + case signin_metrics::AccessPoint::kNonModalSigninBookmarkPromo: return nullptr; } } @@ -510,6 +518,8 @@ kHistorySyncOptinExpansionPillOnInactivity: case signin_metrics::AccessPoint::kHistorySyncEducationalTip: case signin_metrics::AccessPoint::kManagedProfileAutoSigninIos: + case signin_metrics::AccessPoint::kNonModalSigninPasswordPromo: + case signin_metrics::AccessPoint::kNonModalSigninBookmarkPromo: return nullptr; } }
diff --git a/ios/chrome/browser/settings/ui_bundled/downloads/BUILD.gn b/ios/chrome/browser/settings/ui_bundled/downloads/BUILD.gn index f1c0e87..e29f0ce 100644 --- a/ios/chrome/browser/settings/ui_bundled/downloads/BUILD.gn +++ b/ios/chrome/browser/settings/ui_bundled/downloads/BUILD.gn
@@ -72,6 +72,7 @@ "//ios/chrome/browser/authentication/ui_bundled/signin:constants", "//ios/chrome/browser/authentication/ui_bundled/signin:constants", "//ios/chrome/browser/authentication/ui_bundled/signin:signin_headers", + "//ios/chrome/browser/authentication/ui_bundled/signin/add_account_signin", "//ios/chrome/browser/authentication/ui_bundled/views", "//ios/chrome/browser/photos/model:photos_service_factory", "//ios/chrome/browser/settings/ui_bundled/downloads:identity_button_cell",
diff --git a/ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_coordinator.mm b/ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_coordinator.mm index 8229cd6..25f7194 100644 --- a/ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_coordinator.mm +++ b/ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_coordinator.mm
@@ -5,7 +5,9 @@ #import "ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_coordinator.h" #import "components/prefs/pref_service.h" +#import "ios/chrome/browser/authentication/ui_bundled/continuation.h" #import "ios/chrome/browser/authentication/ui_bundled/signin/signin_constants.h" +#import "ios/chrome/browser/authentication/ui_bundled/signin/signin_coordinator.h" #import "ios/chrome/browser/download/coordinator/auto_deletion/auto_deletion_settings_mediator.h" #import "ios/chrome/browser/photos/model/photos_service.h" #import "ios/chrome/browser/photos/model/photos_service_factory.h" @@ -47,6 +49,8 @@ // Auto deletion settings mediator. AutoDeletionSettingsMediator* _autoDeletionSettingsMediator; + // The signin coordinator, if it is opened. + SigninCoordinator* _signinCoordinator; } @synthesize baseNavigationController = _baseNavigationController; @@ -103,6 +107,7 @@ } - (void)stop { + [self stopSigninCoordinator]; [_saveToPhotosSettingsMediator disconnect]; _saveToPhotosSettingsMediator = nil; @@ -159,26 +164,39 @@ #pragma mark - SaveToPhotosSettingsAccountSelectionViewControllerActionDelegate - (void)saveToPhotosSettingsAccountSelectionViewControllerAddAccount { - id<ApplicationCommands> applicationCommandsHandler = HandlerForProtocol( - self.browser->GetCommandDispatcher(), ApplicationCommands); + SigninContextStyle contextStyle = SigninContextStyle::kDefault; + signin_metrics::AccessPoint accessPoint = + signin_metrics::AccessPoint::kSaveToPhotosIos; + __weak __typeof(self) weakSelf = self; - ShowSigninCommand* addAccountCommand = [[ShowSigninCommand alloc] - initWithOperation:AuthenticationOperation::kAddAccount - identity:nil - accessPoint:signin_metrics::AccessPoint::kSaveToPhotosIos - promoAction:signin_metrics::PromoAction:: - PROMO_ACTION_NO_SIGNIN_PROMO - completion:^(SigninCoordinatorResult result, - id<SystemIdentity> signinIdentity) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - if (strongSelf && result == SigninCoordinatorResultSuccess && - signinIdentity) { - [strongSelf->_saveToPhotosSettingsMediator - setSelectedIdentityGaiaID:signinIdentity.gaiaID]; - } - }]; - [applicationCommandsHandler showSignin:addAccountCommand - baseViewController:self.baseViewController]; + _signinCoordinator = [SigninCoordinator + addAccountCoordinatorWithBaseViewController:self.baseViewController + browser:self.browser + contextStyle:contextStyle + accessPoint:accessPoint + continuationProvider: + DoNothingContinuationProvider()]; + _signinCoordinator.signinCompletion = ^(SigninCoordinatorResult result, + id<SystemIdentity> signinIdentity) { + [weakSelf signinCoordinatorCompletion:result signinIdentity:signinIdentity]; + }; + [_signinCoordinator start]; +} + +#pragma mark - Private + +- (void)stopSigninCoordinator { + [_signinCoordinator stop]; + _signinCoordinator = nil; +} + +- (void)signinCoordinatorCompletion:(SigninCoordinatorResult)result + signinIdentity:(id<SystemIdentity>)signinIdentity { + [self stopSigninCoordinator]; + if (result == SigninCoordinatorResultSuccess && signinIdentity) { + [_saveToPhotosSettingsMediator + setSelectedIdentityGaiaID:signinIdentity.gaiaID]; + } } @end
diff --git a/ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_coordinator_unittest.mm b/ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_coordinator_unittest.mm index 0203084..6feb192 100644 --- a/ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_coordinator_unittest.mm +++ b/ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_coordinator_unittest.mm
@@ -6,7 +6,10 @@ #import "base/apple/foundation_util.h" #import "components/signin/public/identity_manager/identity_test_environment.h" +#import "ios/chrome/browser/authentication/ui_bundled/continuation.h" +#import "ios/chrome/browser/authentication/ui_bundled/signin/add_account_signin/add_account_signin_coordinator.h" #import "ios/chrome/browser/authentication/ui_bundled/signin/signin_constants.h" +#import "ios/chrome/browser/authentication/ui_bundled/signin/signin_coordinator.h" #import "ios/chrome/browser/photos/model/photos_service_factory.h" #import "ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_table_view_controller.h" #import "ios/chrome/browser/settings/ui_bundled/downloads/downloads_settings_table_view_controller_action_delegate.h" @@ -52,11 +55,6 @@ base_navigation_controller_ = [[FakeUINavigationController alloc] init]; - mock_application_commands_handler_ = - OCMStrictProtocolMock(@protocol(ApplicationCommands)); - [browser_->GetCommandDispatcher() - startDispatchingToTarget:mock_application_commands_handler_ - forProtocol:@protocol(ApplicationCommands)]; mock_settings_commands_handler_ = OCMStrictProtocolMock(@protocol(SettingsCommands)); [browser_->GetCommandDispatcher() @@ -143,7 +141,6 @@ id mock_save_to_photos_settings_mediator_; id mock_downloads_settings_table_view_controller_; id mock_save_to_photos_settings_account_selection_view_controller_; - id mock_application_commands_handler_; id mock_settings_commands_handler_; }; @@ -311,27 +308,33 @@ CreateMockDownloadsSettingsTableViewControllerStubbed(true); CreateMockSaveToPhotosSettingsAccountSelectionViewControllerStubbed(true); [coordinator start]; + AddAccountSigninCoordinator* signin_coordinator_mock = + OCMClassMock([AddAccountSigninCoordinator class]); + OCMExpect([(id)signin_coordinator_mock alloc]) + .andReturn(signin_coordinator_mock); + OCMExpect([signin_coordinator_mock + initWithBaseViewController:[OCMArg any] + browser:browser_.get() + contextStyle:SigninContextStyle::kDefault + accessPoint:signin_metrics::AccessPoint:: + kSaveToPhotosIos + promoAction:signin_metrics::PromoAction:: + PROMO_ACTION_NO_SIGNIN_PROMO + signinIntent:AddAccountSigninIntent::kAddAccount + continuationProvider:DoNothingContinuationProvider()]) + .ignoringNonObjectArgs() + .andReturn(signin_coordinator_mock); // Expect that a ShowSigninCommand is dispatched to show the Add account view // when -saveToPhotosSettingsAccountSelectionViewControllerAddAccount is // called. __block SigninCoordinatorCompletionCallback show_signin_callback = nil; - OCMExpect([mock_application_commands_handler_ - showSignin:[OCMArg checkWithBlock:^BOOL( - ShowSigninCommand* command) { - EXPECT_TRUE(command.completion); - show_signin_callback = command.completion; - EXPECT_EQ(AuthenticationOperation::kAddAccount, - command.operation); - EXPECT_FALSE(command.identity); - EXPECT_EQ(signin_metrics::AccessPoint::kSaveToPhotosIos, - command.accessPoint); - EXPECT_EQ( - signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO, - command.promoAction); - return YES; - }] - baseViewController:base_navigation_controller_]); + + OCMExpect([signin_coordinator_mock + setSigninCompletion:[OCMArg checkWithBlock:^BOOL(id value) { + show_signin_callback = value; + return YES; + }]]); // Call the coordinator through the action delegate protocol and verify the // ShowSigninCommand was dispatched. @@ -343,7 +346,6 @@ id<SaveToPhotosSettingsAccountSelectionViewControllerActionDelegate>>( coordinator) saveToPhotosSettingsAccountSelectionViewControllerAddAccount]; - EXPECT_OCMOCK_VERIFY(mock_application_commands_handler_); // Expect that the selected identity Gaia ID is set to the Gaia ID of the // identity that was just added.
diff --git a/media/gpu/mac/vt_video_encode_accelerator_mac.mm b/media/gpu/mac/vt_video_encode_accelerator_mac.mm index d861be61..215c4bb 100644 --- a/media/gpu/mac/vt_video_encode_accelerator_mac.mm +++ b/media/gpu/mac/vt_video_encode_accelerator_mac.mm
@@ -720,12 +720,17 @@ std::move(frame), encoder_color_space_.value_or(gfx::ColorSpace()), frame_qp); - // We can pass the ownership of |request| to the encode callback if - // successful. Otherwise let it fall out of scope. + // Pass the ownership of `request` to the encode callback, then release the + // smart pointer. + // + // NOTE: When encoding fails, VT still holds the `sourceFrameRefcon`, and + // either the `CompressionCallback` or VT itself may still use this resource + // afterwards. Therefore, we always release the smart pointer here. OSStatus status = VTCompressionSessionEncodeFrame( compression_session_.get(), pixel_buffer.get(), timestamp_cm, duration_cm, - NSToCFPtrCast(frame_props), reinterpret_cast<void*>(request.get()), + NSToCFPtrCast(frame_props), reinterpret_cast<void*>(request.release()), nullptr); + ++pending_encodes_; if (status == kVTVideoEncoderNotAvailableNowErr || status == kVTCouldNotCreateInstanceErr) { NotifyErrorStatus({EncoderStatus::Codes::kOutOfPlatformEncoders, @@ -739,10 +744,6 @@ logging::DescriptionFromOSStatus(status)}); return; } - ++pending_encodes_; - // We successfully passed ownership to `sourceFrameRefcon` parameter - // of `VTCompressionSessionEncodeFrame`, release the smart pointer. - request.release(); } void VTVideoEncodeAccelerator::UseOutputBitstreamBuffer(
diff --git a/net/BUILD.gn b/net/BUILD.gn index 846e9c60..9391062 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -611,6 +611,8 @@ "http/http_cache.h", "http/http_cache_transaction.cc", "http/http_cache_transaction.h", + "http/http_cache_util.cc", + "http/http_cache_util.h", "http/http_cache_writers.cc", "http/http_cache_writers.h", "http/http_chunked_decoder.cc",
diff --git a/net/device_bound_sessions/session_usage.h b/net/device_bound_sessions/session_usage.h index 45fc9793..972d7b59 100644 --- a/net/device_bound_sessions/session_usage.h +++ b/net/device_bound_sessions/session_usage.h
@@ -10,6 +10,9 @@ // Represents per-request usage of a session for populating use // counters. This currently has the invariant that requests only move // from lower-valued usage enums to higher-valued ones. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +// LINT.IfChange(DeviceBoundSessionUsage) enum class SessionUsage { // Usage is unknown kUnknown = 0, @@ -19,7 +22,9 @@ kInScopeNotDeferred = 2, // Request was deferred by a session kDeferred = 3, + kMaxValue = kDeferred }; +// LINT.ThenChange(//tools/metrics/histograms/metadata/net/enums.xml:DeviceBoundSessionUsage) } // namespace net::device_bound_sessions
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index e64a3398..fdc71064 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc
@@ -55,6 +55,7 @@ #include "net/disk_cache/disk_cache.h" #include "net/disk_cache/memory_entry_data_hints.h" #include "net/http/http_cache.h" +#include "net/http/http_cache_util.h" #include "net/http/http_cache_writers.h" #include "net/http/http_log_util.h" #include "net/http/http_network_session.h" @@ -101,63 +102,6 @@ written_at_run_id.value() < clear_at_run_id.value()); } -// If the request includes one of these request headers, then avoid caching -// to avoid getting confused. -struct HeaderNameAndValue { - std::string_view name; - std::optional<std::string_view> value; -}; - -// If the request includes one of these request headers, then avoid caching -// to avoid getting confused. -constexpr auto kPassThroughHeaders = std::to_array( - {HeaderNameAndValue{"if-unmodified-since", - std::nullopt}, // causes unexpected 412s - HeaderNameAndValue{"if-match", std::nullopt}, // causes unexpected 412s - HeaderNameAndValue{"if-range", std::nullopt}}); - -struct ValidationHeaderInfo { - std::string_view request_header_name; - std::string_view related_response_header_name; -}; - -constexpr auto kValidationHeaders = std::to_array<ValidationHeaderInfo>( - {{"if-modified-since", "last-modified"}, {"if-none-match", "etag"}}); - -// If the request includes one of these request headers, then avoid reusing -// our cached copy if any. -constexpr auto kForceFetchHeaders = - std::to_array({HeaderNameAndValue{"cache-control", "no-cache"}, - HeaderNameAndValue{"pragma", "no-cache"}}); - -// If the request includes one of these request headers, then force our -// cached copy (if any) to be revalidated before reusing it. -constexpr auto kForceValidateHeaders = - std::to_array({HeaderNameAndValue{"cache-control", "max-age=0"}}); - -bool HeaderMatches(const HttpRequestHeaders& headers, - base::span<const HeaderNameAndValue> search_headers) { - for (const auto& search_header : search_headers) { - std::optional<std::string> header_value = - headers.GetHeader(search_header.name); - if (!header_value) { - continue; - } - - if (!search_header.value) { - return true; - } - - HttpUtil::ValuesIterator v(*header_value, ','); - while (v.GetNext()) { - if (base::EqualsCaseInsensitiveASCII(v.value(), *search_header.value)) { - return true; - } - } - } - return false; -} - // Methods other than "GET" or "HEAD" can have request bodies, which causes // problems for the request matching. // TODO(https://crbug.com/390459312): Consider supporting additional methods. @@ -181,10 +125,6 @@ priority_(priority), cache_(cache->GetWeakPtr()), read_no_vary_search_cache_(cache->no_vary_search_cache_) { - static_assert(HttpCache::Transaction::kNumValidationHeaders == - std::size(kValidationHeaders), - "invalid number of validation headers"); - io_callback_ = base::BindRepeating(&Transaction::OnIOComplete, weak_factory_.GetWeakPtr()); cache_io_callback_ = base::BindRepeating(&Transaction::OnCacheIOComplete, @@ -1107,7 +1047,7 @@ } // Downgrade to UPDATE if the request has been externally conditionalized. - if (external_validation_.initialized) { + if (external_validation_) { if (mode_ & WRITE) { // Strip off the READ_DATA bit (and maybe add back a READ_META bit // in case READ was off). @@ -2603,7 +2543,7 @@ // Reset the variables that might get set in this function. This is done // because this function can be invoked multiple times for a transaction. cache_entry_status_ = CacheEntryStatus::ENTRY_UNDEFINED; - external_validation_.Reset(); + external_validation_.reset(); range_requested_ = false; partial_.reset(); @@ -2622,58 +2562,26 @@ effective_load_flags_ |= LOAD_DISABLE_CACHE; } - // Some headers imply load flags. The order here is significant. - // - // LOAD_DISABLE_CACHE : no cache read or write - // LOAD_BYPASS_CACHE : no cache read - // LOAD_VALIDATE_CACHE : no cache read unless validation - // - // The former modes trump latter modes, so if we find a matching header we - // can stop iterating kSpecialHeaders. - static const struct { - // RAW_PTR_EXCLUSION: Never allocated by PartitionAlloc (always points to - // constexpr tables), so there is no benefit to using a raw_ptr, only cost. - RAW_PTR_EXCLUSION const base::span<const HeaderNameAndValue> search; - int load_flag; - } kSpecialHeaders[] = { - {kPassThroughHeaders, LOAD_DISABLE_CACHE}, - {kForceFetchHeaders, LOAD_BYPASS_CACHE}, - {kForceValidateHeaders, LOAD_VALIDATE_CACHE}, - }; + bool range_found = + request_->extra_headers.HasHeader(HttpRequestHeaders::kRange); + int load_flags_for_extra_headers = + http_cache_util::GetLoadFlagsForExtraHeaders(request_->extra_headers); + effective_load_flags_ |= load_flags_for_extra_headers; - bool range_found = false; - bool external_validation_error = false; - bool special_headers = false; - - if (request_->extra_headers.HasHeader(HttpRequestHeaders::kRange)) { - range_found = true; + base::expected<std::optional<http_cache_util::ValidationHeaders>, + std::string_view> + maybe_validation_headers = + http_cache_util::ValidationHeaders::MaybeCreate( + request_->extra_headers); + std::optional<std::string_view> external_validation_error; + if (maybe_validation_headers.has_value()) { + external_validation_ = std::move(maybe_validation_headers.value()); + } else { + external_validation_error = maybe_validation_headers.error(); } - for (const auto& special_header : kSpecialHeaders) { - if (HeaderMatches(request_->extra_headers, special_header.search)) { - effective_load_flags_ |= special_header.load_flag; - special_headers = true; - break; - } - } - - // Check for conditionalization headers which may correspond with a - // cache validation request. - for (size_t i = 0; i < std::size(kValidationHeaders); ++i) { - const ValidationHeaderInfo& info = kValidationHeaders[i]; - if (std::optional<std::string> validation_value = - request_->extra_headers.GetHeader(info.request_header_name); - validation_value) { - if (!external_validation_.values[i].empty() || - validation_value->empty()) { - external_validation_error = true; - } - external_validation_.values[i] = std::move(validation_value).value(); - external_validation_.initialized = true; - } - } - - if (range_found || special_headers || external_validation_.initialized) { + if (range_found || load_flags_for_extra_headers || external_validation_ || + external_validation_error) { // Log the headers before request_ is modified. std::string empty; NetLogRequestHeaders(net_log_, @@ -2682,16 +2590,15 @@ } // We don't support ranges and validation headers. - if (range_found && external_validation_.initialized) { + if (range_found && external_validation_) { LOG(WARNING) << "Byte ranges AND validation headers found."; effective_load_flags_ |= LOAD_DISABLE_CACHE; } - // If there is more than one validation header, we can't treat this request as - // a cache validation, since we don't know for sure which header the server - // will give us a response for (and they could be contradictory). + // If there is an invalid validation header, we can't treat this request as + // a cache validation. if (external_validation_error) { - LOG(WARNING) << "Multiple or malformed validation headers found."; + LOG(WARNING) << *external_validation_error; effective_load_flags_ |= LOAD_DISABLE_CACHE; } @@ -2716,27 +2623,36 @@ } bool HttpCache::Transaction::ShouldPassThrough() { - bool cacheable = true; - // We may have a null disk_cache if there is an error we cannot recover from, // like not enough disk space, or sharing violations. if (!cache_->disk_cache_.get()) { - cacheable = false; - } else if (effective_load_flags_ & LOAD_DISABLE_CACHE) { - cacheable = false; - } else if (method_ == "GET" || method_ == "HEAD") { - } else if (method_ == "POST" && request_->upload_data_stream && - request_->upload_data_stream->identifier()) { - } else if (method_ == "PUT" && request_->upload_data_stream) { - } - // DELETE and PATCH requests may result in invalidating the cache, so cannot - // just pass through. - else if (method_ == "DELETE" || method_ == "PATCH") { - } else { - cacheable = false; + return true; } - return !cacheable; + if (effective_load_flags_ & LOAD_DISABLE_CACHE) { + return true; + } + + if (method_ == "GET" || method_ == "HEAD") { + return false; + } + + if (method_ == "POST" && request_->upload_data_stream && + request_->upload_data_stream->identifier()) { + return false; + } + + if (method_ == "PUT" && request_->upload_data_stream) { + return false; + } + + // DELETE and PATCH requests may result in invalidating the cache, so cannot + // just pass through. + if (method_ == "DELETE" || method_ == "PATCH") { + return false; + } + + return true; } int HttpCache::Transaction::BeginCacheRead() { @@ -2934,33 +2850,12 @@ return OK; } -bool HttpCache::Transaction:: - ExternallyConditionalizedValidationHeadersMatchEntry() const { - DCHECK(external_validation_.initialized); - - for (size_t i = 0; i < std::size(kValidationHeaders); i++) { - if (external_validation_.values[i].empty()) { - continue; - } - - // Retrieve either the cached response's "etag" or "last-modified" header. - std::optional<std::string_view> validator = - response_.headers->EnumerateHeader( - nullptr, kValidationHeaders[i].related_response_header_name); - - if (validator && *validator != external_validation_.values[i]) { - return false; - } - } - - return true; -} - int HttpCache::Transaction::BeginExternallyConditionalizedRequest() { DCHECK_EQ(UPDATE, mode_); + CHECK(external_validation_); if (response_.headers->response_code() != HTTP_OK || truncated_ || - !ExternallyConditionalizedValidationHeadersMatchEntry()) { + !external_validation_->Match(*response_.headers)) { // The externally conditionalized request is not a validation request // for our existing cache entry. Proceed with caching disabled. UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_OTHER); @@ -4029,9 +3924,6 @@ entry_->writers()->HasTransaction(this); } -HttpCache::Transaction::ValidationHeaders::ValidationHeaders() = default; -HttpCache::Transaction::ValidationHeaders::~ValidationHeaders() = default; - HttpCache::Transaction::NetworkTransactionInfo::NetworkTransactionInfo() = default; HttpCache::Transaction::NetworkTransactionInfo::~NetworkTransactionInfo() =
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h index 8623d95d..c6a60783 100644 --- a/net/http/http_cache_transaction.h +++ b/net/http/http_cache_transaction.h
@@ -13,6 +13,7 @@ #include <array> #include <memory> +#include <optional> #include <string> #include "base/functional/callback.h" @@ -31,6 +32,7 @@ #include "net/base/request_priority.h" #include "net/base/tracing.h" #include "net/http/http_cache.h" +#include "net/http/http_cache_util.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" @@ -195,27 +197,6 @@ void AddDiskCacheWriteTime(base::TimeDelta elapsed); private: - static const size_t kNumValidationHeaders = 2; - // Helper struct to pair a header name with its value, for - // headers used to validate cache entries. - struct ValidationHeaders { - ValidationHeaders(); - - ValidationHeaders(const ValidationHeaders&) = delete; - ValidationHeaders& operator=(const ValidationHeaders&) = delete; - - ~ValidationHeaders(); - - std::array<std::string, kNumValidationHeaders> values; - void Reset() { - initialized = false; - for (auto& value : values) { - value.clear(); - } - } - bool initialized = false; - }; - struct NetworkTransactionInfo { NetworkTransactionInfo(); @@ -413,10 +394,6 @@ // the validation of the rest of the entry. Returns a network error code. int ValidateEntryHeadersAndContinue(); - // Returns whether the current externally conditionalized request's validation - // headers match the current cache entry's headers. - bool ExternallyConditionalizedValidationHeadersMatchEntry() const; - // Called to start requests which were given an "if-modified-since" or // "if-none-match" validation header by the caller (NOT when the request was // conditionalized internally in response to LOAD_VALIDATE_CACHE). @@ -678,8 +655,8 @@ NetLogWithSource net_log_; HttpRequestHeaders request_headers_copy_; // If extra_headers specified a "if-modified-since" or "if-none-match", - // |external_validation_| contains the value of those headers. - ValidationHeaders external_validation_; + // `external_validation_` contains the value of those headers. + std::optional<http_cache_util::ValidationHeaders> external_validation_; base::WeakPtr<HttpCache> cache_; scoped_refptr<HttpCache::ActiveEntry> entry_; // This field is not a raw_ptr<> because it was filtered by the rewriter for:
diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index 0d6fcb2..599e8ec 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc
@@ -7045,6 +7045,54 @@ kNetResponse1, kExtraRequestHeaders); } +// Tests that a conditional request with an empty "If-Modified-Since" header +// value bypasses the cache for that request due to the malformed header, +// and does not update the existing cache entry. The original cache entry +// (kNetResponse1) should still be served from cache subsequently. +TEST_F(HttpCacheTest, ConditionalizedRequestEmptyIfModifiedSince) { + static const Response kNetResponse1 = { + "HTTP/1.1 200 OK", + "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" + "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", + "body1"}; + + static const Response kNetResponse2 = { + "HTTP/1.1 200 OK", + "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" + "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", + "body2"}; + + const char kExtraRequestHeaders[] = "If-Modified-Since:\r\n"; + + ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2, + kNetResponse1, kExtraRequestHeaders); +} + +// Tests that a conditional request with an empty "If-None-Match" header +// value bypasses the cache for that request due to the malformed header, +// and does not update the existing cache entry. The original cache entry +// (kNetResponse1) should still be served from cache subsequently. +TEST_F(HttpCacheTest, ConditionalizedRequestEmptyIfNoneMatch) { + static const Response kNetResponse1 = { + "HTTP/1.1 200 OK", + "Date: Fri, 12 Jun 2009 21:46:42 GMT\n" + "Etag: \"Foo1\"\n" + "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", + "body1"}; + + static const Response kNetResponse2 = { + "HTTP/1.1 200 OK", + "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" + "Etag: \"Foo2\"\n" + "Last-Modified: Fri, 03 Jul 2009 02:14:27 GMT\n", + "body2"}; + + const char kExtraRequestHeaders[] = "If-None-Match:\r\n"; + + ConditionalizedRequestUpdatesCacheHelper(kNetResponse1, kNetResponse2, + kNetResponse1, kExtraRequestHeaders); +} + TEST_F(HttpCacheTest, UrlContainingHash) { MockHttpCache cache;
diff --git a/net/http/http_cache_util.cc b/net/http/http_cache_util.cc new file mode 100644 index 0000000..5ceea4d --- /dev/null +++ b/net/http/http_cache_util.cc
@@ -0,0 +1,163 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/http/http_cache_util.h" + +#include <array> +#include <optional> +#include <string_view> + +#include "base/containers/span.h" +#include "base/memory/raw_ptr_exclusion.h" +#include "base/strings/string_util.h" +#include "net/base/load_flags.h" +#include "net/http/http_request_headers.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_util.h" + +namespace net::http_cache_util { + +namespace { + +// If the request includes one of these request headers, then avoid caching +// to avoid getting confused. +struct HeaderNameAndValue { + std::string_view name; + std::optional<std::string_view> value; +}; + +// If the request includes one of these request headers, then avoid caching +// to avoid getting confused. +constexpr auto kPassThroughHeaders = std::to_array( + {HeaderNameAndValue{"if-unmodified-since", + std::nullopt}, // causes unexpected 412s + HeaderNameAndValue{"if-match", std::nullopt}, // causes unexpected 412s + HeaderNameAndValue{"if-range", std::nullopt}}); + +// If the request includes one of these request headers, then avoid reusing +// our cached copy if any. +constexpr auto kForceFetchHeaders = + std::to_array({HeaderNameAndValue{"cache-control", "no-cache"}, + HeaderNameAndValue{"pragma", "no-cache"}}); + +// If the request includes one of these request headers, then force our +// cached copy (if any) to be revalidated before reusing it. +constexpr auto kForceValidateHeaders = + std::to_array({HeaderNameAndValue{"cache-control", "max-age=0"}}); + +bool HeaderMatches(const HttpRequestHeaders& headers, + base::span<const HeaderNameAndValue> search_headers) { + for (const auto& search_header : search_headers) { + std::optional<std::string> header_value = + headers.GetHeader(search_header.name); + if (!header_value) { + continue; + } + + if (!search_header.value) { + return true; + } + + HttpUtil::ValuesIterator v(*header_value, ','); + while (v.GetNext()) { + if (base::EqualsCaseInsensitiveASCII(v.value(), *search_header.value)) { + return true; + } + } + } + return false; +} + +struct ValidationHeaderInfo { + std::string_view request_header_name; + std::string_view related_response_header_name; +}; + +constexpr auto kValidationHeaders = std::to_array<ValidationHeaderInfo>( + {{"if-modified-since", "last-modified"}, {"if-none-match", "etag"}}); + +} // namespace + +int GetLoadFlagsForExtraHeaders(const HttpRequestHeaders& extra_headers) { + // Some headers imply load flags. The order here is significant. + // + // LOAD_DISABLE_CACHE : no cache read or write + // LOAD_BYPASS_CACHE : no cache read + // LOAD_VALIDATE_CACHE : no cache read unless validation + // + // The former modes trump latter modes, so if we find a matching header we + // can stop iterating kSpecialHeaders. + static const struct { + // RAW_PTR_EXCLUSION: Never allocated by PartitionAlloc (always points to + // constexpr tables), so there is no benefit to using a raw_ptr, only cost. + RAW_PTR_EXCLUSION const base::span<const HeaderNameAndValue> search; + int load_flag; + } kSpecialHeaders[] = { + {kPassThroughHeaders, LOAD_DISABLE_CACHE}, + {kForceFetchHeaders, LOAD_BYPASS_CACHE}, + {kForceValidateHeaders, LOAD_VALIDATE_CACHE}, + }; + for (const auto& special_header : kSpecialHeaders) { + if (HeaderMatches(extra_headers, special_header.search)) { + return special_header.load_flag; + } + } + static_assert(LOAD_NORMAL == 0); + return LOAD_NORMAL; +} + +// static +base::expected<std::optional<ValidationHeaders>, std::string_view> +ValidationHeaders::MaybeCreate(const HttpRequestHeaders& extra_headers) { + static_assert(kNumValidationHeaders == std::size(kValidationHeaders), + "invalid number of validation headers"); + ValidationHeaderValues values; + bool validation_header_found = false; + // Check for conditionalization headers which may correspond with a + // cache validation request. + for (size_t i = 0; i < std::size(kValidationHeaders); ++i) { + const ValidationHeaderInfo& info = kValidationHeaders[i]; + if (std::optional<std::string> validation_value = + extra_headers.GetHeader(info.request_header_name)) { + if (validation_value->empty()) { + return base::unexpected("Empty validation header value found"); + } + values[i] = std::move(*validation_value); + validation_header_found = true; + } + } + if (validation_header_found) { + return ValidationHeaders(std::move(values)); + } + return std::nullopt; +} + +ValidationHeaders::ValidationHeaders(ValidationHeaderValues values) + : values_(std::move(values)) {} + +ValidationHeaders::~ValidationHeaders() = default; + +ValidationHeaders::ValidationHeaders(ValidationHeaders&&) = default; +ValidationHeaders& ValidationHeaders::operator=(ValidationHeaders&&) = default; + +bool ValidationHeaders::Match( + const HttpResponseHeaders& response_headers) const { + for (size_t i = 0; i < std::size(kValidationHeaders); i++) { + if (values_[i].empty()) { + continue; + } + + // Retrieve either the cached response's "etag" or "last-modified" header. + std::optional<std::string_view> validator = + response_headers.EnumerateHeader( + nullptr, kValidationHeaders[i].related_response_header_name); + + if (validator && *validator != values_[i]) { + return false; + } + } + return true; +} + +} // namespace net::http_cache_util
diff --git a/net/http/http_cache_util.h b/net/http/http_cache_util.h new file mode 100644 index 0000000..6641209 --- /dev/null +++ b/net/http/http_cache_util.h
@@ -0,0 +1,70 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_HTTP_HTTP_CACHE_UTIL_H_ +#define NET_HTTP_HTTP_CACHE_UTIL_H_ + +#include <optional> +#include <string_view> + +#include "base/types/expected.h" + +namespace net { + +class HttpRequestHeaders; +class HttpResponseHeaders; + +namespace http_cache_util { + +// Determines cache-related load flags based on the provided HTTP request +// headers. +// +// This function inspects `extra_headers` for patterns implying specific cache +// behaviors (e.g., "Cache-Control: no-cache", "If-Match"). It can return +// flags like LOAD_DISABLE_CACHE, LOAD_BYPASS_CACHE, or LOAD_VALIDATE_CACHE. +// +// Returns an int representing the determined load flags , or 0 (LOAD_NORMAL) if +// no special cache-related headers are found. +int GetLoadFlagsForExtraHeaders(const HttpRequestHeaders& extra_headers); + +// Manages HTTP validation headers (e.g., If-Modified-Since, If-None-Match) +// provided in a request. It can parse them from HttpRequestHeaders and +// match them against HttpResponseHeaders. +class ValidationHeaders { + public: + // Attempts to create a ValidationHeaders object by parsing + // "If-Modified-Since" and "If-None-Match" headers from the provided + // `extra_headers`. Returns an ValidationHeaders if one or more valid + // validation headers are found. Returns std::nullopt if no relevant headers + // are present. Returns base::unexpected on error (e.g., an empty header + // value). + static base::expected<std::optional<ValidationHeaders>, std::string_view> + MaybeCreate(const HttpRequestHeaders& extra_headers); + + ~ValidationHeaders(); + + ValidationHeaders(const ValidationHeaders&) = delete; + ValidationHeaders& operator=(const ValidationHeaders&) = delete; + + ValidationHeaders(ValidationHeaders&&); + ValidationHeaders& operator=(ValidationHeaders&&); + + // Checks if the provided `response_headers` satisfy the validation + // conditions. This compares stored "If-Modified-Since" with "Last-Modified" + // and "If-None-Match" with "ETag" from the `response_headers`. + bool Match(const HttpResponseHeaders& response_headers) const; + + private: + static const size_t kNumValidationHeaders = 2; + using ValidationHeaderValues = std::array<std::string, kNumValidationHeaders>; + + explicit ValidationHeaders(ValidationHeaderValues values); + + ValidationHeaderValues values_; +}; + +} // namespace http_cache_util +} // namespace net + +#endif // NET_HTTP_HTTP_CACHE_UTIL_H_
diff --git a/net/http/http_stream_pool_attempt_manager.cc b/net/http/http_stream_pool_attempt_manager.cc index a2b6aafb..393d4e2 100644 --- a/net/http/http_stream_pool_attempt_manager.cc +++ b/net/http/http_stream_pool_attempt_manager.cc
@@ -1624,14 +1624,16 @@ dns_aliases); }); + // This WeakPtr is to ensure `this` is not destroyed while notifying. + // TODO(crbug.com/417339803): Remove once we stabilize the implementation. base::WeakPtr<AttemptManager> weak_this = weak_ptr_factory_.GetWeakPtr(); - while (weak_this && !streams.empty()) { + while (!streams.empty()) { std::unique_ptr<SpdyHttpStream> stream = std::move(streams.back()); streams.pop_back(); NotifyStreamReady(std::move(stream), NextProto::kProtoHTTP2); - // `this` may be deleted. + CHECK(weak_this); } - CHECK(!weak_this || jobs_.empty()); + CHECK(jobs_.empty()); } void HttpStreamPool::AttemptManager::MaybeCreateQuicStreamAndNotify( @@ -1653,14 +1655,16 @@ quic_session->CreateHandle(stream_key().destination()), dns_aliases); }); + // This WeakPtr is to ensure `this` is not destroyed while notifying. + // TODO(crbug.com/417339803): Remove once we stabilize the implementation. base::WeakPtr<AttemptManager> weak_this = weak_ptr_factory_.GetWeakPtr(); - while (weak_this && !streams.empty()) { + while (!streams.empty()) { std::unique_ptr<QuicHttpStream> stream = std::move(streams.back()); streams.pop_back(); NotifyStreamReady(std::move(stream), NextProto::kProtoQUIC); - // `this` may be deleted. + CHECK(weak_this); } - CHECK(!weak_this || jobs_.empty()); + CHECK(jobs_.empty()); } void HttpStreamPool::AttemptManager::NotifyStreamReady(
diff --git a/net/socket/ssl_client_socket.h b/net/socket/ssl_client_socket.h index 625353f..3672a5f1 100644 --- a/net/socket/ssl_client_socket.h +++ b/net/socket/ssl_client_socket.h
@@ -66,33 +66,10 @@ // once https://crbug.com/458365 is resolved. static void SetSSLKeyLogger(std::unique_ptr<SSLKeyLogger> logger); - protected: - void set_signed_cert_timestamps_received( - bool signed_cert_timestamps_received) { - signed_cert_timestamps_received_ = signed_cert_timestamps_received; - } - - void set_stapled_ocsp_response_received(bool stapled_ocsp_response_received) { - stapled_ocsp_response_received_ = stapled_ocsp_response_received; - } - // Serialize |next_protos| in the wire format for ALPN: protocols are listed // in order, each prefixed by a one-byte length. static std::vector<uint8_t> SerializeNextProtos( const NextProtoVector& next_protos); - - private: - FRIEND_TEST_ALL_PREFIXES(SSLClientSocket, SerializeNextProtos); - // For signed_cert_timestamps_received_ and stapled_ocsp_response_received_. - FRIEND_TEST_ALL_PREFIXES(SSLClientSocketVersionTest, - ConnectSignedCertTimestampsTLSExtension); - FRIEND_TEST_ALL_PREFIXES(SSLClientSocketVersionTest, - ConnectSignedCertTimestampsEnablesOCSP); - - // True if SCTs were received via a TLS extension. - bool signed_cert_timestamps_received_ = false; - // True if a stapled OCSP response was received. - bool stapled_ocsp_response_received_ = false; }; // Shared state and configuration across multiple SSLClientSockets.
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc index 7e27804..b285bfe 100644 --- a/net/socket/ssl_client_socket_impl.cc +++ b/net/socket/ssl_client_socket_impl.cc
@@ -906,16 +906,6 @@ RecordNegotiatedProtocol(); - const uint8_t* ocsp_response_raw; - size_t ocsp_response_len; - SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len); - set_stapled_ocsp_response_received(ocsp_response_len != 0); - - const uint8_t* sct_list; - size_t sct_list_len; - SSL_get0_signed_cert_timestamp_list(ssl_.get(), &sct_list, &sct_list_len); - set_signed_cert_timestamps_received(sct_list_len != 0); - if (!IsRenegotiationAllowed()) SSL_set_renegotiate_mode(ssl_.get(), ssl_renegotiate_never); @@ -1070,21 +1060,20 @@ const uint8_t* ocsp_response_raw; size_t ocsp_response_len; SSL_get0_ocsp_response(ssl_.get(), &ocsp_response_raw, &ocsp_response_len); - std::string_view ocsp_response( - reinterpret_cast<const char*>(ocsp_response_raw), ocsp_response_len); + base::span ocsp_response(ocsp_response_raw, ocsp_response_len); const uint8_t* sct_list_raw; size_t sct_list_len; SSL_get0_signed_cert_timestamp_list(ssl_.get(), &sct_list_raw, &sct_list_len); - std::string_view sct_list(reinterpret_cast<const char*>(sct_list_raw), - sct_list_len); + base::span sct_list(sct_list_raw, sct_list_len); cert_verification_result_ = context_->cert_verifier()->Verify( CertVerifier::RequestParams( server_cert_, ech_name_override.empty() ? host_and_port_.host() : ech_name_override, - ssl_config_.GetCertVerifyFlags(), std::string(ocsp_response), - std::string(sct_list)), + ssl_config_.GetCertVerifyFlags(), + std::string(base::as_string_view(ocsp_response)), + std::string(base::as_string_view(sct_list))), &server_cert_verify_result_, base::BindOnce(&SSLClientSocketImpl::OnVerifyComplete, base::Unretained(this)),
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index d811651..db63eb5 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc
@@ -2724,8 +2724,6 @@ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(sock_->signed_cert_timestamps_received_); - ASSERT_EQ(cert_verifier_->GetVerifyParams().size(), 1u); const auto& params = cert_verifier_->GetVerifyParams().front(); EXPECT_TRUE(params.certificate()->EqualsIncludingChain( @@ -2756,7 +2754,12 @@ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(sock_->stapled_ocsp_response_received_); + ASSERT_EQ(cert_verifier_->GetVerifyParams().size(), 1u); + const auto& params = cert_verifier_->GetVerifyParams().front(); + EXPECT_TRUE(params.certificate()->EqualsIncludingChain( + embedded_test_server()->GetCertificate().get())); + EXPECT_EQ(params.hostname(), embedded_test_server()->host_port_pair().host()); + EXPECT_FALSE(params.ocsp_response().empty()); } // Tests that IsConnectedAndIdle and WasEverUsed behave as expected.
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 8781f09..d7ffce2 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -974,6 +974,9 @@ base::UmaHistogramCounts100("Net.DeviceBoundSessions.RequestDeferralCount", device_bound_session_deferral_count_); + base::UmaHistogramEnumeration( + "Net.DeviceBoundSessions.RequestDeferralDecision", + request_->device_bound_session_usage()); if (device_bound_session_deferral_count_ > 0) { base::UmaHistogramTimes( "Net.DeviceBoundSessions.TotalRequestDeferredDuration",
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc index a4609b6..2fd8b1d 100644 --- a/net/url_request/url_request_http_job_unittest.cc +++ b/net/url_request/url_request_http_job_unittest.cc
@@ -1603,6 +1603,7 @@ TEST_F(URLRequestHttpJobWithMockSocketsDeviceBoundSessionServiceTest, DeferRequestIfNeeded) { + base::HistogramTester histogram_tester; const MockWrite writes[] = { MockWrite("GET / HTTP/1.1\r\n" "Host: www.example.com\r\n" @@ -1629,16 +1630,34 @@ device_bound_sessions::Session::Id("test")); })); EXPECT_CALL(GetMockService(), DeferRequestForRefresh) - .WillOnce(base::test::RunOnceClosure<3>()); + .WillOnce(Invoke([](URLRequest* request, Unused, + device_bound_sessions::SessionServiceMock:: + RefreshCompleteCallback restart_callback, + device_bound_sessions::SessionServiceMock:: + RefreshCompleteCallback continue_callback) { + request->set_device_bound_session_usage( + net::device_bound_sessions::SessionUsage::kDeferred); + std::move(restart_callback).Run(); + })); + EXPECT_CALL(GetMockService(), ShouldDefer).WillOnce(Return(std::nullopt)); } request_->Start(); delegate_.RunUntilComplete(); EXPECT_THAT(delegate_.request_status(), IsOk()); + histogram_tester.ExpectUniqueSample( + "Net.DeviceBoundSessions.RequestDeferralCount", + /*sample=*/1, + /*expected_bucket_count=*/1); + histogram_tester.ExpectUniqueSample( + "Net.DeviceBoundSessions.RequestDeferralDecision", + /*sample=*/device_bound_sessions::SessionUsage::kDeferred, + /*expected_bucket_count=*/1); } TEST_F(URLRequestHttpJobWithMockSocketsDeviceBoundSessionServiceTest, DontDeferRequestIfNotNeeded) { + base::HistogramTester histogram_tester; const MockWrite writes[] = { MockWrite("GET / HTTP/1.1\r\n" "Host: www.example.com\r\n" @@ -1662,6 +1681,10 @@ request_->Start(); delegate_.RunUntilComplete(); EXPECT_THAT(delegate_.request_status(), IsOk()); + histogram_tester.ExpectUniqueSample( + "Net.DeviceBoundSessions.RequestDeferralCount", + /*sample=*/0, + /*expected_bucket_count=*/1); } TEST_F(URLRequestHttpJobWithMockSocketsDeviceBoundSessionServiceTest,
diff --git a/services/webnn/tflite/graph_builder_tflite.cc b/services/webnn/tflite/graph_builder_tflite.cc index f096b4f..c9af27f 100644 --- a/services/webnn/tflite/graph_builder_tflite.cc +++ b/services/webnn/tflite/graph_builder_tflite.cc
@@ -1790,6 +1790,53 @@ return SerializeQuantizedOutput(*next_op); } +std::optional<base::FixedArray<GraphBuilderTflite::TensorInfo>> +GraphBuilderTflite::CanFuseQuantizeAndGetOutput(const mojom::Split& split) { + if (!IsDequantizeOutput(split.input_operand_id)) { + return std::nullopt; + } + + // TODO(crbug.com/413083273): Consider the restriction in GPU delegate. + // For XNNPack delegate, the scale and zero point of input and output have to + // be scaler, and the number of outputs should be in the range of [2, 4]. But + // there is no limitation on the number of outputs for TFLite kernel, so relax + // the output number restriction here. + // https://source.chromium.org/chromium/chromium/src/+/main:third_party/tflite/src/tensorflow/lite/delegates/xnnpack/xnnpack_delegate.cc;l=5558;drc=1379ddb0f0535ff846ce0fbad8ee49af303140c4 + const mojom::DequantizeLinear& input_dequantize = + GetDequantizeOp(split.input_operand_id); + if (!IsInts8AndScalarScale(input_dequantize)) { + return std::nullopt; + } + + const size_t outputs_size = split.output_operand_ids.size(); + const OperandDataType quantized_type = + GetOperand(input_dequantize.input_operand_id).descriptor.data_type(); + base::FixedArray<std::pair<OperationId, QuantizateParametersOffset>> + quantize_ops(outputs_size); + for (size_t i = 0; i < outputs_size; ++i) { + std::optional<std::pair<OperationId, QuantizateParametersOffset>> next_op = + IsNextOpQuantize(split.output_operand_ids[i], {quantized_type}); + if (!next_op) { + return std::nullopt; + } + + OperationId quantize_op_id = next_op->first; + const mojom::QuantizeLinear& output_quantize = + GetQuantizeOp(quantize_op_id); + if (!IsInts8AndScalarScale(output_quantize)) { + return std::nullopt; + } + quantize_ops[i] = std::move(*next_op); + } + + base::FixedArray<TensorInfo> output_tensor_infos(outputs_size); + for (size_t i = 0; i < outputs_size; ++i) { + output_tensor_infos[i] = SerializeQuantizedOutput(quantize_ops[i]); + } + + return output_tensor_infos; +} + std::optional<GraphBuilderTflite::TensorInfo> GraphBuilderTflite::CanFuseQuantizeAndGetOutput( const mojom::Transpose& transpose) { @@ -6657,17 +6704,31 @@ /*buffer=*/std::array<int32_t, 1>{checked_axis.ValueOrDie()}, /*dimensions=*/{}); + std::optional<base::FixedArray<TensorInfo>> quantized_outputs = + CanFuseQuantizeAndGetOutput(split); + const bool fuse_dequantize = quantized_outputs.has_value(); + ASSIGN_OR_RETURN(const TensorInfo& input_tensor_info, + SerializeInputTensorInfo( + split.input_operand_id, /*quantize_params=*/0, + /*operation_supports_float16=*/false, fuse_dequantize)); + // Serialize the split sizes tensor that specifies the sizes of each output // tensor along the axis. const size_t outputs_size = split.output_operand_ids.size(); base::FixedArray<int32_t> split_sizes(outputs_size); base::FixedArray<int32_t> op_outputs(outputs_size); for (size_t i = 0; i < outputs_size; ++i) { - const TensorInfo output_tensor_info = - SerializeOutputTensorInfo(split.output_operand_ids[i]); - CHECK_LT(split.axis, output_tensor_info.dimensions.size()); - split_sizes[i] = output_tensor_info.dimensions[split.axis]; - op_outputs[i] = output_tensor_info.index; + if (fuse_dequantize) { + CHECK_LT(split.axis, quantized_outputs->at(i).dimensions.size()); + split_sizes[i] = quantized_outputs->at(i).dimensions[split.axis]; + op_outputs[i] = quantized_outputs->at(i).index; + } else { + const TensorInfo output_tensor_info = + SerializeOutputTensorInfo(split.output_operand_ids[i]); + CHECK_LT(split.axis, output_tensor_info.dimensions.size()); + split_sizes[i] = output_tensor_info.dimensions[split.axis]; + op_outputs[i] = output_tensor_info.index; + } } const auto checked_split_size = base::MakeCheckedNum<int32_t>(split_sizes.size()); @@ -6683,8 +6744,6 @@ const auto split_options = ::tflite::CreateSplitOptions( builder_, /*num_splits=*/checked_split_size.ValueOrDie()); - ASSIGN_OR_RETURN(const TensorInfo& input_tensor_info, - SerializeInputTensorInfo(split.input_operand_id)); const OperatorCodeIndex operator_code_index = GetOperatorCodeIndex(::tflite::BuiltinOperator_SPLIT_V); // The order of inputs is input, split sizes tensor and then axis tensor as
diff --git a/services/webnn/tflite/graph_builder_tflite.h b/services/webnn/tflite/graph_builder_tflite.h index d3aa8789d..d124929ff 100644 --- a/services/webnn/tflite/graph_builder_tflite.h +++ b/services/webnn/tflite/graph_builder_tflite.h
@@ -726,6 +726,8 @@ const mojom::Pool2d& pool2d); std::optional<TensorInfo> CanFuseQuantizeAndGetOutput( const mojom::Reshape& reshape); + std::optional<base::FixedArray<TensorInfo>> CanFuseQuantizeAndGetOutput( + const mojom::Split& split); std::optional<TensorInfo> CanFuseQuantizeAndGetOutput( const mojom::Transpose& transpose); std::optional<TensorInfo> CanFuseQuantizeAndGetOutput(
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index c516bd5..d3d57c1 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -4956,35 +4956,6 @@ ] } ], - "ChromnientIPH": [ - { - "platforms": [ - "chromeos", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "availability": "any", - "event_trigger": "name:lens_overlay_iph_triggered;comparator:any;window:90;storage:365", - "event_used": "name:lens_overlay_used;comparator:==0;window:90;storage:365", - "session_rate": "==0", - "x_url_allow_filters": "[\"*\"]", - "x_url_block_filters": "[\"chegg.com\",\"brainly.com\",\"coursehero.com\",\"quizlet.com\",\"study.com\",\"tutor.com\",\"wyzant.com\",\"tutoring.k12.com\",\"varsitytutors.com\",\"studypool.com\",\"sylvanlearning.com\",\"skooli.com\",\"socratic.org\",\"schoolhouse.world\",\"google.com\",\"ai\",\"indeedassessments.com\",\"nytimes.com\",\"cnn.com\",\"foxnews.com\",\"people.com\",\"usatoday.com\",\"msn.com\",\"nypost.com\",\"apnews.com\",\"dailymail.co.uk\",\"news.google.com\",\"cnbc.com\",\"newsweek.com\",\"washingtonpost.com\",\"yahoo.com\",\"theguardian.com\",\"bbc.com\",\"wsj.com\",\"reuters.com\",\"breitbart.com\",\"bloomberg.com\",\"huffpost.com\",\"nbcnews.com\",\"businessinsider.com\",\"cbsnews.com\",\"usnews.com\",\"thegatewaypundit.com\",\"axios.com\",\"drudgereport.com\",\"theatlantic.com\",\"forbes.com\",\"npr.org\",\"espn.com\",\"latimes.com\",\"thecooldown.com\",\"zerohedge.com\",\"politico.com\",\"thehill.com\",\"weather.com\",\"marketwatch.com\",\"buzzfeed.com\",\"cbssports.com\",\"tmz.com\",\"slate.com\",\"vice.com\",\"salon.com\",\"theintercept.com\",\"inquirer.com\",\"chicagotribune.com\",\"bostonglobe.com\",\"upworthy.com\",\"geediting.com\",\"popularmechanics.com \",\"hindustantimes.com\",\"independent.co.uk\",\"uniladtech.com\",\"paypal.com\",\"capitalone.com\",\"chase.com\",\"finance.yahoo.com\",\"bankofamerica.com\",\"wellsfargo.com\",\"fidelity.com\",\"citi.com\",\"americanexpress.com\",\"schwab.com\",\"creditkarma.com\",\"experian.com\",\"discover.com\",\"usbank.com\",\"navyfederal.org\",\"pnc.com\",\"truist.com\",\"ally.com\",\"vanguard.com\",\"forbes.com\",\"intuit.com\",\"investopedia.com\",\"cnbc.com\",\"nerdwallet.com\",\"wsj.com\",\"marketwatch.com\",\"bloomberg.com\",\"reuters.com\",\"businessinsider.com\",\"cash.app\",\"venmo.com\",\"equifax.com\",\"transunion.com\",\"etrade.com\",\"robinhood.com\",\"morganstanley.com\",\"ml.com\",\"sofi.com\",\"chime.com\",\"huntington.com\",\"key.com\",\"citizensbank.com\",\"fifththird.com\",\"mtb.com\",\"regions.com\",\"santanderbank.com\",\"td.com\",\"usaa.com\",\"bankrate.com\",\"youtube.com\",\"facebook.com\",\"instagram.com\",\"tiktok.com\",\"x.com\",\"reddit.com\",\"pinterest.com\",\"linkedin.com\",\"whatsapp.com\",\"messenger.com\",\"snapchat.com\",\"twitch.tv\",\"discord.com\",\"telegram.org\",\"quora.com\",\"nextdoor.com\",\"tumblr.com\",\"threads.net\",\"blueskyweb.xyz\",\"mastodon.social\",\"medium.com\",\"vimeo.com\",\"flickr.com\",\"yelp.com\",\"bere.al\",\"kick.com\",\"behance.net\",\"deviantart.com\",\"goodreads.com\",\"clubhouse.com\",\"ello.co\",\"mewe.com\",\"signal.org\",\"glassdoor.com\",\"meetup.com\",\"houzz.com\",\"imgur.com\",\"letterboxd.com\",\"care2.com\",\"ravelry.com\",\"bandcamp.com\",\"soundcloud.com\",\"gaia.com\",\"caringbridge.org\",\"myspace.com\",\"livejournal.com\",\"classmates.com\",\"weheartit.com\",\"unofficialnetworks.com\",\"internalfb.com\",\"allrecipes.com\"]", - "x_url_path_match_allow_patterns": "[\"(?i)assignments\",\"(?i)assignment\",\"(?i)assign\",\"(?i)assessment\",\"(?i)assessments\",\"(?i)homework\",\"(?i)quiz\",\"(?i)quizzes\",\"(?i)question\",\"(?i)questions\",\"(?i)exam\",\"(?i)exams\",\"(?i)task\",\"(?i)tasks\",\"(?i)attempt\",\"(?i)test\",\"(?i)tests\",\"(?i)worksheet\",\"(?i)worksheets\",\"(?i)science\",\"(?i)biology\",\"(?i)chemistry\",\"(?i)physics\",\"(?i)geology\",\"(?i)astronomy\",\"(?i)programming\",\"(?i)robotics\",\"(?i)engineering\",\"(?i)mechanics\",\"(?i)mathematics\",\"(?i)math\",\"(?i)algebra\",\"(?i)calculus\",\"(?i)geometry\",\"(?i)statistics\",\"(?i)sociology\",\"(?i)geography\",\"(?i)psychology\",\"(?i)literature\",\"(?i)archaeology\",\"(?i)economics\",\"(?i)accounting\",\"(?i)course\",\"(?i)courses\"]", - "x_url_path_match_block_patterns": "[\"(?i)tutor\",\"(?i)protest\",\"(?i)latest\",\"(?i)account\",\"(?i)management\",\"(?i)login\",\"(?i)assessment\",\"(?i)apply\",\"(?i)questionnaire\",\"(?i)calendar\",\"(?i)news\",\"(?i)certification\",\"(?i)article\",\"(?i)download\",\"(?i)profile\",\"(?i)policy\",\"(?i)auth\",\"(?i)secure\"]", - "x_wait_time": "60s" - }, - "enable_features": [ - "IPH_LensOverlay" - ] - } - ] - } - ], "ChromnientLatencyOptimizations": [ { "platforms": [ @@ -5027,6 +4998,24 @@ ] } ], + "ChromnientNewFeedback": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "NewFeedbackEnabled", + "enable_features": [ + "LensSearchSidePanelNewFeedback" + ] + } + ] + } + ], "ChromnientPostLaunchTranslate": [ { "platforms": [
diff --git a/third_party/angle b/third_party/angle index f5f6704..8d75490 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit f5f6704c1cf00faa87a8b55eec0988600a8128e6 +Subproject commit 8d75490aa47bc2be90e8b1bbeaae495bdf0a37e9
diff --git a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom index 9b0d0f41..264b5583 100644 --- a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom +++ b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
@@ -163,7 +163,7 @@ kVersionError = 33, kAbortError = 20, kIgnorableAbortError = 11, - kQuotaError = 22, + kQuotaError = 37, kTimeoutError = 23, };
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni index e0b3fe84..32b5721 100644 --- a/third_party/blink/renderer/bindings/generated_in_core.gni +++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -378,6 +378,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_property_definition.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_queuing_strategy_init.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_quota_exceeded_error_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_quota_exceeded_error_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_get_reader_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_get_reader_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_iterator_options.cc", @@ -1352,6 +1354,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_progress_event.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_promise_rejection_event.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_promise_rejection_event.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_quota_exceeded_error.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_quota_exceeded_error.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_radio_node_list.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_radio_node_list.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_range.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni index be1c11899..a8ade17f 100644 --- a/third_party/blink/renderer/bindings/idl_in_core.gni +++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -188,6 +188,7 @@ "//third_party/blink/renderer/core/dom/pointer_lock_options.idl", "//third_party/blink/renderer/core/dom/popover_invoker_element.idl", "//third_party/blink/renderer/core/dom/processing_instruction.idl", + "//third_party/blink/renderer/core/dom/quota_exceeded_error.idl", "//third_party/blink/renderer/core/dom/range.idl", "//third_party/blink/renderer/core/dom/shadow_root.idl", "//third_party/blink/renderer/core/dom/shadow_root_init.idl",
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index 4f1e3faa8..0f5253c 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -695,7 +695,7 @@ // g-issues.chromium.org/issues/349835587 // https://github.com/WICG/canvas-place-element -static bool IsCanvasPlaceOrDrawElement(const Element* element) { +static bool IsCanvasDrawElement(const Element* element) { if (RuntimeEnabledFeatures::CanvasDrawElementEnabled() && element && element->IsInCanvasSubtree()) { // Placed elements are always immediate children of the canvas. @@ -708,7 +708,7 @@ return false; } -static bool IsCanvasWithPlaceOrDrawElements(const Element* element) { +static bool IsCanvasWithDrawElements(const Element* element) { if (!RuntimeEnabledFeatures::CanvasDrawElementEnabled() || !element) { return false; } @@ -725,10 +725,10 @@ const ComputedStyle& layout_parent_style, const Element* element, Document* document) { - bool is_canvas_place_or_draw_element = IsCanvasPlaceOrDrawElement(element); + bool is_canvas_draw_element = IsCanvasDrawElement(element); if ((layout_parent_style.BlockifiesChildren() && !HostIsInputFile(element)) || - is_canvas_place_or_draw_element) { + is_canvas_draw_element) { builder.SetIsInBlockifyingDisplay(); if (builder.Display() != EDisplay::kContents) { builder.SetDisplay(EquivalentBlockDisplay(builder.Display())); @@ -737,13 +737,13 @@ } } if (layout_parent_style.IsDisplayFlexibleOrGridBox() || - layout_parent_style.IsDisplayMathType() || - is_canvas_place_or_draw_element) { + layout_parent_style.IsDisplayMathType() || is_canvas_draw_element) { builder.SetIsInsideDisplayIgnoringFloatingChildren(); } - if (is_canvas_place_or_draw_element) { + if (is_canvas_draw_element) { builder.SetPosition(EPosition::kStatic); + builder.SetContain(builder.Contain() | kContainsPaint); } } @@ -1165,8 +1165,7 @@ builder.Overlay() == EOverlay::kAuto || builder.StyleType() == kPseudoIdBackdrop || builder.StyleType() == kPseudoIdViewTransition || - IsCanvasPlaceOrDrawElement(element) || - IsCanvasWithPlaceOrDrawElements(element)) { + IsCanvasWithDrawElements(element)) { builder.SetForcesStackingContext(true); }
diff --git a/third_party/blink/renderer/core/dom/build.gni b/third_party/blink/renderer/core/dom/build.gni index 9e799323..464901b 100644 --- a/third_party/blink/renderer/core/dom/build.gni +++ b/third_party/blink/renderer/core/dom/build.gni
@@ -231,6 +231,8 @@ "pseudo_element.cc", "pseudo_element.h", "pseudo_element_data.h", + "quota_exceeded_error.cc", + "quota_exceeded_error.h", "range.cc", "range.h", "range_boundary_point.h",
diff --git a/third_party/blink/renderer/core/dom/dom_exception.cc b/third_party/blink/renderer/core/dom/dom_exception.cc index cea8135..8bcdbc3 100644 --- a/third_party/blink/renderer/core/dom/dom_exception.cc +++ b/third_party/blink/renderer/core/dom/dom_exception.cc
@@ -30,6 +30,7 @@ #include "base/notreached.h" #include "third_party/blink/renderer/platform/bindings/exception_messages.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/text/strcat.h" namespace blink { @@ -189,6 +190,11 @@ exception_code <= DOMExceptionCode::kLegacyErrorCodeMax) { return static_cast<uint16_t>(exception_code); } + if (!RuntimeEnabledFeatures::QuotaExceededErrorUpdateEnabled() && + exception_code == DOMExceptionCode::kQuotaExceededError) { + // Return legacy error code. + return 22; + } return 0; }
diff --git a/third_party/blink/renderer/core/dom/quota_exceeded_error.cc b/third_party/blink/renderer/core/dom/quota_exceeded_error.cc new file mode 100644 index 0000000..25a8169 --- /dev/null +++ b/third_party/blink/renderer/core/dom/quota_exceeded_error.cc
@@ -0,0 +1,58 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/dom/quota_exceeded_error.h" + +#include "third_party/blink/renderer/bindings/core/v8/v8_quota_exceeded_error_options.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" + +namespace blink { + +// static +QuotaExceededError* QuotaExceededError::Create( + const String& message, + const QuotaExceededErrorOptions* options) { + // Not doing AttachStackProperty is consistent with `new DOMException()` + // but should be updated to do so to match spec (crbug.com/40815519). + return MakeGarbageCollected<QuotaExceededError>(message, options); +} + +// static +v8::Local<v8::Value> QuotaExceededError::Create( + v8::Isolate* isolate, + const String& message, + std::optional<double> quota, + std::optional<double> requested) { + auto* options = QuotaExceededErrorOptions::Create(isolate); + if (quota) { + options->setQuota(quota.value()); + } + if (requested) { + options->setRequested(requested.value()); + } + auto* exception = MakeGarbageCollected<QuotaExceededError>(message, options); + return V8ThrowDOMException::AttachStackProperty(isolate, exception); +} + +QuotaExceededError::QuotaExceededError(const String& message, + const QuotaExceededErrorOptions* options) + : DOMException(DOMExceptionCode::kQuotaExceededError, message), + quota_(options->hasQuota() ? std::make_optional(options->quota()) + : std::nullopt), + requested_(options->hasRequested() + ? std::make_optional(options->requested()) + : std::nullopt) {} + +QuotaExceededError::QuotaExceededError(const String& message, + std::optional<double> quota, + std::optional<double> requested) + : DOMException(DOMExceptionCode::kQuotaExceededError, message), + quota_(quota), + requested_(requested) {} + +QuotaExceededError::QuotaExceededError(const String& message) + : DOMException(DOMExceptionCode::kQuotaExceededError, message) {} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/dom/quota_exceeded_error.h b/third_party/blink/renderer/core/dom/quota_exceeded_error.h new file mode 100644 index 0000000..bf90283 --- /dev/null +++ b/third_party/blink/renderer/core/dom/quota_exceeded_error.h
@@ -0,0 +1,50 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_QUOTA_EXCEEDED_ERROR_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_QUOTA_EXCEEDED_ERROR_H_ + +#include <optional> + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" + +namespace blink { + +class QuotaExceededErrorOptions; + +class CORE_EXPORT QuotaExceededError : public DOMException { + DEFINE_WRAPPERTYPEINFO(); + + public: + // Constructor exposed to script. Called by the V8 bindings. + static QuotaExceededError* Create(const String& message, + const QuotaExceededErrorOptions* options); + + // For creating a QuotaExceededError from C++ to be immediately passed to + // ScriptPromiseResolverBase::Reject. + static v8::Local<v8::Value> Create(v8::Isolate*, + const String& message, + std::optional<double> quota, + std::optional<double> requested); + + QuotaExceededError(const String& message, + const QuotaExceededErrorOptions* options); + QuotaExceededError(const String& message, + std::optional<double> quota, + std::optional<double> requested); + explicit QuotaExceededError(const String& message); + + std::optional<double> quota() const { return quota_; } + std::optional<double> requested() const { return requested_; } + + private: + std::optional<double> quota_; + std::optional<double> requested_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_QUOTA_EXCEEDED_ERROR_H_
diff --git a/third_party/blink/renderer/core/dom/quota_exceeded_error.idl b/third_party/blink/renderer/core/dom/quota_exceeded_error.idl new file mode 100644 index 0000000..96bfb5e4 --- /dev/null +++ b/third_party/blink/renderer/core/dom/quota_exceeded_error.idl
@@ -0,0 +1,18 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +dictionary QuotaExceededErrorOptions { + double quota; + double requested; +}; + +[ + Exposed=*, + Serializable, + RuntimeEnabled=QuotaExceededErrorUpdate +] interface QuotaExceededError : DOMException { + constructor(optional DOMString message = "", optional QuotaExceededErrorOptions options = {}); + readonly attribute double? quota; + readonly attribute double? requested; +};
diff --git a/third_party/blink/renderer/core/html/resources/html.css b/third_party/blink/renderer/core/html/resources/html.css index e82b003..484370e 100644 --- a/third_party/blink/renderer/core/html/resources/html.css +++ b/third_party/blink/renderer/core/html/resources/html.css
@@ -2112,5 +2112,4 @@ select:-internal-list-box::picker-icon { display: none !important; } - }
diff --git a/third_party/blink/renderer/core/scroll/scroll_into_view_util.cc b/third_party/blink/renderer/core/scroll/scroll_into_view_util.cc index 20974abc..47a265a 100644 --- a/third_party/blink/renderer/core/scroll/scroll_into_view_util.cc +++ b/third_party/blink/renderer/core/scroll/scroll_into_view_util.cc
@@ -593,15 +593,13 @@ Intersection(non_zero_visible_rect, expose_rect_x).Width(); if (intersect_width == expose_rect_no_margin.Width()) { // If the rectangle is fully visible, use the specified visible behavior. - // If the rectangle is partially visible, but over a certain threshold, - // then treat it as fully visible to avoid unnecessary horizontal scrolling scroll_x = align_x.rect_visible; } else if (intersect_width == non_zero_visible_rect.Width()) { // The rect is bigger than the visible area. scroll_x = align_x.rect_visible; } else if (intersect_width > 0) { - // If the rectangle is partially visible, but not above the minimum - // threshold, use the specified partial behavior + // If the rectangle is partially visible, use the specified partial + // behavior. scroll_x = align_x.rect_partial; } else { scroll_x = align_x.rect_hidden; @@ -635,7 +633,8 @@ // The rect is bigger than the visible area. scroll_y = align_y.rect_visible; } else if (intersect_height > 0) { - // If the rectangle is partially visible, use the specified partial behavior + // If the rectangle is partially visible, use the specified partial + // behavior. scroll_y = align_y.rect_partial; } else { scroll_y = align_y.rect_hidden;
diff --git a/third_party/blink/renderer/core/url_pattern/url_pattern_canon.cc b/third_party/blink/renderer/core/url_pattern/url_pattern_canon.cc index 610c787..d95e5962 100644 --- a/third_party/blink/renderer/core/url_pattern/url_pattern_canon.cc +++ b/third_party/blink/renderer/core/url_pattern/url_pattern_canon.cc
@@ -59,12 +59,11 @@ url::Component component; if (stripped.Is8Bit()) { StringUTF8Adaptor utf8(stripped); - result = url::CanonicalizeScheme( - utf8.data(), url::Component(0, utf8.size()), &canon_output, &component); + result = + url::CanonicalizeScheme(utf8.AsStringView(), &canon_output, &component); } else { - result = url::CanonicalizeScheme(stripped.Characters16(), - url::Component(0, stripped.length()), - &canon_output, &component); + result = + url::CanonicalizeScheme(stripped.View16(), &canon_output, &component); } if (!result) {
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc index 9f0165c9..161f454 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -191,29 +191,29 @@ if (element->parentElement() != canvas_element) { exception_state.ThrowTypeError( "Only immediate children of the <canvas> element can be passed to " - "placeElement()."); - return false; - } - - if (!element->GetLayoutObject()) { - exception_state.ThrowTypeError( - "An element used with drawElement() must have been laid out. " - "Add layoutsubtree=`true` to the canvas element and be sure the " - "element is not `display: none`."); - return false; - } - - // TODO(crbug.com/413728246): Maybe we can support canvas element. - if (IsA<HTMLCanvasElement>(element)) { - exception_state.ThrowTypeError( - "<canvas> children of a <canvas> cannot be passed to placeElement()."); + "drawElement()."); return false; } if (!canvas_element->layoutSubtree()) { exception_state.ThrowTypeError( "<canvas> elements without layoutsubtree do not support " - "placeElement()."); + "drawElement()."); + return false; + } + + if (!element->GetLayoutObject()) { + exception_state.ThrowTypeError( + "The canvas and element used with drawElement() must have been laid " + "out. Detached canvases are not supported, nor canvas or children that " + "are `display: none`."); + return false; + } + + // TODO(crbug.com/413728246): Maybe we can support canvas element. + if (IsA<HTMLCanvasElement>(element)) { + exception_state.ThrowTypeError( + "<canvas> children of a <canvas> cannot be passed to drawElement()."); return false; }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_database.cc b/third_party/blink/renderer/modules/indexeddb/idb_database.cc index 629e9a930..21c5f01 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_database.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -40,6 +40,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_union_string_stringsequence.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/dom/quota_exceeded_error.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" #include "third_party/blink/renderer/modules/indexed_db_names.h" @@ -55,6 +56,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" @@ -211,9 +213,15 @@ mojom::blink::IDBException code, const WTF::String& message) { DCHECK(transactions_.Contains(transaction_id)); - transactions_.at(transaction_id) - ->OnAbort(MakeGarbageCollected<DOMException>( - static_cast<DOMExceptionCode>(code), message)); + DOMException* dom_exception; + if (code == mojom::blink::IDBException::kQuotaError && + RuntimeEnabledFeatures::QuotaExceededErrorUpdateEnabled()) { + dom_exception = MakeGarbageCollected<QuotaExceededError>(message); + } else { + dom_exception = MakeGarbageCollected<DOMException>( + static_cast<DOMExceptionCode>(code), message); + } + transactions_.at(transaction_id)->OnAbort(dom_exception); } void IDBDatabase::Complete(int64_t transaction_id) {
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_factory_client.cc b/third_party/blink/renderer/modules/indexeddb/idb_factory_client.cc index cdab81a..be3d484 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_factory_client.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_factory_client.cc
@@ -35,11 +35,13 @@ #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" #include "third_party/blink/public/platform/web_blob_info.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/dom/quota_exceeded_error.h" #include "third_party/blink/renderer/modules/indexed_db_names.h" #include "third_party/blink/renderer/modules/indexeddb/idb_metadata.h" #include "third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h" #include "third_party/blink/renderer/modules/indexeddb/idb_value.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" namespace blink { @@ -86,8 +88,15 @@ IDBOpenDBRequest* request = request_.Get(); Detach(); - request->OnDBFactoryError(MakeGarbageCollected<DOMException>( - static_cast<DOMExceptionCode>(code), message)); + DOMException* dom_exception; + if (code == mojom::blink::IDBException::kQuotaError && + RuntimeEnabledFeatures::QuotaExceededErrorUpdateEnabled()) { + dom_exception = MakeGarbageCollected<QuotaExceededError>(message); + } else { + dom_exception = MakeGarbageCollected<DOMException>( + static_cast<DOMExceptionCode>(code), message); + } + request->OnDBFactoryError(dom_exception); } void IDBFactoryClient::OpenSuccess(
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/third_party/blink/renderer/modules/indexeddb/idb_request.cc index b59870f..38231a4b 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -43,6 +43,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_union_idbcursor_idbindex_idbobjectstore.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_union_idbindex_idbobjectstore.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/dom/quota_exceeded_error.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/modules/indexed_db_names.h" @@ -56,6 +57,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { @@ -662,12 +664,19 @@ } probe::AsyncTask async_task(GetExecutionContext(), &async_task_context_, "error"); - auto* exception = MakeGarbageCollected<DOMException>( - static_cast<DOMExceptionCode>(code), - error ? error->error_message : "Invalid response"); + + DOMException* dom_exception; + auto message = error ? error->error_message : "Invalid response"; + if (code == mojom::blink::IDBException::kQuotaError && + RuntimeEnabledFeatures::QuotaExceededErrorUpdateEnabled()) { + dom_exception = MakeGarbageCollected<QuotaExceededError>(message); + } else { + dom_exception = MakeGarbageCollected<DOMException>( + static_cast<DOMExceptionCode>(code), message); + } transaction_->EnqueueResult(std::make_unique<IDBRequestQueueItem>( - this, exception, + this, dom_exception, WTF::BindOnce(&IDBTransaction::OnResultReady, WrapPersistent(transaction_.Get())))); }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_queue_item.cc b/third_party/blink/renderer/modules/indexeddb/idb_request_queue_item.cc index 38e57c84..7ebe03c 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request_queue_item.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request_queue_item.cc
@@ -12,11 +12,13 @@ #include "base/memory/scoped_refptr.h" #include "mojo/public/cpp/bindings/associated_receiver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/dom/quota_exceeded_error.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key.h" #include "third_party/blink/renderer/modules/indexeddb/idb_request.h" #include "third_party/blink/renderer/modules/indexeddb/idb_request_loader.h" #include "third_party/blink/renderer/modules/indexeddb/idb_value.h" #include "third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { @@ -88,9 +90,18 @@ void OnError(mojom::blink::IDBErrorPtr error) override { DCHECK(active_); + DOMException* dom_exception; + if (error->error_code == mojom::blink::IDBException::kQuotaError && + RuntimeEnabledFeatures::QuotaExceededErrorUpdateEnabled()) { + dom_exception = + MakeGarbageCollected<QuotaExceededError>(error->error_message); + } else { + dom_exception = MakeGarbageCollected<DOMException>( + static_cast<DOMExceptionCode>(error->error_code), + error->error_message); + } owner_->response_type_ = IDBRequestQueueItem::kError; - owner_->error_ = MakeGarbageCollected<DOMException>( - static_cast<DOMExceptionCode>(error->error_code), error->error_message); + owner_->error_ = dom_exception; active_ = false; owner_->OnResultReady(); }
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition.cc b/third_party/blink/renderer/modules/speech/speech_recognition.cc index 7751523..f65fad9 100644 --- a/third_party/blink/renderer/modules/speech/speech_recognition.cc +++ b/third_party/blink/renderer/modules/speech/speech_recognition.cc
@@ -499,9 +499,8 @@ ExecutionContextLifecycleObserver(window), PageVisibilityObserver(window->GetFrame() ? window->GetFrame()->GetPage() : nullptr), - grammars_(SpeechGrammarList::Create()), // FIXME: The spec is not clear - // on the default value for the - // grammars attribute. + grammars_(SpeechGrammarList::Create()), + phrases_(SpeechRecognitionPhraseList::Create({})), controller_(SpeechRecognitionController::From(*window)), receiver_(this, window), session_(window) {}
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 04c10fcd..3126c81 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -755,7 +755,7 @@ "fonts/shaping/glyph_data_range.cc", "fonts/shaping/glyph_data_range.h", "fonts/shaping/glyph_index_result.h", - "fonts/shaping/glyph_offset_array.h", + "fonts/shaping/glyph_offset_iterator.h", "fonts/shaping/han_kerning.cc", "fonts/shaping/han_kerning.h", "fonts/shaping/harfbuzz_face.cc",
diff --git a/third_party/blink/renderer/platform/bindings/exception_code.h b/third_party/blink/renderer/platform/bindings/exception_code.h index b41391a..c277546 100644 --- a/third_party/blink/renderer/platform/bindings/exception_code.h +++ b/third_party/blink/renderer/platform/bindings/exception_code.h
@@ -68,7 +68,6 @@ kNetworkError = 19, kAbortError = 20, kURLMismatchError = 21, - kQuotaExceededError = 22, kTimeoutError = 23, kInvalidNodeTypeError = 24, kDataCloneError = 25, @@ -90,6 +89,7 @@ kOperationError, kNotAllowedError, kOptOutError, + kQuotaExceededError, // The rest of entries are defined out of scope of Web IDL.
diff --git a/third_party/blink/renderer/platform/fonts/shaping/glyph_offset_array.h b/third_party/blink/renderer/platform/fonts/shaping/glyph_offset_array.h deleted file mode 100644 index 43936e1..0000000 --- a/third_party/blink/renderer/platform/fonts/shaping/glyph_offset_array.h +++ /dev/null
@@ -1,179 +0,0 @@ -// Copyright 2024 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_GLYPH_OFFSET_ARRAY_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_GLYPH_OFFSET_ARRAY_H_ - -#include "third_party/blink/renderer/platform/fonts/shaping/glyph_data.h" -#include "third_party/blink/renderer/platform/fonts/shaping/glyph_data_range.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" - -namespace blink { - -// A array of glyph offsets. If all offsets are zero, we don't allocate -// storage for reducing memory usage. -class PLATFORM_EXPORT GlyphOffsetArray final { - DISALLOW_NEW(); - - public: - GlyphOffsetArray() = default; - GlyphOffsetArray(const GlyphOffsetArray& other) : storage_(other.storage_) {} - - // The `span` of `GlyphOffset` if `HasStorage()`, or an empty span. - explicit operator base::span<const GlyphOffset>() const { - return base::span{storage_}; - } - - // A return value of |GetOffsets()| to represent optional |GlyphOffset| - // array. - template <bool has_non_zero_glyph_offsets> - struct iterator final {}; - - template <bool has_non_zero_glyph_offsets> - iterator<has_non_zero_glyph_offsets> GetIterator() const { - return iterator<has_non_zero_glyph_offsets>(*this); - } - - size_t ByteSize() const { - return HasStorage() ? AllocatedSize() * sizeof(GlyphOffset) : 0; - } - - void CopyFrom(const GlyphOffsetArray& other1, - wtf_size_t size1, - const GlyphOffsetArray& other2, - wtf_size_t size2) { - other1.CheckSize(size1); - other2.CheckSize(size2); - DCHECK(size1); - DCHECK(size2); - const wtf_size_t size = size1 + size2; - if (other1.HasStorage()) { - AllocateStorageIfNeeded(size); - std::ranges::copy(other1.storage_, GetStorage()); - } - if (other2.HasStorage()) { - AllocateStorageIfNeeded(size); - std::ranges::copy(other2.storage_, UNSAFE_TODO(GetStorage() + size1)); - } - } - - void CopyFromRange(const GlyphDataRange& range) { - if (!range.HasOffsets() || range.IsEmpty()) { - storage_.clear(); - return; - } - AllocateStorage(range.size()); - std::ranges::copy(range.Offsets(), GetStorage()); - } - - GlyphOffset* GetStorage() { return storage_.data(); } - const GlyphOffset* GetStorage() const { return storage_.data(); } - bool HasStorage() const { return !storage_.empty(); } - wtf_size_t AllocatedSize() const { return storage_.size(); } - - void Reverse() { storage_.Reverse(); } - - void Shrink(unsigned new_size) { - DCHECK_GE(new_size, 1u); - if (!HasStorage()) { - return; - } - storage_.Shrink(new_size); - } - - // Functions to change one element. - void AddHeightAt(unsigned index, float delta, wtf_size_t size) { - DCHECK_NE(delta, 0.0f); - AllocateStorageIfNeeded(size); - storage_[index].set_y(storage_[index].y() + delta); - } - - void AddWidthAt(unsigned index, float delta, wtf_size_t size) { - DCHECK_NE(delta, 0.0f); - AllocateStorageIfNeeded(size); - storage_[index].set_x(storage_[index].x() + delta); - } - - void SetAt(unsigned index, GlyphOffset offset, wtf_size_t size) { - if (!HasStorage()) { - if (offset.IsZero()) { - return; - } - AllocateStorage(size); - } - storage_[index] = offset; - } - - void Trace(Visitor* visitor) const { visitor->Trace(storage_); } - - private: - void CheckSize(wtf_size_t size) const { - CHECK(!HasStorage() || size == AllocatedSize()); - } - - // Note: HarfBuzzShaperTest.ShapeVerticalUpright uses non-zero glyph offset. - void AllocateStorage(wtf_size_t size) { - DCHECK_GE(size, 1u); - DCHECK(!HasStorage()); - storage_.resize(size); - } - - void AllocateStorageIfNeeded(wtf_size_t size) { - CheckSize(size); - if (!HasStorage()) { - AllocateStorage(size); - } - } - - HeapVector<GlyphOffset> storage_; -}; - -// For non-zero glyph offset array -template <> -struct GlyphOffsetArray::iterator<true> final { - STACK_ALLOCATED(); - - public: - explicit iterator(base::span<const GlyphOffset> offsets) - : iterator_(offsets.begin()) { - // An empty span should use `has_non_zero_glyph_offsets = false`. - DCHECK(!offsets.empty()); - } - - // The constructor for ShapeResult - explicit iterator(const GlyphOffsetArray& array) - : iterator(static_cast<base::span<const GlyphOffset>>(array)) {} - - // The constructor for ShapeResultView - explicit iterator(const GlyphDataRange& range) : iterator(range.Offsets()) {} - - GlyphOffset operator*() const { return *iterator_; } - void operator++() { ++iterator_; } - void operator+=(ptrdiff_t s) { iterator_ += s; } - - GlyphOffset operator[](size_t i) const { return *(iterator_ + i); } - - private: - base::span<const GlyphOffset>::iterator iterator_; -}; - -// For zero glyph offset array -template <> -struct GlyphOffsetArray::iterator<false> final { - explicit iterator(const GlyphOffsetArray& array) { - DCHECK(!array.HasStorage()); - } - explicit iterator(const GlyphDataRange& range) { - DCHECK(!range.HasOffsets()); - } - - GlyphOffset operator*() const { return GlyphOffset(); } - void operator++() {} - void operator+=(ptrdiff_t) {} - GlyphOffset operator[](size_t) const { return GlyphOffset(); } -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_GLYPH_OFFSET_ARRAY_H_
diff --git a/third_party/blink/renderer/platform/fonts/shaping/glyph_offset_iterator.h b/third_party/blink/renderer/platform/fonts/shaping/glyph_offset_iterator.h new file mode 100644 index 0000000..a515608 --- /dev/null +++ b/third_party/blink/renderer/platform/fonts/shaping/glyph_offset_iterator.h
@@ -0,0 +1,67 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_GLYPH_OFFSET_ITERATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_GLYPH_OFFSET_ITERATOR_H_ + +#include "third_party/blink/renderer/platform/fonts/shaping/glyph_data.h" +#include "third_party/blink/renderer/platform/fonts/shaping/glyph_data_range.h" +#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" + +namespace blink { + +// An iterator for `ShapeResultRun::offsets_`. +// +// Since it could be empty if there are no glyph offsets in the run, this +// iterator makes iterating offsets to be no-operations in such case. +template <bool has_non_zero_glyph_offsets> +struct PLATFORM_EXPORT GlyphOffsetIterator final {}; + +// For non-zero glyph offset array +template <> +struct GlyphOffsetIterator<true> final { + STACK_ALLOCATED(); + + public: + explicit GlyphOffsetIterator(base::span<const GlyphOffset> offsets) + : iterator_(offsets.begin()) { + // An empty span should use `has_non_zero_glyph_offsets = false`. + DCHECK(!offsets.empty()); + } + + // The constructor for ShapeResultView + explicit GlyphOffsetIterator(const GlyphDataRange& range) + : GlyphOffsetIterator(range.Offsets()) {} + + GlyphOffset operator*() const { return *iterator_; } + void operator++() { ++iterator_; } + void operator+=(ptrdiff_t s) { iterator_ += s; } + + GlyphOffset operator[](size_t i) const { return *(iterator_ + i); } + + private: + base::span<const GlyphOffset>::iterator iterator_; +}; + +// For zero glyph offset array +template <> +struct GlyphOffsetIterator<false> final { + explicit GlyphOffsetIterator(base::span<const GlyphOffset> offsets) { + // An empty span should use `has_non_zero_glyph_offsets = false`. + DCHECK(offsets.empty()); + } + + explicit GlyphOffsetIterator(const GlyphDataRange& range) { + DCHECK(!range.HasOffsets()); + } + + GlyphOffset operator*() const { return GlyphOffset(); } + void operator++() {} + void operator+=(ptrdiff_t) {} + GlyphOffset operator[](size_t) const { return GlyphOffset(); } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_GLYPH_OFFSET_ITERATOR_H_
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_run.h b/third_party/blink/renderer/platform/fonts/shaping/shape_result_run.h index 5aa0fc3..1171ef7e 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_run.h +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_run.h
@@ -42,7 +42,7 @@ #include "third_party/blink/renderer/platform/fonts/shaping/glyph_data.h" #include "third_party/blink/renderer/platform/fonts/shaping/glyph_data_range.h" #include "third_party/blink/renderer/platform/fonts/shaping/glyph_index_result.h" -#include "third_party/blink/renderer/platform/fonts/shaping/glyph_offset_array.h" +#include "third_party/blink/renderer/platform/fonts/shaping/glyph_offset_iterator.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -274,11 +274,11 @@ HarfBuzzRunGlyphData& back() { return data_.back(); } const HarfBuzzRunGlyphData& back() const { return data_.back(); } - bool HasNonZeroOffsets() const { return offsets_.HasStorage(); } + bool HasNonZeroOffsets() const { return !offsets_.empty(); } size_t ByteSize() const { return sizeof(*this) + size() * sizeof(HarfBuzzRunGlyphData) + - offsets_.ByteSize(); + sizeof(GlyphOffset) * offsets_.size(); } // The `span` of `GlyphOffset` if `HasNonZeroOffsets()`, or an empty span. @@ -287,8 +287,8 @@ } template <bool has_non_zero_glyph_offsets> - GlyphOffsetArray::iterator<has_non_zero_glyph_offsets> GetOffsets() const { - return offsets_.GetIterator<has_non_zero_glyph_offsets>(); + GlyphOffsetIterator<has_non_zero_glyph_offsets> GetOffsets() const { + return GlyphOffsetIterator<has_non_zero_glyph_offsets>(offsets_); } // Note: Caller should be adjust |HarfBuzzRunGlyphData.character_index|. @@ -301,8 +301,16 @@ std::ranges::copy(other1.data_, data_.data()); std::ranges::copy(other2.data_, UNSAFE_TODO(data_.data() + other1.size())); - offsets_.CopyFrom(other1.offsets_, other1.size(), other2.offsets_, - other2.size()); + + if (other1.HasNonZeroOffsets()) { + AllocateOffsetsIfNeeded(); + std::ranges::copy(other1.offsets_, offsets_.begin()); + } + if (other2.HasNonZeroOffsets()) { + AllocateOffsetsIfNeeded(); + std::ranges::copy(other2.offsets_, + UNSAFE_TODO(offsets_.begin() + other1.size())); + } } // Note: Caller should be adjust |HarfBuzzRunGlyphData.character_index|. @@ -310,19 +318,35 @@ CHECK_EQ(range.size(), size()); static_assert(std::is_trivially_copyable_v<HarfBuzzRunGlyphData>); std::ranges::copy(range, data_.data()); - offsets_.CopyFromRange(range); + + if (!range.HasOffsets() || range.IsEmpty()) { + offsets_.clear(); + } else { + AllocateOffsets(); + std::ranges::copy(range.Offsets(), offsets_.begin()); + } } void AddOffsetHeightAt(unsigned index, float delta) { - offsets_.AddHeightAt(index, delta, size()); + DCHECK_NE(delta, 0.0f); + AllocateOffsetsIfNeeded(); + offsets_[index].set_y(offsets_[index].y() + delta); } void AddOffsetWidthAt(unsigned index, float delta) { - offsets_.AddWidthAt(index, delta, size()); + DCHECK_NE(delta, 0.0f); + AllocateOffsetsIfNeeded(); + offsets_[index].set_x(offsets_[index].x() + delta); } void SetOffsetAt(unsigned index, GlyphOffset offset) { - offsets_.SetAt(index, offset, size()); + if (!HasNonZeroOffsets()) { + if (offset.IsZero()) { + return; + } + AllocateOffsets(); + } + offsets_[index] = offset; } // Vector<HarfBuzzRunGlyphData> like functions @@ -357,7 +381,9 @@ } DCHECK_LT(new_size, size()); data_.Shrink(new_size); - offsets_.Shrink(new_size); + if (HasNonZeroOffsets()) { + offsets_.Shrink(new_size); + } } void Trace(Visitor* visitor) const { @@ -366,12 +392,24 @@ } private: + void AllocateOffsets() { + DCHECK_GE(size(), 1u); + DCHECK(!HasNonZeroOffsets()); + offsets_.resize(size()); + } + + void AllocateOffsetsIfNeeded() { + if (!HasNonZeroOffsets()) { + AllocateOffsets(); + } + } + // Note: |offsets_| holds number of elements instead o here to reduce // memory usage. HeapVector<HarfBuzzRunGlyphData> data_; // |offsets_| holds collection of offset for |data_[i]|. // When all offsets are zero, we don't allocate for reducing memory usage. - GlyphOffsetArray offsets_; + HeapVector<GlyphOffset> offsets_; }; void CheckConsistency() const {
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_run_test.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result_run_test.cc index f2a4b07..c22dfe7 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_run_test.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_run_test.cc
@@ -4,101 +4,152 @@ #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_run.h" +#include <hb.h> + #include "testing/gtest/include/gtest/gtest.h" namespace blink { -class ShapeResultRunTest : public testing::Test {}; +namespace { -TEST_F(ShapeResultRunTest, CopyConstructor) { - GlyphOffsetArray offsets; - - GlyphOffsetArray offsets2(offsets); - EXPECT_FALSE(offsets2.HasStorage()); - - offsets.SetAt(0, GlyphOffset(1, 1), 2); - GlyphOffsetArray offsets3(offsets); - ASSERT_TRUE(offsets3.HasStorage()); - EXPECT_EQ(GlyphOffset(1, 1), offsets3.GetStorage()[0]); +ShapeResultRun* CreateTestShapeResultRun(unsigned num_glyphs, + unsigned num_characters) { + return MakeGarbageCollected<ShapeResultRun>( + /*font*/ nullptr, hb_direction_t::HB_DIRECTION_LTR, + CanvasRotationInVertical::kRegular, hb_script_t::HB_SCRIPT_LATIN, + /*start_index*/ 0, num_glyphs, num_characters); } -TEST_F(ShapeResultRunTest, CopyFromRange) { - ShapeResultRun* run = MakeGarbageCollected<ShapeResultRun>( - nullptr, HB_DIRECTION_LTR, CanvasRotationInVertical::kRegular, - HB_SCRIPT_COMMON, 0, 2, 2); +} // namespace - GlyphOffsetArray offsets2; - offsets2.CopyFromRange(GlyphDataRange{*run}); - EXPECT_FALSE(offsets2.HasStorage()); +class ShapeResultRunTest : public testing::Test {}; + +TEST_F(ShapeResultRunTest, GlyphDataCopyConstructor) { + ShapeResultRun* run = CreateTestShapeResultRun(2, 2); + + ShapeResultRun* run2 = MakeGarbageCollected<ShapeResultRun>(*run); + EXPECT_FALSE(run2->glyph_data_.HasNonZeroOffsets()); + + run->glyph_data_.SetOffsetAt(0, GlyphOffset(1, 1)); + ShapeResultRun* run3 = MakeGarbageCollected<ShapeResultRun>(*run); + ASSERT_TRUE(run3->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(GlyphOffset(1, 1), run3->glyph_data_.Offsets()[0]); +} + +TEST_F(ShapeResultRunTest, GlyphDataCopyFromRange) { + ShapeResultRun* run = CreateTestShapeResultRun(2, 2); + + ShapeResultRun* run2 = CreateTestShapeResultRun(2, 2); + run2->glyph_data_.CopyFromRange(GlyphDataRange{*run}); + EXPECT_FALSE(run2->glyph_data_.HasNonZeroOffsets()); run->glyph_data_.SetOffsetAt(0, GlyphOffset(1, 1)); ASSERT_TRUE(run->glyph_data_.HasNonZeroOffsets()); - GlyphOffsetArray offsets3; - offsets3.CopyFromRange(GlyphDataRange{*run}); - ASSERT_TRUE(offsets3.HasStorage()); - EXPECT_EQ(GlyphOffset(1, 1), offsets3.GetStorage()[0]); + ShapeResultRun* run3 = CreateTestShapeResultRun(2, 2); + run3->glyph_data_.CopyFromRange(GlyphDataRange{*run}); + ASSERT_TRUE(run3->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(GlyphOffset(1, 1), run3->glyph_data_.Offsets()[0]); } -TEST_F(ShapeResultRunTest, GlyphOffsetArrayReverse) { - GlyphOffsetArray offsets; +TEST_F(ShapeResultRunTest, GlyphDataReverse) { + ShapeResultRun* run = CreateTestShapeResultRun(2, 2); - offsets.Reverse(); - EXPECT_FALSE(offsets.HasStorage()); + run->glyph_data_.Reverse(); + EXPECT_FALSE(run->glyph_data_.HasNonZeroOffsets()); - offsets.SetAt(0, GlyphOffset(1, 1), 2); - ASSERT_TRUE(offsets.HasStorage()); - offsets.Reverse(); - EXPECT_EQ(GlyphOffset(), offsets.GetStorage()[0]); - EXPECT_EQ(GlyphOffset(1, 1), UNSAFE_TODO(offsets.GetStorage()[1])); + run->glyph_data_.SetOffsetAt(0, GlyphOffset(1, 1)); + ASSERT_TRUE(run->glyph_data_.HasNonZeroOffsets()); + run->glyph_data_.Reverse(); + EXPECT_EQ(GlyphOffset(), run->glyph_data_.Offsets()[0]); + EXPECT_EQ(GlyphOffset(1, 1), run->glyph_data_.Offsets()[1]); } -TEST_F(ShapeResultRunTest, GlyphOffsetArraySetAddOffsetHeightAt) { - GlyphOffsetArray offsets; +TEST_F(ShapeResultRunTest, GlyphDataAddOffsetHeightAt) { + ShapeResultRun* run = CreateTestShapeResultRun(2, 2); - offsets.AddHeightAt(1, 1.5f, 2); - ASSERT_TRUE(offsets.HasStorage()); - EXPECT_EQ(GlyphOffset(0, 1.5f), UNSAFE_TODO(offsets.GetStorage()[1])); + run->glyph_data_.AddOffsetHeightAt(1, 1.5f); + ASSERT_TRUE(run->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(GlyphOffset(0, 1.5f), run->glyph_data_.Offsets()[1]); - offsets.AddHeightAt(1, 2.0f, 2); - ASSERT_TRUE(offsets.HasStorage()); - EXPECT_EQ(GlyphOffset(0, 3.5f), UNSAFE_TODO(offsets.GetStorage()[1])); + run->glyph_data_.AddOffsetHeightAt(1, 2.0f); + ASSERT_TRUE(run->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(GlyphOffset(0, 3.5f), run->glyph_data_.Offsets()[1]); } -TEST_F(ShapeResultRunTest, GlyphOffsetArraySetAddOffsetWidthAt) { - GlyphOffsetArray offsets; +TEST_F(ShapeResultRunTest, GlyphDataAddOffsetWidthAt) { + ShapeResultRun* run = CreateTestShapeResultRun(2, 2); - offsets.AddWidthAt(1, 1.5f, 2); - ASSERT_TRUE(offsets.HasStorage()); - EXPECT_EQ(GlyphOffset(1.5f, 0), UNSAFE_TODO(offsets.GetStorage()[1])); + run->glyph_data_.AddOffsetWidthAt(1, 1.5f); + ASSERT_TRUE(run->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(GlyphOffset(1.5f, 0), run->glyph_data_.Offsets()[1]); - offsets.AddWidthAt(1, 2.0f, 2); - ASSERT_TRUE(offsets.HasStorage()); - EXPECT_EQ(GlyphOffset(3.5f, 0), UNSAFE_TODO(offsets.GetStorage()[1])); + run->glyph_data_.AddOffsetWidthAt(1, 2.0f); + ASSERT_TRUE(run->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(GlyphOffset(3.5f, 0), run->glyph_data_.Offsets()[1]); } -TEST_F(ShapeResultRunTest, GlyphOffsetArraySetAt) { - GlyphOffsetArray offsets; +TEST_F(ShapeResultRunTest, GlyphDataSetAt) { + ShapeResultRun* run = CreateTestShapeResultRun(2, 2); - offsets.SetAt(0, GlyphOffset(), 2); - EXPECT_FALSE(offsets.HasStorage()); + run->glyph_data_.SetOffsetAt(0, GlyphOffset()); + // Setting a zero offset should not allocate storage if it wasn't already + // allocated. + EXPECT_FALSE(run->glyph_data_.HasNonZeroOffsets()); - offsets.SetAt(1, GlyphOffset(1, 1), 2); - EXPECT_TRUE(offsets.HasStorage()); + run->glyph_data_.SetOffsetAt(1, GlyphOffset(1, 1)); + ASSERT_TRUE(run->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(GlyphOffset(1, 1), run->glyph_data_.Offsets()[1]); } -TEST_F(ShapeResultRunTest, GlyphOffsetArrayShrink) { - GlyphOffsetArray offsets; +TEST_F(ShapeResultRunTest, GlyphDataShrink) { + // Case 1: Shrink when no offsets are allocated. + ShapeResultRun* run_no_offsets = CreateTestShapeResultRun(3, 3); + EXPECT_FALSE(run_no_offsets->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(3u, run_no_offsets->glyph_data_.size()); - offsets.Shrink(2); - EXPECT_FALSE(offsets.HasStorage()); + run_no_offsets->glyph_data_.Shrink(2); // Shrink from 3 to 2 + // Offsets should remain unallocated. + EXPECT_FALSE(run_no_offsets->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(2u, run_no_offsets->glyph_data_.size()); // Data should shrink. - offsets.SetAt(0, GlyphOffset(1, 1), 2); - ASSERT_TRUE(offsets.HasStorage()); + run_no_offsets->glyph_data_.Shrink(1); // Shrink from 2 to 1 + EXPECT_FALSE(run_no_offsets->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(1u, run_no_offsets->glyph_data_.size()); - offsets.Shrink(1); - ASSERT_TRUE(offsets.HasStorage()); - EXPECT_EQ(GlyphOffset(1, 1), offsets.GetStorage()[0]); + // Case 2: Shrink when offsets are allocated. + ShapeResultRun* run_with_offsets = CreateTestShapeResultRun(3, 3); + run_with_offsets->glyph_data_.SetOffsetAt(0, GlyphOffset(1, 0)); + run_with_offsets->glyph_data_.SetOffsetAt(1, GlyphOffset(2, 0)); + run_with_offsets->glyph_data_.SetOffsetAt(2, GlyphOffset(3, 0)); + ASSERT_TRUE(run_with_offsets->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(3u, run_with_offsets->glyph_data_.size()); + ASSERT_EQ(3u, run_with_offsets->glyph_data_.Offsets().size()); + + // Shrink to a smaller size. + run_with_offsets->glyph_data_.Shrink(2); + ASSERT_TRUE(run_with_offsets->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(2u, run_with_offsets->glyph_data_.size()); + ASSERT_EQ(2u, run_with_offsets->glyph_data_.Offsets().size()); + EXPECT_EQ(GlyphOffset(1, 0), run_with_offsets->glyph_data_.Offsets()[0]); + EXPECT_EQ(GlyphOffset(2, 0), run_with_offsets->glyph_data_.Offsets()[1]); + + // Shrink further. + run_with_offsets->glyph_data_.Shrink(1); + ASSERT_TRUE(run_with_offsets->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(1u, run_with_offsets->glyph_data_.size()); + ASSERT_EQ(1u, run_with_offsets->glyph_data_.Offsets().size()); + EXPECT_EQ(GlyphOffset(1, 0), run_with_offsets->glyph_data_.Offsets()[0]); + + // Case 3: Shrink to the same size (no-op for vector sizes). + ShapeResultRun* run_shrink_same_size = CreateTestShapeResultRun(2, 2); + run_shrink_same_size->glyph_data_.SetOffsetAt(0, GlyphOffset(5, 0)); + ASSERT_TRUE(run_shrink_same_size->glyph_data_.HasNonZeroOffsets()); + run_shrink_same_size->glyph_data_.Shrink(2); // Shrink to current size. + ASSERT_TRUE(run_shrink_same_size->glyph_data_.HasNonZeroOffsets()); + EXPECT_EQ(2u, run_shrink_same_size->glyph_data_.size()); + ASSERT_EQ(2u, run_shrink_same_size->glyph_data_.Offsets().size()); + EXPECT_EQ(GlyphOffset(5, 0), run_shrink_same_size->glyph_data_.Offsets()[0]); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h index f87afcd..c62a856f 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h
@@ -8,7 +8,7 @@ #include "base/containers/span.h" #include "third_party/blink/renderer/platform/fonts/shaping/glyph_data.h" #include "third_party/blink/renderer/platform/fonts/shaping/glyph_data_range.h" -#include "third_party/blink/renderer/platform/fonts/shaping/glyph_offset_array.h" +#include "third_party/blink/renderer/platform/fonts/shaping/glyph_offset_iterator.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h" @@ -186,9 +186,8 @@ return *(UNSAFE_TODO(range_.begin() + index)); } template <bool has_non_zero_glyph_offsets> - GlyphOffsetArray::iterator<has_non_zero_glyph_offsets> GetGlyphOffsets() - const { - return GlyphOffsetArray::iterator<has_non_zero_glyph_offsets>(range_); + GlyphOffsetIterator<has_non_zero_glyph_offsets> GetGlyphOffsets() const { + return GlyphOffsetIterator<has_non_zero_glyph_offsets>(range_); } bool HasGlyphOffsets() const { return range_.HasOffsets(); } // The end character index of |this| without considering offsets in
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 3a01973..db2d458 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -2722,7 +2722,7 @@ }, { name: "LanguageDetectionAPI", - status: "experimental", + status: "stable", origin_trial_feature_name: "LanguageDetectionAPI", origin_trial_allows_third_party: true, base_feature_status: "enabled", @@ -3711,6 +3711,11 @@ base_feature: "none", }, { + // ChromeStatus: https://chromestatus.com/feature/6194847180128256 + name: "QuotaExceededErrorUpdate", + status: "experimental", + }, + { // crbug.com/323953913 // Fix looking for next radio button in the form's scope. This was added // in M135 and can be removed after M138.
diff --git a/third_party/blink/renderer/platform/weborigin/kurl.cc b/third_party/blink/renderer/platform/weborigin/kurl.cc index 3cfab81..f834f8c 100644 --- a/third_party/blink/renderer/platform/weborigin/kurl.cc +++ b/third_party/blink/renderer/platform/weborigin/kurl.cc
@@ -483,11 +483,11 @@ // the URL and set "m_isValid." url::RawCanonOutputT<char> canon_protocol; url::Component protocol_component; - if (!url::CanonicalizeScheme(new_protocol_utf8.data(), - url::Component(0, new_protocol_utf8.size()), + if (!url::CanonicalizeScheme(new_protocol_utf8.AsStringView(), &canon_protocol, &protocol_component) || - protocol_component.is_empty()) + protocol_component.is_empty()) { return false; + } DCHECK_EQ(protocol_component.begin, 0); const wtf_size_t protocol_length =
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index da019e44..debe802 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -5413,6 +5413,13 @@ {} ] ], + "text-decoration-first-line-layer-crash.html": [ + "5f5b7e7b9e4774d74224000271e2115ef9792540", + [ + null, + {} + ] + ], "text-decoration-first-line-multi-crash.html": [ "f6176334ad6e6ef2662a8f89785f601f48a762cf", [ @@ -9503,6 +9510,13 @@ {} ] ], + "scroll-timeline-completion-crash.html": [ + "fb7ecd1ed1bff87cb45bfdbcbb9ad7504a9fda9c", + [ + null, + {} + ] + ], "viewport-100vh.html": [ "cc862bd29955ec0c6730614a4eb72e3565c46cd4", [ @@ -20601,8 +20615,8 @@ {} ] ], - "SpeechRecognition-recognitionContext-manual.https.html": [ - "1039baa2825baed883e1c95c80247ee96a2ee33d", + "SpeechRecognition-phrases-manual.https.html": [ + "2d0b19ab46ce3c41610b298750cbb0ca85832513", [ null, {} @@ -73956,7 +73970,7 @@ ] ], "align-self-stretch-auto-margins-aspect-ratio.html": [ - "4eaa9d2f3a6dbab63d3d931d4c58a427bc11976f", + "347005204e333eeb813bd531ec1aa12e734e37d4", [ null, [ @@ -73969,7 +73983,7 @@ ] ], "align-self-stretch-auto-margins.html": [ - "9d1b6454c848c02b7fef360fb447d4d6b46ee8c0", + "9d6eb2306534d5d2a30c5724abf11e994470b92c", [ null, [ @@ -74008,7 +74022,7 @@ ] ], "justify-self-stretch-auto-margins-aspect-ratio.html": [ - "c50b32f089b1b0043ac5d9dbd0f79906d82827f3", + "bc6120584c248659646cad0a3f6349a23f4b8744", [ null, [ @@ -74021,7 +74035,7 @@ ] ], "justify-self-stretch-auto-margins.html": [ - "7d7b4bfc8570d3dde59fc903de7cb173b0b5baf8", + "675321fc2b12b16816e5355d420e51e3b0195aac", [ null, [ @@ -74253,7 +74267,7 @@ {} ] ], - "justify-items-anonymous.tentative.html": [ + "justify-items-anonymous.html": [ "641dea1f54b2f0cea29bc4c4c82e023a479e3d3c", [ null, @@ -74280,7 +74294,7 @@ ] ], "justify-self-auto-margins-2.html": [ - "33c98d6c1dfb43ff29f5c63472f041add65faff1", + "e81c4bba6f4fb98f79a3abfced011d896bd734d3", [ null, [ @@ -74538,7 +74552,7 @@ ] ], "anchor-center-visibility-change.html": [ - "0f7d805844f010d9854301c094b5ce6fd03d13fa", + "e5559433206741222198471088ddd165cf6786bf", [ null, [ @@ -75216,6 +75230,19 @@ {} ] ], + "position-area-visibility-change.html": [ + "61d8ab50284aed3f7e2c3abc13180af7967e1463", + [ + null, + [ + [ + "/css/css-anchor-position/reference/position-area-visibility-change-ref.html", + "==" + ] + ], + {} + ] + ], "position-try-fallbacks-001.html": [ "b41e326800cf26a85b762ae34213e20aa47905b2", [ @@ -134265,6 +134292,32 @@ {} ] ], + "flex-gap-decorations-020.html": [ + "6c07493d14d576026e7693b4391fd8baeadbba14", + [ + null, + [ + [ + "/css/css-gaps/flex/flex-gap-decorations-020-ref.html", + "==" + ] + ], + {} + ] + ], + "flex-gap-decorations-021.html": [ + "c59db4f635b361c4f8f5d77c94129264f560d79b", + [ + null, + [ + [ + "/css/css-gaps/flex/flex-gap-decorations-021-ref.html", + "==" + ] + ], + {} + ] + ], "flex-gap-decorations-022.html": [ "5f3b512ef76214b3645c329c92bd06ebf23efd9d", [ @@ -134696,6 +134749,58 @@ {} ] ], + "grid-gap-decorations-034.html": [ + "afe20ef5117b5bc7b628fee1ce86960a9b927adc", + [ + null, + [ + [ + "/css/css-gaps/grid/grid-gap-decorations-034-ref.html", + "==" + ] + ], + {} + ] + ], + "grid-gap-decorations-035.html": [ + "d2fa76094a96e8b7f786ca903288b1a057c999e3", + [ + null, + [ + [ + "/css/css-gaps/grid/grid-gap-decorations-035-ref.html", + "==" + ] + ], + {} + ] + ], + "grid-gap-decorations-036.html": [ + "8b1e1e2e1c2d37e9a3367e3d2224b15ded9ebf57", + [ + null, + [ + [ + "/css/css-gaps/grid/grid-gap-decorations-036-ref.html", + "==" + ] + ], + {} + ] + ], + "grid-gap-decorations-037.html": [ + "656bfee7dfcdd7f568a3ff9bf088c0ece08a57df", + [ + null, + [ + [ + "/css/css-gaps/grid/grid-gap-decorations-037-ref.html", + "==" + ] + ], + {} + ] + ], "grid-gap-decorations-38.html": [ "8b87bcd4860ac50a1c2f3de98cec9599bebb77a3", [ @@ -168146,6 +168251,19 @@ {} ] ], + "multicol-fill-balance-030.html": [ + "9fc1f4e859afb74d151d3a4c2d56fd96aacfdc40", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "multicol-fill-balance-nested-000.html": [ "5e466df8077545b4d6474389d296bc26c5b28b86", [ @@ -282578,6 +282696,19 @@ {} ] ], + "negated-last-of-type-invalidation.html": [ + "40bf8a8f0f4727ffa6b61633e8c2e35dbb812d82", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "negated-negated-first-of-type-when-ancestor-changes.html": [ "7e5376fc31f15febe5db2202e915427ea2e4cc5d", [ @@ -320144,10 +320275,18 @@ [] ], "util.js": [ - "3e95a936304f3190066f3774e9483394d31a501f", + "7eba1467f925a3871bcb9bf445accbf2678fd8f2", [] ] }, + "rewriter": { + "resources": { + "iframe-helper.html": [ + "222c192f04f84f78f6785a7bc274445da5cf864c", + [] + ] + } + }, "summarizer": { "resources": { "iframe-helper.html": [ @@ -320171,6 +320310,14 @@ [] ] } + }, + "writer": { + "resources": { + "iframe-helper.html": [ + "e85e8a5fb408b7029596d86fcd65e2ffd3a57959", + [] + ] + } } }, "ambient-light": { @@ -332726,7 +332873,7 @@ [] ], "anchor-center-visibility-change-ref.html": [ - "66bf9083c3a24e6adad0ad724a1e54ccbe6f568b", + "bc9872a9093680d8584df0e923c658ce589ef271", [] ], "anchor-center-vrl-htb-expected.txt": [ @@ -332956,6 +333103,10 @@ "a4feab487c5c9262e6c71d2f16f4bb83384cdcbe", [] ], + "position-area-visibility-change-ref.html": [ + "87e1804940900132e8b8a062e096924585a5b227", + [] + ], "sticky-anchor-position-invalid-ref.html": [ "c4a5dd37354f61c66b0e2e53847b8fcc16112fc3", [] @@ -350201,6 +350352,14 @@ "flex-gap-decorations-018-ref.html": [ "644a409bd977acb91812666ac2f9a6e1c1b66830", [] + ], + "flex-gap-decorations-020-ref.html": [ + "b708a78a3472f1a903febe26cbec09da22db1f19", + [] + ], + "flex-gap-decorations-021-ref.html": [ + "1e28d73b4e2ce48d62880be1aa66e26f511ab7b1", + [] ] }, "grid": { @@ -350319,6 +350478,22 @@ "grid-gap-decorations-033-ref.html": [ "e26143a6b93e9fdd53d4055234d89e40d98dc2af", [] + ], + "grid-gap-decorations-034-ref.html": [ + "4e964879e795ec6877b6564c04575d296aa4d94b", + [] + ], + "grid-gap-decorations-035-ref.html": [ + "851360a99a4bb9262e24368fed9a81d34f066a45", + [] + ], + "grid-gap-decorations-036-ref.html": [ + "29ed684d85f72c24fcf6e67187c834f5624eeda3", + [] + ], + "grid-gap-decorations-037-ref.html": [ + "4a2ee5bd5c6fbdb25e5a70eac56a9b0bbac5d56f", + [] ] }, "multicol": { @@ -361629,7 +361804,7 @@ [] ], "scroll-initial-target-with-text-fragment-navigation-target.html": [ - "aea8e120c15af61717f79b52ddd2f5c957393725", + "8b3c168af8a101a2421563babcf24c476201a534", [] ], "stash.py": [ @@ -371362,7 +371537,7 @@ [] ], "WEB_FEATURES.yml": [ - "a10f70297916abe13376013b18ae4b2f7cd4dec5", + "e699a40acddb78a7ef04314918aa839519eaa3f2", [] ], "accent-color-checkbox-checked-001-notref.html": [ @@ -371575,7 +371750,7 @@ ], "parsing": { "WEB_FEATURES.yml": [ - "b4ae339c2f3301bc1845c39923c05095d9e48499", + "3be770b3a51dcebaca35d4a92e1f0b4a2e8004b9", [] ], "canonical-order-outline-sub-properties-001-expected.txt": [ @@ -380804,7 +380979,7 @@ [] ], "iframe.html": [ - "3ec761e08a6266ab24fcea357d866f76d8c9ed2f", + "d737dcfc091b7873863e46ba5bdb5e2bef07e2f4", [] ] }, @@ -380813,7 +380988,7 @@ [] ], "user-activation.https-expected.txt": [ - "5b258016a6775998fc2ae6163cd1915d9ea4a494", + "fed8949f2d27e344d58df8bf136e0d486d43511c", [] ] }, @@ -397027,7 +397202,7 @@ [] ], "noopener-helper.js": [ - "6dd2c9bc1c9ac2625be861246160e1a4dd7c4088", + "ead0ef3b34370bc4fc805ab72595beb3dea3deee", [] ], "popup-test.js": [ @@ -397768,7 +397943,7 @@ [] ], "idlharness.https_include=(Document_Window)-expected.txt": [ - "a59b20d054bd2e80a3751d8e005a9ad1a183b7f4", + "e975efd5af5f2240eb4efe84f575100c6a05a740", [] ], "idlharness.https_include=HTML.+-expected.txt": [ @@ -403774,7 +403949,7 @@ [] ], "iframe-loading-lazy-reload-navigation-reload-expected.txt": [ - "3ad8c48808bc4661334beb6a80564c43f6773ab4", + "8d930e94fc176d9f49af0d93f9e1250bf873990e", [] ], "iframe-modify-scrolling-attr-to-yes-ref.html": [ @@ -404535,6 +404710,10 @@ "6a81fd2c5e28412b1316c23a17ab6d5cac48873e", [] ], + "WEB_FEATURES.yml": [ + "c5f2a8811dda16b13199adde7b81e4659f69d57d", + [] + ], "input-text-focused-ref.html": [ "f78a937f17815a6a063a7465bf53fe402cdb671f", [] @@ -404723,6 +404902,10 @@ "ca0f27e1264c80a86a50081786c047cdcb03840d", [] ], + "WEB_FEATURES.yml": [ + "944746a8eece9a2f3ecfd172ff37b98b0a785bb9", + [] + ], "meter-min-rendering-ref.html": [ "f253945968e49902d1f2c2d60d9d8cd230166c6b", [] @@ -404780,6 +404963,10 @@ "DIR_METADATA": [ "fc4f695cfcf8d1113152f89b4e363e756b4668a4", [] + ], + "WEB_FEATURES.yml": [ + "95c7b887c3770a821d37849b7cce77daf81ebf44", + [] ] }, "the-select-element": { @@ -411157,7 +411344,7 @@ [] ], "crash-reporting.idl": [ - "a6737ca8482e1d67c40d6d3618424969fa680f96", + "6eaee138a828f7749026458265e7db598822330f", [] ], "credential-management.idl": [ @@ -411337,7 +411524,7 @@ [] ], "digital-credentials.idl": [ - "e4ebb3b3e8621b668a18dcdeed7974e6446234e0", + "60b63975640c5a131c802ac459d08eb938446df8", [] ], "digital-goods.idl": [ @@ -411861,7 +412048,7 @@ [] ], "speech-api.idl": [ - "0e07b4619a5b80e901f0b8c17a208f9077f9187f", + "94a416f262b361e326c5b3c89fa8d160c1118b48", [] ], "storage-access.idl": [ @@ -411900,6 +412087,10 @@ "19f55156a6e3a40c8a6c78a303754c1c8ace58de", [] ], + "translation-api.idl": [ + "6cbad38938a15f373936cf760a9b30b8506bd5e0", + [] + ], "trust-token-api.idl": [ "9b74290da724b62fb91b3f5532b689cf70a10045", [] @@ -412073,7 +412264,7 @@ [] ], "webnn.idl": [ - "37fcc32501efbeb38c9686a8fc96e1ce062eb30a", + "8d0e485bc76e49a616847f305d0b81cc5cce0589", [] ], "webrtc-encoded-transform.idl": [ @@ -420154,6 +420345,10 @@ "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", [] ], + "WEB_FEATURES.yml": [ + "989f1fc7e45c3c1d04746a4cf627981a8652d4d2", + [] + ], "resources": { "child.html": [ "4d6895125a2acaad00cc2bc849e026a2632dd88e", @@ -420877,7 +421072,7 @@ ] }, "idlharness.js": [ - "d52ba9fd3c417955f5cb6eb68f96113057128318", + "2eb710c1827cda28b7bf75acd5b3a3d6c67d66fc", [] ], "idlharness.js.headers": [ @@ -420945,7 +421140,7 @@ [] ], "testharness.js": [ - "6ccede34483b227cc41fcb15235e56aa60d4022e", + "32f033a569b166b238fa9b02fbf99639f1f2f90c", [] ], "testharness.js.headers": [ @@ -435030,11 +435225,11 @@ }, "resources": { "utils.js": [ - "9d5cfc70c10187743807096421975a099f22afc9", + "c562b3028bdecd3cd9cb9afacd658132ca3b1420", [] ], "utils_validation.js": [ - "77a6d79205b5365d9a92af7d1a2d39df144a0f3f", + "3f8687b88f17a00eb29cd28d0cc4a81c75466b7c", [] ] }, @@ -435428,8 +435623,12 @@ "d4cec39ffce0f58b76da653c78dc384f22ffa43d", [] ], - "idlharness.https.window-expected.txt": [ - "655d49107e28d78dc284c4475f384527ea118af3", + "idlharness.https.window_exclude=SFrameTransform._-expected.txt": [ + "5bd2fe419921843598c49bc16ffa70ed01c026bd", + [] + ], + "idlharness.https.window_include=SFrameTransform._-expected.txt": [ + "e0e394e24cf86578fe3cd367a9b4129258e39319", [] ], "routines.js": [ @@ -467210,9 +467409,87 @@ ] ] }, + "rewriter": { + "rewriter-abort.tentative.https.window.js": [ + "eaf33e62b758d37cb8668c031569c0bda6bb37f7", + [ + "ai/rewriter/rewriter-abort.tentative.https.window.html", + { + "script_metadata": [ + [ + "title", + "Rewriter Abort" + ], + [ + "script", + "../resources/util.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ], + "rewriter-from-detached-iframe.tentative.https.window.js": [ + "ecc24c77be7b9e05cd20a1a307432e25d4972d87", + [ + "ai/rewriter/rewriter-from-detached-iframe.tentative.https.window.html", + { + "script_metadata": [ + [ + "title", + "Rewriter Detached Iframe" + ], + [ + "script", + "../resources/util.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ], + "rewriter-iframe.tentative.https.html": [ + "979a39b86973bfd02e96fc81f489f3db4928efdd", + [ + null, + {} + ] + ], + "rewriter.tentative.https.window.js": [ + "86b9a2fbccdd2b0ee4ebb11ff34d4385d7a025ab", + [ + "ai/rewriter/rewriter.tentative.https.window.html", + { + "script_metadata": [ + [ + "title", + "Rewriter" + ], + [ + "script", + "../resources/util.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ] + }, "summarizer": { "summarizer-abort.tentative.https.window.js": [ - "64595ea930c9e21b8044a281c2f9f4d467478772", + "c96c561e6faedc457a8b81d2f2ff7fb2d1546981", [ "ai/summarizer/summarizer-abort.tentative.https.window.html", { @@ -467222,10 +467499,6 @@ "Summarizer Abort" ], [ - "global", - "window,worker" - ], - [ "script", "../resources/util.js" ] @@ -467465,6 +467738,84 @@ } ] ] + }, + "writer": { + "writer-abort.tentative.https.window.js": [ + "f1796d22fb98f10e17b3309367eed3de093a82a5", + [ + "ai/writer/writer-abort.tentative.https.window.html", + { + "script_metadata": [ + [ + "title", + "Writer Abort" + ], + [ + "script", + "../resources/util.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ], + "writer-from-detached-iframe.tentative.https.window.js": [ + "6143bc4276fbe6ea2f9f16270b293174cda496f5", + [ + "ai/writer/writer-from-detached-iframe.tentative.https.window.html", + { + "script_metadata": [ + [ + "title", + "Writer Detached Iframe" + ], + [ + "script", + "../resources/util.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ], + "writer-iframe.tentative.https.html": [ + "10819399324f8204ba0a03f7d255ab51f7b07bb3", + [ + null, + {} + ] + ], + "writer.tentative.https.window.js": [ + "38b1254e3459446e619c6baf9b308d3b4d92f243", + [ + "ai/writer/writer.tentative.https.window.html", + { + "script_metadata": [ + [ + "title", + "Writer Detached Iframe" + ], + [ + "script", + "../resources/util.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ] } }, "ambient-light": { @@ -476712,7 +477063,7 @@ ] ], "async-navigator-clipboard-basics.https.html": [ - "f7aed80b17ebd0af8f4c255ef83dfc85a7eb71ce", + "b71d6665bcba982b9d686f3b1d6115269feb60e3", [ null, { @@ -476738,6 +477089,15 @@ } ] ], + "async-navigator-clipboard-write-domstring.https.html": [ + "a16f358f46d4d555ade6a96eb5f14f73c732e1c5", + [ + null, + { + "testdriver": true + } + ] + ], "async-navigator-clipboard-write-multiple.tentative.https.sub.html": [ "c310203503f3530b881b866b7fc2f8b8ade5b371", [ @@ -496275,6 +496635,20 @@ null, {} ] + ], + "corner-shape-outside-left.html": [ + "b38b7f3f27872e5bf8ad402aa6dabe981a9d5530", + [ + null, + {} + ] + ], + "corner-shape-outside-right.html": [ + "96a297230bb52863ac149c7a8da1ec1e9d20bcac", + [ + null, + {} + ] ] }, "parsing": { @@ -538253,7 +538627,7 @@ ] ], "allow-attribute-with-get.https.html": [ - "15601d891f25c4c2d75dad2260d1b45a26a9344d", + "a13a188c9da1554df1cd38ca07e3fcb87837063f", [ null, { @@ -538334,7 +538708,7 @@ ] ], "non-fully-active.https.html": [ - "3c09b132daf76ec719cadf2fc741d60a2a8d0df2", + "8d8f889f6ac627d584e27e59e001e2b5e7e7d90a", [ null, { @@ -538343,7 +538717,7 @@ ] ], "user-activation.https.html": [ - "facaf7bddbbd419801a9ffa470f4bb5bbc1ab07c", + "1189c32252ae1a1c52fa2d75d11f4ec00b45d57a", [ null, { @@ -645050,7 +645424,7 @@ ] ], "iframe-loading-lazy-nav-navigation-navigate.html": [ - "1010c540b7fd59521278ece38b34f9e572e4e4a6", + "47435f4c48d4e2fb1c5382c27c0325dfc1a7e8bf", [ null, {} @@ -645078,7 +645452,7 @@ ] ], "iframe-loading-lazy-reload-navigation-reload.html": [ - "aefd6c472b5ae888e0786de8e26e8d9ad5111adb", + "6633b710828d8f15e8f7edf0834c6260bd270bb3", [ null, {} @@ -712367,15 +712741,6 @@ } ] ], - "replacestate.tentative.html": [ - "d47b9b653881f57e085fef94360c9245e23c022f", - [ - null, - { - "testdriver": true - } - ] - ], "second-interaction-not-softnav.tentative.html": [ "a9bb337060d00a5e21075f2c2cb53570e500afaf", [ @@ -712388,7 +712753,7 @@ "smoke": { "tentative": { "almost-soft-navigation.html": [ - "bbd09e1625d2a10694e3af94ed6fe4d246be921e", + "aa5732f9fb7e735d72c732a8299f5832db410ce0", [ null, { @@ -712452,15 +712817,6 @@ } ] ], - "soft-navigation-no-url.tentative.html": [ - "a0055c654c2049c9df444510c892489e363d0bb3", - [ - null, - { - "testdriver": true - } - ] - ], "softnav-after-lcp-paint-larger-than-viewport.tentative.html": [ "3c930d8be4cd459d9167404be13ad9ac219ec422", [ @@ -715440,7 +715796,7 @@ ] ], "SpeechRecognition-basics.https.html": [ - "827844096f6e58a7b64f1192958c8a2475a1410f", + "91cf8e6d3e54a64a6cac0cf776fa618b99966cbc", [ null, {} @@ -715581,7 +715937,7 @@ "storage": { "buckets": { "bucket-quota-indexeddb.tentative.https.any.js": [ - "ee9202777e7ec55faee0b89f4c656f7a76c05e83", + "49cd7077b7908e75ee626d307fffbba8310630fe", [ "storage/buckets/bucket-quota-indexeddb.tentative.https.any.html", { @@ -763705,7 +764061,7 @@ ] ], "DOMException-constructor-behavior.any.js": [ - "c4ddabdafd4597aac6f13ad5182b78566045c09a", + "5bb6da77a7d1ca7d68a74538b36e609bb3f0c417", [ "webidl/ecmascript-binding/es-exceptions/DOMException-constructor-behavior.any.html", { @@ -796827,12 +797183,55 @@ ] ], "idlharness.https.window.js": [ - "2c6ef19ca82a56c799b97b5eb9af3edb900a40b5", + "d3eea3bc138cad7676690e274006a5c521ec038d", [ - "webrtc-encoded-transform/idlharness.https.window.html", + "webrtc-encoded-transform/idlharness.https.window.html?exclude=SFrameTransform.*", { "script_metadata": [ [ + "variant", + "?exclude=SFrameTransform.*" + ], + [ + "variant", + "?include=SFrameTransform.*" + ], + [ + "script", + "/common/subset-tests-by-key.js" + ], + [ + "script", + "/resources/WebIDLParser.js" + ], + [ + "script", + "/resources/idlharness.js" + ], + [ + "script", + "./RTCPeerConnection-helper.js" + ] + ] + } + ], + [ + "webrtc-encoded-transform/idlharness.https.window.html?include=SFrameTransform.*", + { + "script_metadata": [ + [ + "variant", + "?exclude=SFrameTransform.*" + ], + [ + "variant", + "?include=SFrameTransform.*" + ], + [ + "script", + "/common/subset-tests-by-key.js" + ], + [ "script", "/resources/WebIDLParser.js" ],
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-visibility-change-ref.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-visibility-change-ref.html index 66bf9083..bc9872a9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-visibility-change-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-visibility-change-ref.html
@@ -17,16 +17,43 @@ background: lime; } -.target { - position: fixed; - background: cyan; - left: 111px; +.target-inner { + width: 30px; + height: 20px; } + +.target { + position: absolute; +} + +#target-1 { + background: cyan; + left: 50px; +} + +#target-2 { + top: 20px; + left: 0; + background: blue; +} + +#target-3 { + top: 20px; + left: 50px; + background: magenta; +} + </style> <div class="container"> <div class="anchor"></div> - <div class="target"> - <div style="width:30px;height:20px;"></div> + <div id="target-1" class="target"> + <div class="target-inner"></div> + </div> + <div id="target-2" class="target"> + <div class="target-inner"></div> + </div> + <div id="target-3" class="target"> + <div class="target-inner"></div> </div> </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-visibility-change.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-visibility-change.html index 0f7d8058..e555943 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-visibility-change.html +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-visibility-change.html
@@ -1,8 +1,9 @@ <!DOCTYPE html> <html class=reftest-wait> -<title>Tests 'anchor-center' value when target visibility changes</title> +<title>Tests 'anchor-center' value when target visibility changes (by changing 'display', 'visibility', or popover trigger)</title> <link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#valdef-justify-self-anchor-center"> <link rel="author" href="mailto:plampe@igalia.com"> +<link rel="author" href="mailto:kiet.ho@apple.com"> <link rel="match" href="anchor-center-visibility-change-ref.html"> <script src="/common/reftest-wait.js"></script> <script src="/common/rendering-utils.js"></script> @@ -27,27 +28,61 @@ .target { position-anchor: --anchor; - position: fixed; - background: cyan; + position: absolute; +} + +.target-inner { + width: 30px; + height: 20px; +} + +#target-1 { justify-self: anchor-center; + background: cyan; display: none; } + +#target-2 { + align-self: anchor-center; + background: blue; + visibility: hidden; +} + +#target-3 { + align-self: anchor-center; + justify-self: anchor-center; + background: magenta; + + /* Override default popover style */ + margin: 0; + padding: 0; + border: none; +} </style> <div class="container"> <div class="anchor"></div> - <div id="target" class="target"> - <div style="width:30px;height:20px;"></div> + <div id="target-1" class="target"> + <div class="target-inner"></div> + </div> + <div id="target-2" class="target"> + <div class="target-inner"></div> + </div> + <div id="target-3" class="target" popover> + <div class="target-inner"></div> </div> </div> <script> - // #target should be invisible initially. + // Targets should be invisible initially. waitForAtLeastOneFrame().then(() => { - // Change #target to be visible. - document.getElementById('target').style.display = 'flow'; + // Change targets to be visible. + document.getElementById('target-1').style.display = 'flow'; + document.getElementById('target-2').style.visibility = 'visible'; + document.getElementById('target-3').showPopover(); + waitForAtLeastOneFrame().then(() => { - // #target should be visible and anchor-centered now. + // Targets should be visible now. takeScreenshot(); }); });
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/position-area-visibility-change.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/position-area-visibility-change.html new file mode 100644 index 0000000..61d8ab5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/position-area-visibility-change.html
@@ -0,0 +1,113 @@ +<!DOCTYPE html> + +<html class="reftest-wait"> + +<head> + <title>Tests that an element positioned using position-area renders when it's initially hidden, then shown</title> + + <link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#position-area"> + <link rel="author" href="mailto:kiet.ho@apple.com"> + <link rel="match" href="reference/position-area-visibility-change-ref.html"> + + <script src="/common/reftest-wait.js"></script> + <script src="/common/rendering-utils.js"></script> + + <style> + .containing-block { + position: relative; + width: 150px; + height: 150px; + outline: 2px black solid; + } + + .cell { + width: 50px; + height: 50px; + } + + #anchor-cell { + position: absolute; + top: 50px; + left: 50px; + + anchor-name: --anchor; + + background: green; + } + + .anchor-positioned-cell { + position: absolute; + position-anchor: --anchor; + } + + #target-1 { + position-area: top right; + + /* Will be changed to 'block' */ + display: none; + } + + #target-2 { + position-area: bottom left; + + /* Will be changed to 'visible' */ + visibility: hidden; + } + + #target-3 { + position-area: bottom right; + + /* Override default popover style */ + margin: 0; + padding: 0; + border: none; + } + + .blue-background { + background: blue; + } + + .magenta-background { + background: magenta; + } + + .cyan-background { + background: cyan; + } + </style> +</head> + +<body> + <div class="containing-block"> + <div class="cell" id="anchor-cell"></div> + + <div class="cell anchor-positioned-cell" id="target-1"> + <div class="cell blue-background"></div> + </div> + + <div class="cell anchor-positioned-cell" id="target-2"> + <div class="cell magenta-background"></div> + </div> + + <div class="cell anchor-positioned-cell" id="target-3" popover> + <div class="cell cyan-background"></div> + </div> + </div> + + <script> + // All targets should initially be hidden. + waitForAtLeastOneFrame().then(() => { + // Change targets to be visible. + document.getElementById('target-1').style.display = 'block'; + document.getElementById('target-2').style.visibility = 'visible'; + document.getElementById('target-3').showPopover(); + + waitForAtLeastOneFrame().then(() => { + // All targets should be visible now. + takeScreenshot(); + }); + }); + </script> +</body> + +</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/reference/position-area-visibility-change-ref.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/reference/position-area-visibility-change-ref.html new file mode 100644 index 0000000..87e1804 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/reference/position-area-visibility-change-ref.html
@@ -0,0 +1,72 @@ +<!DOCTYPE html> + +<style> + .containing-block { + position: relative; + width: 150px; + height: 150px; + outline: 2px black solid; + } + + .cell { + width: 50px; + height: 50px; + } + + #anchor-cell { + position: absolute; + top: 50px; + left: 50px; + + background: green; + } + + .anchor-positioned-cell { + position: absolute; + } + + #target-1 { + top: 0; + right: 0; + } + + #target-2 { + bottom: 0; + left: 0; + } + + #target-3 { + bottom: 0; + right: 0; + } + + .blue-background { + background: blue; + } + + .magenta-background { + background: magenta; + } + + .cyan-background { + background: cyan; + } +</style> + +<body> + <div class="containing-block"> + <div class="cell" id="anchor-cell"></div> + + <div class="cell anchor-positioned-cell" id="target-1"> + <div class="cell blue-background"></div> + </div> + + <div class="cell anchor-positioned-cell" id="target-2"> + <div class="cell magenta-background"></div> + </div> + + <div class="cell anchor-positioned-cell" id="target-3"> + <div class="cell cyan-background"></div> + </div> + </div> +</body> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-initial-target/scroll-initial-target-with-text-fragment-navigation-target.html b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-initial-target/scroll-initial-target-with-text-fragment-navigation-target.html index aea8e120..8b3c168 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-initial-target/scroll-initial-target-with-text-fragment-navigation-target.html +++ b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-initial-target/scroll-initial-target-with-text-fragment-navigation-target.html
@@ -57,11 +57,12 @@ const expected_scroll_top = document.scrollingElement.scrollHeight - document.scrollingElement.clientHeight; - const scroll_start_target_top = top_box.getBoundingClientRect().height; + const scroll_start_target_top = Math.round(top_box.getBoundingClientRect().height); - if (document.scrollingElement.scrollTop == scroll_start_target_top) { + const actual_scroll_top = Math.round(document.scrollingElement.scrollTop); + if (actual_scroll_top == scroll_start_target_top) { scroll_position = "AT_SCROLL_START_TARGET"; - } else if (document.scrollingElement.scrollTop == expected_scroll_top) { + } else if (actual_scroll_top == expected_scroll_top) { scroll_position = "AT_TEXT_FRAGMENT"; }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/css/css-ui/WEB_FEATURES.yml index a10f702..e699a40 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-ui/WEB_FEATURES.yml +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/WEB_FEATURES.yml
@@ -8,3 +8,6 @@ - name: outline files: - outline-* +- name: user-select + files: + - user-select-*
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/parsing/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/css/css-ui/parsing/WEB_FEATURES.yml index b4ae339..3be770b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-ui/parsing/WEB_FEATURES.yml +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/parsing/WEB_FEATURES.yml
@@ -2,3 +2,6 @@ - name: field-sizing files: - field-sizing-* +- name: user-select + files: + - user-select-*
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/negated-last-of-type-invalidation.html b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/negated-last-of-type-invalidation.html new file mode 100644 index 0000000..40bf8a8f0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/negated-last-of-type-invalidation.html
@@ -0,0 +1,32 @@ +<!doctype html> +<meta charset="utf-8"> +<html class="reftest-wait"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1964575"> +<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com"> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-last-of-type-pseudo"> +<style> +#dut { + width: 100px; + height: 100px; + background: red; +} +.foo:not(:last-of-type ~ .bar) > #dut.baz { + background-color: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div> + <span></span> + <div class="foo bar"> + <div id=dut></div> + </div> + <span></span> +</div> +<script> +window.onload = () => { + dut.classList.add("baz"); + document.documentElement.classList.remove('reftest-wait'); +}; +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/digital-credentials/allow-attribute-with-get.https.html b/third_party/blink/web_tests/external/wpt/digital-credentials/allow-attribute-with-get.https.html index 15601d8..a13a188c 100644 --- a/third_party/blink/web_tests/external/wpt/digital-credentials/allow-attribute-with-get.https.html +++ b/third_party/blink/web_tests/external/wpt/digital-credentials/allow-attribute-with-get.https.html
@@ -105,10 +105,11 @@ const options = { digital: { // Results in TypeError when allowed, NotAllowedError when disallowed - requests: [], + requests: [{ data: {}, protocol: "openid4vp" }], }, mediation: "required", }; + await test_driver.bless("User activation"); const { data } = await new Promise((resolve) => { window.addEventListener("message", resolve, { once: true,
diff --git a/third_party/blink/web_tests/external/wpt/digital-credentials/non-fully-active.https.html b/third_party/blink/web_tests/external/wpt/digital-credentials/non-fully-active.https.html index 3c09b13..8d8f889 100644 --- a/third_party/blink/web_tests/external/wpt/digital-credentials/non-fully-active.https.html +++ b/third_party/blink/web_tests/external/wpt/digital-credentials/non-fully-active.https.html
@@ -33,7 +33,7 @@ controller.abort(); // Steal all the needed references. - const navigator = iframe.contentWindow.navigator; + const { credentials } = iframe.contentWindow.navigator; const DOMExceptionCtor = iframe.contentWindow.DOMException; // No longer fully active. @@ -44,7 +44,7 @@ t, "InvalidStateError", DOMExceptionCtor, - navigator.credentials.get({ signal }), + credentials.get({ signal }), "Expected InvalidStateError for get() on non-fully-active document" ); @@ -53,7 +53,7 @@ t, "InvalidStateError", DOMExceptionCtor, - navigator.credentials.create({ signal }), + credentials.create({ signal }), "Expected InvalidStateError for create() on non-fully-active document" ); @@ -62,7 +62,7 @@ t, "InvalidStateError", DOMExceptionCtor, - navigator.credentials.preventSilentAccess(), + credentials.preventSilentAccess(), "Expected InvalidStateError for preventSilentAccess() on non-fully-active document" ); }, "non-fully active document behavior for CredentialsContainer");
diff --git a/third_party/blink/web_tests/external/wpt/digital-credentials/support/iframe.html b/third_party/blink/web_tests/external/wpt/digital-credentials/support/iframe.html index 3ec761e..d737dcf 100644 --- a/third_party/blink/web_tests/external/wpt/digital-credentials/support/iframe.html +++ b/third_party/blink/web_tests/external/wpt/digital-credentials/support/iframe.html
@@ -27,8 +27,8 @@ } data.options.signal = abortController.signal; } - if (data.needsActivation) { - await test_driver.bless("user activation", null, window); + if (data.needsActivation && !navigator.userActivation.isActive) { + await test_driver.bless("user activation"); } let result; try {
diff --git a/third_party/blink/web_tests/external/wpt/digital-credentials/user-activation.https-expected.txt b/third_party/blink/web_tests/external/wpt/digital-credentials/user-activation.https-expected.txt index 5b258016..fed8949 100644 --- a/third_party/blink/web_tests/external/wpt/digital-credentials/user-activation.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/digital-credentials/user-activation.https-expected.txt
@@ -1,6 +1,4 @@ This is a testharness.js-based test. -[FAIL] navigator.credentials.get() calling the API without user activation should reject with NotAllowedError. - promise_rejects_dom: function "function() { throw e; }" threw object "TypeError: Failed to execute 'get' on 'CredentialsContainer': Digital identity API needs at least one well-formed request." that is not a DOMException NotAllowedError: property "code" is equal to undefined, expected 0 [FAIL] navigator.credentials.get() consumes user activation. assert_false: User activation should be consumed after navigator.credentials.get(). expected false got true [FAIL] navigator.credentials.create() calling the API without user activation should reject with NotAllowedError.
diff --git a/third_party/blink/web_tests/external/wpt/digital-credentials/user-activation.https.html b/third_party/blink/web_tests/external/wpt/digital-credentials/user-activation.https.html index facaf7bd..1189c32 100644 --- a/third_party/blink/web_tests/external/wpt/digital-credentials/user-activation.https.html +++ b/third_party/blink/web_tests/external/wpt/digital-credentials/user-activation.https.html
@@ -14,7 +14,7 @@ navigator.userActivation.isActive, "User activation should not be active" ); - const options = makeGetOptions([]); + const options = makeGetOptions("openid4vp"); await promise_rejects_dom( t, "NotAllowedError", @@ -24,12 +24,17 @@ promise_test(async (t) => { await test_driver.bless(); + const abort = new AbortController(); + const options = makeGetOptions("openid4vp"); + options.signal = abort.signal; assert_true( navigator.userActivation.isActive, "User activation should be active after test_driver.bless()." ); - const options = makeGetOptions([]); - await promise_rejects_js(t, TypeError, navigator.credentials.get(options)); + + const getPromise = navigator.credentials.get(options); + abort.abort(); + await promise_rejects_dom(t, "AbortError", getPromise); assert_false( navigator.userActivation.isActive, "User activation should be consumed after navigator.credentials.get()."
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/noopener-helper.js b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/noopener-helper.js index 6dd2c9b..ead0ef3 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/noopener-helper.js +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/resources/noopener-helper.js
@@ -121,8 +121,9 @@ assert_equals(await receive(reply_token), 'Popup loaded'); t.add_cleanup(() => send(popup_token, 'window.close()')); - // Assert that we can script the popup. - assert_not_equals(popup.window, null, 'can script the popup'); + // There's an open question if we should check that popup.window is null here. + // See https://github.com/whatwg/html/issues/10457 + // Assert that we cannot script the popup. assert_false(popup.closed, 'popup closed'); // Ensure that the popup has no access to its opener.
diff --git "a/third_party/blink/web_tests/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt" "b/third_party/blink/web_tests/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt" index a59b20d..e975efd 100644 --- "a/third_party/blink/web_tests/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt" +++ "b/third_party/blink/web_tests/external/wpt/html/dom/idlharness.https_include=\050Document_Window\051-expected.txt"
@@ -1,19 +1,7 @@ This is a testharness.js-based test. -Found 8 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 2 FAIL, 0 TIMEOUT, 0 NOTRUN. [FAIL] Window interface: attribute navigation assert_equals: setter must be undefined for readonly attributes expected (undefined) undefined but got (function) function "function set navigation() { [native code] }" -[FAIL] Window interface: attribute oncopy - assert_own_property: The global object must have a property "oncopy" expected property "oncopy" missing -[FAIL] Window interface: attribute oncut - assert_own_property: The global object must have a property "oncut" expected property "oncut" missing -[FAIL] Window interface: attribute onpaste - assert_own_property: The global object must have a property "onpaste" expected property "onpaste" missing -[FAIL] Window interface: window must inherit property "oncopy" with the proper type - assert_own_property: expected property "oncopy" missing -[FAIL] Window interface: window must inherit property "oncut" with the proper type - assert_own_property: expected property "oncut" missing -[FAIL] Window interface: window must inherit property "onpaste" with the proper type - assert_own_property: expected property "onpaste" missing [FAIL] Document interface: calling parseHTMLUnsafe((TrustedHTML or DOMString)) on iframe.contentDocument with too few arguments must throw TypeError assert_own_property: interface object must have static operation as own property expected property "parseHTMLUnsafe" missing Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-navigation-navigate.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-navigation-navigate.html index 1010c540..47435f4 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-navigation-navigate.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-navigation-navigate.html
@@ -14,8 +14,8 @@ <script src="/resources/testharnessreport.js"></script> <script> setup({single_test: true}); +assert_true("navigation" in window, "Navigation API is supported"); iframeLoaded.then(() => { - assert_true("navigation" in window, "Navigation API is supported"); // Need a timeout to detect failure when there are two navigations. step_timeout(() => { assert_equals(iframe.contentWindow.location.href, new URL("support/blank.htm?nav", location.href).href);
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload-expected.txt index 3ad8c48..8d930e9 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -[FAIL] Reloading iframe loading='lazy' before it is loaded: location.reload +[FAIL] Reloading iframe loading='lazy' before it is loaded: navigation.reload Uncaught Error: assert_equals: expected "http://web-platform.test:8001/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src" but got "about:blank" Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload.html index aefd6c4..6633b710 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>Reloading iframe loading='lazy' before it is loaded: location.reload</title> +<title>Reloading iframe loading='lazy' before it is loaded: navigation.reload</title> <iframe src="support/blank.htm?src" loading="lazy" hidden></iframe> <script> const iframe = document.querySelector('iframe'); @@ -15,10 +15,10 @@ <script src="/resources/testharnessreport.js"></script> <script> setup({single_test: true}); +assert_true("navigation" in window, "Navigation API is supported"); iframeLoaded.then(() => { // Need a timeout to detect failure when there are two navigations. step_timeout(() => { - assert_true("navigation" in window, "Navigation API is supported"); assert_equals(iframe.contentWindow.location.href, new URL("support/blank.htm?src", location.href).href); done(); }, 1000);
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-datalist-element/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-datalist-element/WEB_FEATURES.yml new file mode 100644 index 0000000..c5f2a881 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-datalist-element/WEB_FEATURES.yml
@@ -0,0 +1,3 @@ +features: +- name: datalist + files: "**"
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-meter-element/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-meter-element/WEB_FEATURES.yml new file mode 100644 index 0000000..944746a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-meter-element/WEB_FEATURES.yml
@@ -0,0 +1,3 @@ +features: +- name: meter + files: "**"
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-progress-element/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-progress-element/WEB_FEATURES.yml new file mode 100644 index 0000000..95c7b88 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-progress-element/WEB_FEATURES.yml
@@ -0,0 +1,3 @@ +features: +- name: progress + files: "**"
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/crash-reporting.idl b/third_party/blink/web_tests/external/wpt/interfaces/crash-reporting.idl index a6737ca8..6eaee13 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/crash-reporting.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/crash-reporting.idl
@@ -8,4 +8,6 @@ [Default] object toJSON(); readonly attribute DOMString? reason; readonly attribute DOMString? stack; + readonly attribute DOMString? is_top_level; + readonly attribute DocumentVisibilityState? page_visibility; };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/digital-credentials.idl b/third_party/blink/web_tests/external/wpt/interfaces/digital-credentials.idl index e4ebb3b..60b6397 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/digital-credentials.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/digital-credentials.idl
@@ -1,17 +1,30 @@ // GENERATED CONTENT - DO NOT EDIT // Content was automatically extracted by Reffy into webref // (https://github.com/w3c/webref) -// Source: Digital Credentials (https://wicg.github.io/digital-credentials/) +// Source: Digital Credentials (https://w3c-fedid.github.io/digital-credentials/) partial dictionary CredentialRequestOptions { DigitalCredentialRequestOptions digital; }; dictionary DigitalCredentialRequestOptions { - sequence<DigitalCredentialRequest> requests; + sequence<DigitalCredentialGetRequest> requests; }; -dictionary DigitalCredentialRequest { +dictionary DigitalCredentialGetRequest { + required DOMString protocol; + required object data; +}; + +partial dictionary CredentialCreationOptions { + DigitalCredentialCreationOptions digital; +}; + +dictionary DigitalCredentialCreationOptions { + sequence<DigitalCredentialCreateRequest> requests; +}; + +dictionary DigitalCredentialCreateRequest { required DOMString protocol; required object data; };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl index 0e07b46..94a416f 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/speech-api.idl
@@ -3,7 +3,7 @@ // (https://github.com/w3c/webref) // Source: Web Speech API (https://webaudio.github.io/web-speech-api/) -[Exposed=Window] +[SecureContext, Exposed=Window] interface SpeechRecognition : EventTarget { constructor(); @@ -61,7 +61,7 @@ "available" }; -[Exposed=Window] +[SecureContext, Exposed=Window] interface SpeechRecognitionErrorEvent : Event { constructor(DOMString type, SpeechRecognitionErrorEventInit eventInitDict); readonly attribute SpeechRecognitionErrorCode error; @@ -74,14 +74,14 @@ }; // Item in N-best list -[Exposed=Window] +[SecureContext, Exposed=Window] interface SpeechRecognitionAlternative { readonly attribute DOMString transcript; readonly attribute float confidence; }; // A complete one-shot simple response -[Exposed=Window] +[SecureContext, Exposed=Window] interface SpeechRecognitionResult { readonly attribute unsigned long length; getter SpeechRecognitionAlternative item(unsigned long index); @@ -89,14 +89,14 @@ }; // A collection of responses (used in continuous mode) -[Exposed=Window] +[SecureContext, Exposed=Window] interface SpeechRecognitionResultList { readonly attribute unsigned long length; getter SpeechRecognitionResult item(unsigned long index); }; // A full response, which could be interim or final, part of a continuous response or not -[Exposed=Window] +[SecureContext, Exposed=Window] interface SpeechRecognitionEvent : Event { constructor(DOMString type, SpeechRecognitionEventInit eventInitDict); readonly attribute unsigned long resultIndex; @@ -109,7 +109,7 @@ }; // The object representing a phrase for contextual biasing. -[Exposed=Window] +[SecureContext, Exposed=Window] interface SpeechRecognitionPhrase { constructor(DOMString phrase, optional float boost = 1.0); readonly attribute DOMString phrase; @@ -117,7 +117,7 @@ }; // The object representing a list of phrases for contextual biasing. -[Exposed=Window] +[SecureContext, Exposed=Window] interface SpeechRecognitionPhraseList { constructor(sequence<SpeechRecognitionPhrase> phrases); readonly attribute unsigned long length;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/translation-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/translation-api.idl new file mode 100644 index 0000000..6cbad38 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/interfaces/translation-api.idl
@@ -0,0 +1,85 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into webref +// (https://github.com/w3c/webref) +// Source: Translator and Language Detector APIs (https://webmachinelearning.github.io/translation-api/) + +[Exposed=Window, SecureContext] +interface Translator { + static Promise<Translator> create(TranslatorCreateOptions options); + static Promise<Availability> availability(TranslatorCreateCoreOptions options); + + Promise<DOMString> translate( + DOMString input, + optional TranslatorTranslateOptions options = {} + ); + ReadableStream translateStreaming( + DOMString input, + optional TranslatorTranslateOptions options = {} + ); + + readonly attribute DOMString sourceLanguage; + readonly attribute DOMString targetLanguage; + + Promise<double> measureInputUsage( + DOMString input, + optional TranslatorTranslateOptions options = {} + ); + readonly attribute unrestricted double inputQuota; +}; +Translator includes DestroyableModel; + +dictionary TranslatorCreateCoreOptions { + required DOMString sourceLanguage; + required DOMString targetLanguage; +}; + +dictionary TranslatorCreateOptions : TranslatorCreateCoreOptions { + AbortSignal signal; + CreateMonitorCallback monitor; +}; + +dictionary TranslatorTranslateOptions { + AbortSignal signal; +}; + +[Exposed=Window, SecureContext] +interface LanguageDetector { + static Promise<LanguageDetector> create( + optional LanguageDetectorCreateOptions options = {} + ); + static Promise<Availability> availability( + optional LanguageDetectorCreateCoreOptions options = {} + ); + + Promise<sequence<LanguageDetectionResult>> detect( + DOMString input, + optional LanguageDetectorDetectOptions options = {} + ); + + readonly attribute FrozenArray<DOMString>? expectedInputLanguages; + + Promise<double> measureInputUsage( + DOMString input, + optional LanguageDetectorDetectOptions options = {} + ); + readonly attribute unrestricted double inputQuota; +}; +LanguageDetector includes DestroyableModel; + +dictionary LanguageDetectorCreateCoreOptions { + sequence<DOMString> expectedInputLanguages; +}; + +dictionary LanguageDetectorCreateOptions : LanguageDetectorCreateCoreOptions { + AbortSignal signal; + CreateMonitorCallback monitor; +}; + +dictionary LanguageDetectorDetectOptions { + AbortSignal signal; +}; + +dictionary LanguageDetectionResult { + DOMString detectedLanguage; + double confidence; +};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webnn.idl b/third_party/blink/web_tests/external/wpt/interfaces/webnn.idl index 37fcc32..8d0e485b 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webnn.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webnn.idl
@@ -799,8 +799,7 @@ enum MLPaddingMode { "constant", "edge", - "reflection", - "symmetric" + "reflection" }; dictionary MLPadOptions : MLOperatorOptions {
diff --git a/third_party/blink/web_tests/external/wpt/requestidlecallback/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/requestidlecallback/WEB_FEATURES.yml new file mode 100644 index 0000000..989f1fc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/requestidlecallback/WEB_FEATURES.yml
@@ -0,0 +1,3 @@ +features: +- name: requestidlecallback + files: "**"
diff --git a/third_party/blink/web_tests/external/wpt/resources/idlharness.js b/third_party/blink/web_tests/external/wpt/resources/idlharness.js index d52ba9f..2eb710c1 100644 --- a/third_party/blink/web_tests/external/wpt/resources/idlharness.js +++ b/third_party/blink/web_tests/external/wpt/resources/idlharness.js
@@ -783,6 +783,10 @@ } testedPartials.set(parsed_idl.name, partialTestCount); + if (!self.shouldRunSubTest(partialTestName)) { + return; + } + if (!parsed_idl.untested) { test(function () { assert_true(originalExists, `Original ${parsed_idl.type} should be defined`); @@ -871,6 +875,7 @@ { const lhs = parsed_idl.target; const rhs = parsed_idl.includes; + const testName = lhs + " includes " + rhs + ": member names are unique"; var errStr = lhs + " includes " + rhs + ", but "; if (!(lhs in this.members)) throw errStr + lhs + " is undefined."; @@ -878,7 +883,7 @@ if (!(rhs in this.members)) throw errStr + rhs + " is undefined."; if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface."; - if (this.members[rhs].members.length) { + if (this.members[rhs].members.length && self.shouldRunSubTest(testName)) { test(function () { var clash = this.members[rhs].members.find(function(member) { return this.members[lhs].members.find(function(m) { @@ -892,7 +897,7 @@ this.members[lhs].members.push(new IdlInterfaceMember(member)); }.bind(this)); assert_true(!clash, "member " + (clash && clash.name) + " is unique"); - }.bind(this), lhs + " includes " + rhs + ": member names are unique"); + }.bind(this), testName); } } this.includes = [];
diff --git a/third_party/blink/web_tests/external/wpt/resources/testharness.js b/third_party/blink/web_tests/external/wpt/resources/testharness.js index 6ccede34..32f033a 100644 --- a/third_party/blink/web_tests/external/wpt/resources/testharness.js +++ b/third_party/blink/web_tests/external/wpt/resources/testharness.js
@@ -2321,7 +2321,6 @@ NetworkError: 19, AbortError: 20, URLMismatchError: 21, - QuotaExceededError: 22, TimeoutError: 23, InvalidNodeTypeError: 24, DataCloneError: 25, @@ -2336,7 +2335,8 @@ VersionError: 0, OperationError: 0, NotAllowedError: 0, - OptOutError: 0 + OptOutError: 0, + QuotaExceededError: 0 }; var code_name_map = {};
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/crashtests/scroll-timeline-completion-crash.html b/third_party/blink/web_tests/external/wpt/scroll-animations/crashtests/scroll-timeline-completion-crash.html new file mode 100644 index 0000000..fb7ecd1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/crashtests/scroll-timeline-completion-crash.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<title>This test passes if it does not crash</title> +<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/"> +<script src="/web-animations/testcommon.js"></script> + +<style> + @keyframes grow-progress { + from { background-color: green; } + to { background-color: red; } + } + + #container { + overflow: scroll; + width: 100px; + height: 100px; + animation: grow-progress linear forwards; + animation-timeline: scroll(self); + } + + #content { + width: 200px; + height: 200px; + } +</style> +<body onload="runTest()"> +<div id="container"> + <div id="content"></div> +</div> +<script> + +async function runTest() { + const container = document.getElementById("container"); + container.scrollTo(0, container.scrollHeight - container.clientHeight); + await waitForNextFrame(); + + const elem = document.getElementById("content"); + elem.style.width = "0px"; + elem.style.height = "0px"; + + await waitForNextFrame(); + } +</script>
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechRecognition-basics.https.html b/third_party/blink/web_tests/external/wpt/speech-api/SpeechRecognition-basics.https.html index 8278440..91cf8e6 100644 --- a/third_party/blink/web_tests/external/wpt/speech-api/SpeechRecognition-basics.https.html +++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechRecognition-basics.https.html
@@ -12,6 +12,6 @@ assert_false(reco.interimResults, 'SpeechRecognition.interimResults'); assert_equals(reco.maxAlternatives, 1, 'SpeechRecognition.maxAlternatives'); assert_equals(reco.mode, 'ondevice-preferred', 'SpeechRecognition.mode'); - assert_equals(reco.phrases, null, 'SpeechRecognition.phrases'); + assert_equals(reco.phrases.length, 0, 'SpeechRecognition.phrases.length'); }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechRecognition-recognitionContext-manual.https.html b/third_party/blink/web_tests/external/wpt/speech-api/SpeechRecognition-phrases-manual.https.html similarity index 74% rename from third_party/blink/web_tests/external/wpt/speech-api/SpeechRecognition-recognitionContext-manual.https.html rename to third_party/blink/web_tests/external/wpt/speech-api/SpeechRecognition-phrases-manual.https.html index 1039baa..2d0b19a 100644 --- a/third_party/blink/web_tests/external/wpt/speech-api/SpeechRecognition-recognitionContext-manual.https.html +++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechRecognition-phrases-manual.https.html
@@ -1,6 +1,6 @@ <!DOCTYPE html> <html lang="en"> -<title>SpeechRecognition RecognitionContext</title> +<title>SpeechRecognition Phrases</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> @@ -29,42 +29,41 @@ "Audio track should be a valid MediaStreamTrack" ); - // Create the recognition context. - var list = new SpeechRecognitionPhraseList(); - list.addItem(new SpeechRecognitionPhrase("ASIC", 1.0)); - list.addItem(new SpeechRecognitionPhrase("FPGA", 1.0)); - var context = new SpeechRecognitionContext(list); - - // Create the first speech recognition with a mode that does not support - // recognition context. Note that this may vary between browsers in the future. + // Create the first speech recognition with a mode that does not support contextual biasing. + // Note that this may vary between browsers in the future. window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; const recognition1 = new SpeechRecognition(); recognition1.mode = "cloud-only"; recognition1.lang = "en-US"; - recognition1.context = context; recognition1.onerror = function(event) { assert_equals( event.error, - "recognition-context-not-supported", - "First speech recognition should throw a recognition-context-not-supported error" + "phrases-not-supported", + "First speech recognition should throw a phrases-not-supported error" ); }; - recognition1.start(audioTrack); + recognition1.phrases = new SpeechRecognitionPhraseList([ + new SpeechRecognitionPhrase("test", 1.0) + ]); - // Create the second speech recognition with a mode that supports recognition context. + // Create the second speech recognition with a mode that supports contextual biasing. const recognition2 = new SpeechRecognition(); recognition2.mode = "ondevice-only"; recognition2.lang = "en-US"; - recognition2.context = context; recognition2.onerror = function(event) { // Currently WPT may not be able to detect that SODA is available and // will throw a "language-not-supported" error here. - assert_unreached(); + assert_unreached("Caught an error: " + event.error); }; + recognition2.phrases = new SpeechRecognitionPhraseList([ + new SpeechRecognitionPhrase("ASIC", 1.0), + new SpeechRecognitionPhrase("FPGA", 1.0) + ]); + const recognitionPromise = new Promise((resolve) => { recognition2.onresult = (event) => { const transcript = event.results[0][0].transcript; @@ -80,6 +79,6 @@ "the fpga's latency were both below expectations", "Second speech recognition should correctly recognize the phrases" ); -}, "SpeechRecognition should recognize speech with the given recognition context."); +}, "SpeechRecognition should recognize speech with the given contextual information."); </script> </html>
diff --git a/third_party/blink/web_tests/external/wpt/storage/buckets/bucket-quota-indexeddb.tentative.https.any.js b/third_party/blink/web_tests/external/wpt/storage/buckets/bucket-quota-indexeddb.tentative.https.any.js index ee920277..49cd707 100644 --- a/third_party/blink/web_tests/external/wpt/storage/buckets/bucket-quota-indexeddb.tentative.https.any.js +++ b/third_party/blink/web_tests/external/wpt/storage/buckets/bucket-quota-indexeddb.tentative.https.any.js
@@ -34,8 +34,11 @@ type: 'binary/random' }), 2); - await promise_rejects_dom( - t, 'QuotaExceededError', transactionPromise(txn)); + try { + await transactionPromise(txn); + } catch (e) { + assert_equals(e.name, 'QuotaExceededError'); + } db.close(); }, 'IDB respects bucket quota');
diff --git a/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-constructor-behavior.any.js b/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-constructor-behavior.any.js index c4ddabd..5bb6da7 100644 --- a/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-constructor-behavior.any.js +++ b/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/es-exceptions/DOMException-constructor-behavior.any.js
@@ -107,7 +107,6 @@ {name: "NetworkError", code: 19}, {name: "AbortError", code: 20}, {name: "URLMismatchError", code: 21}, - {name: "QuotaExceededError", code: 22}, {name: "TimeoutError", code: 23}, {name: "InvalidNodeTypeError", code: 24}, {name: "DataCloneError", code: 25}, @@ -128,7 +127,9 @@ {name: "ReadOnlyError", code: 0}, {name: "VersionError", code: 0}, {name: "OperationError", code: 0}, - {name: "NotAllowedError", code: 0} + {name: "NotAllowedError", code: 0}, + // See https://github.com/whatwg/webidl/pull/1465. + {name: "QuotaExceededError", code: 0} ].forEach(function(test_case) { test(function() { var ex = new DOMException("msg", test_case.name);
diff --git a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/qdq_subgraph.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/qdq_subgraph.https.any.js index 80a53ed..9369fce 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/qdq_subgraph.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/qdq_subgraph.https.any.js
@@ -1471,6 +1471,132 @@ } } }, + { + 'name': 'quantized split', + 'graph': { + 'inputs': { + 'input': { + 'data': [ + 1.6811466217041016, 0.0479511022567749, 0.33355462551116943, + -0.1988269537687301, -0.0041167140007019, -0.0634240251779556, + ], + 'descriptor': {shape: [2, 3], dataType: 'float32'}, + 'constant': false + }, + 'inputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'inputZeroPoint': { + 'data': [16], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'outputScale': { + 'data': [0.003921568859368563], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'outputZeroPoint': { + 'data': [16], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + }, + 'operators': [ + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'input'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'quantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedInput'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'dequantizedInput' + }, + { + 'name': 'split', + 'arguments': [{'input': 'dequantizedInput'}, {'splits': 3}, {'options': {'axis': 1}}], + 'outputs': ['splitOutput 1', 'splitOutput 2', 'splitOutput 3'], + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'splitOutput 1'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedSplitOutput 1' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedSplitOutput 1'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output 1' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'splitOutput 2'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedSplitOutput 2' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedSplitOutput 2'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output 2' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'splitOutput 3'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedSplitOutput 3' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedSplitOutput 3'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output 3' + } + ], + 'expectedOutputs': { + 'output 1': { + 'data': [ + 0.43529415130615234, -0.20000001788139343, + ], + 'descriptor': {shape: [2, 1], dataType: 'float32'} + }, + 'output 2': { + 'data': [ + 0.0470588281750679, -0.003921568859368563, + ], + 'descriptor': {shape: [2, 1], dataType: 'float32'} + }, + 'output 3': { + 'data': [ + 0.3333333432674408, -0.062745101749897, + ], + 'descriptor': {shape: [2, 1], dataType: 'float32'} + } + } + } + }, ]; if (navigator.ml) {
diff --git a/third_party/blink/web_tests/external/wpt/webnn/resources/utils.js b/third_party/blink/web_tests/external/wpt/webnn/resources/utils.js index 9d5cfc7..c562b30 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/resources/utils.js +++ b/third_party/blink/web_tests/external/wpt/webnn/resources/utils.js
@@ -143,8 +143,8 @@ const assertDescriptorsEquals = (outputOperand, expected) => { const dataType = expected.castedType ? expected.castedType : expected.dataType; - assert_true( - outputOperand.dataType === dataType, + assert_equals( + outputOperand.dataType, dataType, 'actual output dataType should be equal to expected output dataType'); assert_array_equals( outputOperand.shape, expected.shape, @@ -282,7 +282,7 @@ * @param {Array} actual - Array of test values. * @param {Array} expected - Array of values expected to be close to the values * in ``actual``. - * @param {Number} nulp - A BigInt value indicates acceptable ULP distance. + * @param {(Number|BigInt)} nulp - A value indicates acceptable ULP distance. * @param {String} dataType - A data type string, value: "float32", * more types, please see: * https://www.w3.org/TR/webnn/#enumdef-mloperanddatatype @@ -292,33 +292,25 @@ /* * Test if two primitive arrays are equal within acceptable ULP distance */ - assert( - typeof nulp === 'number', `unexpected type for nulp: ${typeof nulp}`); - assert_true( - actual.length === expected.length, - `assert_array_approx_equals_ulp: ${description} lengths differ, ` + - `expected ${expected.length} but got ${actual.length}`); - let distance; + assert_equals( + actual.length, expected.length, + `assert_array_approx_equals_ulp: ${description} lengths differ`); for (let i = 0; i < actual.length; i++) { if (actual[i] === expected[i]) { continue; } else { - distance = ulpDistance(actual[i], expected[i], dataType); + let distance = ulpDistance(actual[i], expected[i], dataType); - // if true, invoke assert_true() in failure case - // if false, it's expected, not invoke assert_true() in success case to - // prevent spammy output - if (distance > nulp) { - assert_true( - false, + // TODO: See if callers can be updated to pass matching type. + nulp = typeof distance === 'bigint' ? BigInt(nulp) : Number(nulp); + + assert_less_than_equal(distance, nulp, `assert_array_approx_equals_ulp: ${description} actual ` + `${ dataType === 'float16' ? float16AsUint16ToNumber(actual[i]) : actual[i]} should be close enough to expected ` + - `${expected[i]} by the acceptable ${nulp} ULP distance, ` + - `but they have ${distance} ULP distance`); - } + `${expected[i]} by ULP distance:`); } } };
diff --git a/third_party/blink/web_tests/external/wpt/webnn/resources/utils_validation.js b/third_party/blink/web_tests/external/wpt/webnn/resources/utils_validation.js index 77a6d79..3f8687b 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/resources/utils_validation.js +++ b/third_party/blink/web_tests/external/wpt/webnn/resources/utils_validation.js
@@ -205,7 +205,7 @@ function assert_throws_with_label(func, regrexp) { try { func.call(this); - assert_true(false, 'Graph builder method unexpectedly succeeded'); + assert_unreached('Graph builder method unexpectedly succeeded'); } catch (e) { assert_equals(e.name, 'TypeError'); const error_message = e.message;
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window.js b/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window.js index 2c6ef19ca..d3eea3bc 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window.js +++ b/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window.js
@@ -1,3 +1,6 @@ +// META: variant=?exclude=SFrameTransform.* +// META: variant=?include=SFrameTransform.* +// META: script=/common/subset-tests-by-key.js // META: script=/resources/WebIDLParser.js // META: script=/resources/idlharness.js // META: script=./RTCPeerConnection-helper.js
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window_exclude=SFrameTransform._-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window_exclude=SFrameTransform._-expected.txt new file mode 100644 index 0000000..5bd2fe4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window_exclude=SFrameTransform._-expected.txt
@@ -0,0 +1,9 @@ +This is a testharness.js-based test. +[FAIL] RTCRtpSender interface: operation generateKeyFrame(optional sequence<DOMString>) + assert_own_property: interface prototype object missing non-static operation expected property "generateKeyFrame" missing +[FAIL] RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "generateKeyFrame(optional sequence<DOMString>)" with the proper type + assert_inherits: property "generateKeyFrame" not found in prototype chain +[FAIL] RTCRtpSender interface: calling generateKeyFrame(optional sequence<DOMString>) on new RTCPeerConnection().addTransceiver('audio').sender with too few arguments must throw TypeError + assert_inherits: property "generateKeyFrame" not found in prototype chain +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window_include=SFrameTransform._-expected.txt similarity index 82% rename from third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window-expected.txt rename to third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window_include=SFrameTransform._-expected.txt index 655d491..e0e394e2 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/idlharness.https.window_include=SFrameTransform._-expected.txt
@@ -1,5 +1,4 @@ This is a testharness.js-based test. -Found 20 FAIL, 0 TIMEOUT, 0 NOTRUN. [FAIL] SFrameTransform interface: existence and properties of interface object assert_own_property: self does not have own property "SFrameTransform" expected property "SFrameTransform" missing [FAIL] SFrameTransform interface object length @@ -34,11 +33,5 @@ assert_own_property: self does not have own property "SFrameTransformErrorEvent" expected property "SFrameTransformErrorEvent" missing [FAIL] SFrameTransformErrorEvent interface: attribute frame assert_own_property: self does not have own property "SFrameTransformErrorEvent" expected property "SFrameTransformErrorEvent" missing -[FAIL] RTCRtpSender interface: operation generateKeyFrame(optional sequence<DOMString>) - assert_own_property: interface prototype object missing non-static operation expected property "generateKeyFrame" missing -[FAIL] RTCRtpSender interface: new RTCPeerConnection().addTransceiver('audio').sender must inherit property "generateKeyFrame(optional sequence<DOMString>)" with the proper type - assert_inherits: property "generateKeyFrame" not found in prototype chain -[FAIL] RTCRtpSender interface: calling generateKeyFrame(optional sequence<DOMString>) on new RTCPeerConnection().addTransceiver('audio').sender with too few arguments must throw TypeError - assert_inherits: property "generateKeyFrame" not found in prototype chain Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/fast/dom/DOMException/constructor.html b/third_party/blink/web_tests/fast/dom/DOMException/constructor.html index 19c6501..2f4986a7 100644 --- a/third_party/blink/web_tests/fast/dom/DOMException/constructor.html +++ b/third_party/blink/web_tests/fast/dom/DOMException/constructor.html
@@ -75,7 +75,6 @@ {name: "NetworkError", code: 19}, {name: "AbortError", code: 20}, {name: "URLMismatchError", code: 21}, - {name: "QuotaExceededError", code: 22}, {name: "TimeoutError", code: 23}, {name: "InvalidNodeTypeError", code: 24}, {name: "DataCloneError", code: 25}
diff --git a/third_party/blink/web_tests/flag-specific/enable-skia-graphite/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload-expected.txt b/third_party/blink/web_tests/flag-specific/enable-skia-graphite/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload-expected.txt new file mode 100644 index 0000000..3ad8c48 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-skia-graphite/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-navigation-reload-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] Reloading iframe loading='lazy' before it is loaded: location.reload + Uncaught Error: assert_equals: expected "http://web-platform.test:8001/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src" but got "about:blank" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/flag-specific/enable-skia-graphite/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reciprocal.https.any_cpu-expected.txt b/third_party/blink/web_tests/flag-specific/enable-skia-graphite/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reciprocal.https.any_cpu-expected.txt new file mode 100644 index 0000000..6df8957 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-skia-graphite/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reciprocal.https.any_cpu-expected.txt
@@ -0,0 +1,13 @@ +This is a testharness.js-based test. +[FAIL] reciprocal float16 1D tensor + assert_less_than_equal: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by ULP distance: expected a number less than or equal to 2n but got 3n +[FAIL] reciprocal float16 2D tensor + assert_less_than_equal: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by ULP distance: expected a number less than or equal to 2n but got 3n +[FAIL] reciprocal float16 3D tensor + assert_less_than_equal: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by ULP distance: expected a number less than or equal to 2n but got 3n +[FAIL] reciprocal float16 4D tensor + assert_less_than_equal: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by ULP distance: expected a number less than or equal to 2n but got 3n +[FAIL] reciprocal float16 5D tensor + assert_less_than_equal: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by ULP distance: expected a number less than or equal to 2n but got 3n +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/flag-specific/enable-skia-graphite/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/neg.https.any_npu-expected.txt b/third_party/blink/web_tests/flag-specific/enable-skia-graphite/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/neg.https.any_npu-expected.txt new file mode 100644 index 0000000..cca069b2 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/enable-skia-graphite/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/neg.https.any_npu-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +[FAIL] neg int8 4D tensor + promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'input' data type int8 must be one of [float32,float16,int32]." +[FAIL] neg int32 4D tensor + assert_less_than_equal: assert_array_approx_equals_ulp: test neg int32 actual -2147483648 should be close enough to expected -2147483646 by ULP distance: expected a number less than or equal to 0n but got 2n +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 994d24d2..88a1538 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1668,6 +1668,11 @@ getter applicationServerKey getter userVisibleOnly method constructor +interface QuotaExceededError : DOMException + attribute @@toStringTag + getter quota + getter requested + method constructor interface RTCRtpAcks attribute @@toStringTag getter explicitCongestionNotification
diff --git a/third_party/blink/web_tests/http/tests/shadowrealm/webexposed/global-interface-listing-shadow-realm-expected.txt b/third_party/blink/web_tests/http/tests/shadowrealm/webexposed/global-interface-listing-shadow-realm-expected.txt index 9a2a85e2..16cddb1 100644 --- a/third_party/blink/web_tests/http/tests/shadowrealm/webexposed/global-interface-listing-shadow-realm-expected.txt +++ b/third_party/blink/web_tests/http/tests/shadowrealm/webexposed/global-interface-listing-shadow-realm-expected.txt
@@ -163,6 +163,11 @@ CONSOLE MESSAGE: getter promise CONSOLE MESSAGE: getter reason CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface QuotaExceededError : DOMException +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter quota +CONSOLE MESSAGE: getter requested +CONSOLE MESSAGE: method constructor CONSOLE MESSAGE: interface ReadableByteStreamController CONSOLE MESSAGE: attribute @@toStringTag CONSOLE MESSAGE: getter byobRequest
diff --git a/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-audio-worklet-expected.txt b/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-audio-worklet-expected.txt index d5b6acb..85fc3a0 100644 --- a/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-audio-worklet-expected.txt +++ b/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-audio-worklet-expected.txt
@@ -95,6 +95,11 @@ CONSOLE MESSAGE: setter onclose CONSOLE MESSAGE: setter onmessage CONSOLE MESSAGE: setter onmessageerror +CONSOLE MESSAGE: interface QuotaExceededError : DOMException +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter quota +CONSOLE MESSAGE: getter requested +CONSOLE MESSAGE: method constructor CONSOLE MESSAGE: interface ReadableByteStreamController CONSOLE MESSAGE: attribute @@toStringTag CONSOLE MESSAGE: getter byobRequest
diff --git a/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-layout-worklet-expected.txt b/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-layout-worklet-expected.txt index e8af938..f4db7a8 100644 --- a/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-layout-worklet-expected.txt +++ b/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-layout-worklet-expected.txt
@@ -282,6 +282,11 @@ CONSOLE MESSAGE: interface LayoutWorkletGlobalScope : WorkletGlobalScope CONSOLE MESSAGE: attribute @@toStringTag CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface QuotaExceededError : DOMException +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter quota +CONSOLE MESSAGE: getter requested +CONSOLE MESSAGE: method constructor CONSOLE MESSAGE: interface ReadableByteStreamController CONSOLE MESSAGE: attribute @@toStringTag CONSOLE MESSAGE: getter byobRequest @@ -695,6 +700,11 @@ CONSOLE MESSAGE: interface LayoutWorkletGlobalScope : WorkletGlobalScope CONSOLE MESSAGE: attribute @@toStringTag CONSOLE MESSAGE: method constructor +CONSOLE MESSAGE: interface QuotaExceededError : DOMException +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter quota +CONSOLE MESSAGE: getter requested +CONSOLE MESSAGE: method constructor CONSOLE MESSAGE: interface ReadableByteStreamController CONSOLE MESSAGE: attribute @@toStringTag CONSOLE MESSAGE: getter byobRequest
diff --git a/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt b/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt index 0b18e9ec..b68dc268 100644 --- a/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt +++ b/third_party/blink/web_tests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
@@ -353,6 +353,11 @@ CONSOLE MESSAGE: method quadraticCurveTo CONSOLE MESSAGE: method rect CONSOLE MESSAGE: method roundRect +CONSOLE MESSAGE: interface QuotaExceededError : DOMException +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter quota +CONSOLE MESSAGE: getter requested +CONSOLE MESSAGE: method constructor CONSOLE MESSAGE: interface ReadableByteStreamController CONSOLE MESSAGE: attribute @@toStringTag CONSOLE MESSAGE: getter byobRequest @@ -838,6 +843,11 @@ CONSOLE MESSAGE: method quadraticCurveTo CONSOLE MESSAGE: method rect CONSOLE MESSAGE: method roundRect +CONSOLE MESSAGE: interface QuotaExceededError : DOMException +CONSOLE MESSAGE: attribute @@toStringTag +CONSOLE MESSAGE: getter quota +CONSOLE MESSAGE: getter requested +CONSOLE MESSAGE: method constructor CONSOLE MESSAGE: interface ReadableByteStreamController CONSOLE MESSAGE: attribute @@toStringTag CONSOLE MESSAGE: getter byobRequest
diff --git a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reciprocal.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reciprocal.https.any_cpu-expected.txt index 7e2f6a7..221eeec 100644 --- a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reciprocal.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reciprocal.https.any_cpu-expected.txt
@@ -1,13 +1,13 @@ This is a testharness.js-based test. [FAIL] reciprocal float16 1D tensor - assert_true: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by the acceptable 2 ULP distance, but they have 3 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by ULP distance: expected a number less than or equal to 2 but got 3 [FAIL] reciprocal float16 2D tensor - assert_true: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by the acceptable 2 ULP distance, but they have 3 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by ULP distance: expected a number less than or equal to 2 but got 3 [FAIL] reciprocal float16 3D tensor - assert_true: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by the acceptable 2 ULP distance, but they have 3 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by ULP distance: expected a number less than or equal to 2 but got 3 [FAIL] reciprocal float16 4D tensor - assert_true: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by the acceptable 2 ULP distance, but they have 3 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by ULP distance: expected a number less than or equal to 2 but got 3 [FAIL] reciprocal float16 5D tensor - assert_true: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by the acceptable 2 ULP distance, but they have 3 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reciprocal float16 actual 0.216796875 should be close enough to expected 0.2164306640625 by ULP distance: expected a number less than or equal to 2 but got 3 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_npu-expected.txt index 3e7bfde..1dc322e 100644 --- a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_npu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] convTranspose2d same output size different padding (padding=2, outputPadding=2)) - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 1 should be close enough to expected 2 by the acceptable 18 ULP distance, but they have 8388608 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 1 should be close enough to expected 2 by ULP distance: expected a number less than or equal to 18n but got 8388608n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/neg.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/neg.https.any_npu-expected.txt index 2b8e54db..02ae569c 100644 --- a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/neg.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/neg.https.any_npu-expected.txt
@@ -2,6 +2,6 @@ [FAIL] neg int8 4D tensor promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'input' data type int8 must be one of [float32,float16,int32]." [FAIL] neg int32 4D tensor - assert_true: assert_array_approx_equals_ulp: test neg int32 actual -2147483648 should be close enough to expected -2147483646 by the acceptable 0 ULP distance, but they have 2 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test neg int32 actual -2147483648 should be close enough to expected -2147483646 by ULP distance: expected a number less than or equal to 0 but got 2 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_gpu-expected.txt index 3e7bfde..1dc322e 100644 --- a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_gpu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] convTranspose2d same output size different padding (padding=2, outputPadding=2)) - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 1 should be close enough to expected 2 by the acceptable 18 ULP distance, but they have 8388608 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 1 should be close enough to expected 2 by ULP distance: expected a number less than or equal to 18n but got 8388608n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/neg.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/neg.https.any_gpu-expected.txt index 2b8e54db..cca069b2 100644 --- a/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/neg.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac14-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/neg.https.any_gpu-expected.txt
@@ -2,6 +2,6 @@ [FAIL] neg int8 4D tensor promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'input' data type int8 must be one of [float32,float16,int32]." [FAIL] neg int32 4D tensor - assert_true: assert_array_approx_equals_ulp: test neg int32 actual -2147483648 should be close enough to expected -2147483646 by the acceptable 0 ULP distance, but they have 2 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test neg int32 actual -2147483648 should be close enough to expected -2147483646 by ULP distance: expected a number less than or equal to 0n but got 2n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/abs.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/abs.https.any_cpu-expected.txt index cb5fabb..364ab1b 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/abs.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/abs.https.any_cpu-expected.txt
@@ -2,6 +2,6 @@ [FAIL] abs int8 4D tensor promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'input' data type int8 must be one of [float32,float16,int32]." [FAIL] abs int32 4D tensor - assert_true: assert_array_approx_equals_ulp: test abs int32 actual 2147483647 should be close enough to expected 2147483646 by the acceptable 0 ULP distance, but they have 1 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test abs int32 actual 2147483647 should be close enough to expected 2147483646 by ULP distance: expected a number less than or equal to 0 but got 1 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt index a753779..28d4d598 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt
@@ -4,6 +4,6 @@ [FAIL] gather float32 1D tensor and int64 0D scalar indices default options promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, constant 'indices' data type int64 must be one of [float32,float16,int32,uint32,int8,uint8,int4,uint4]." [FAIL] gather float32 2D tensor and int32 0D out-of-bound positive indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual -66.05901336669922 should be close enough to expected 90.2870101928711 by the acceptable 0 ULP distance, but they have 2235085098 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual -66.05901336669922 should be close enough to expected 90.2870101928711 by ULP distance: expected a number less than or equal to 0n but got 2235085098n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherElements.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherElements.https.any_cpu-expected.txt index 1a387fc..c3c893f 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherElements.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherElements.https.any_cpu-expected.txt
@@ -2,8 +2,8 @@ [FAIL] gatherElements float32 2D input and uint32 indices options.axis=1 promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'indices' data type uint32 must be one of [int32]." [FAIL] gatherElements float32 3D input and int32 negative indices - assert_true: assert_array_approx_equals_ulp: test gatherElements float32 actual -66.05901336669922 should be close enough to expected 89.0337142944336 by the acceptable 0 ULP distance, but they have 2234920826 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherElements float32 actual -66.05901336669922 should be close enough to expected 89.0337142944336 by ULP distance: expected a number less than or equal to 0n but got 2234920826n [FAIL] gatherElements float32 1D input and int32 out-of-bounds indices - assert_true: assert_array_approx_equals_ulp: test gatherElements float32 actual -26.158037185668945 should be close enough to expected 51.79948425292969 by the acceptable 0 ULP distance, but they have 2216719957 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherElements float32 actual -26.158037185668945 should be close enough to expected 51.79948425292969 by ULP distance: expected a number less than or equal to 0n but got 2216719957n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt index 43ba1600..95341fc 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt
@@ -4,10 +4,10 @@ [FAIL] gatherND float32 4D input and 1D int64 indices promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, constant 'indices' data type int64 must be one of [float32,float16,int32,uint32,int8,uint8,int4,uint4]." [FAIL] gatherND float32 2D input and 2D negative indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 44.92119598388672 by the acceptable 0 ULP distance, but they have 2226638213 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 44.92119598388672 by ULP distance: expected a number less than or equal to 0n but got 2226638213n [FAIL] gatherND float32 1D input and 2D out-of-bounds indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by the acceptable 0 ULP distance, but they have 2229759677 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by ULP distance: expected a number less than or equal to 0n but got 2229759677n [FAIL] gatherND float32 2D input and 2D out-of-bounds indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by the acceptable 0 ULP distance, but they have 2229759677 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by ULP distance: expected a number less than or equal to 0n but got 2229759677n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt index 4f2fe75..0857e24 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] lstm float32 tensors steps=2 with all options - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by the acceptable 3 ULP distance, but they have 27754759 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by ULP distance: expected a number less than or equal to 3n but got 27754759n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_cpu-expected.txt index bc3cdc4..0a0f2072 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_cpu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] reduceL1 float32 1D constant tensor empty axes - assert_true: assert_array_approx_equals_ulp: test reduceL1 float32 actual -5.50882625579834 should be close enough to expected 5.50882625579834 by the acceptable 1 ULP distance, but they have 2170589340 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reduceL1 float32 actual -5.50882625579834 should be close enough to expected 5.50882625579834 by ULP distance: expected a number less than or equal to 1n but got 2170589340n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_cpu-expected.txt index e4f6147..f308670 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_cpu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] reduceL2 float32 1D constant tensor empty axes - assert_true: assert_array_approx_equals_ulp: test reduceL2 float32 actual -4.860228061676025 should be close enough to expected 4.860228061676025 by the acceptable 3 ULP distance, but they have 2167868922 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reduceL2 float32 actual -4.860228061676025 should be close enough to expected 4.860228061676025 by ULP distance: expected a number less than or equal to 3n but got 2167868922n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/abs.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/abs.https.any_npu-expected.txt index cb5fabb..364ab1b 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/abs.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/abs.https.any_npu-expected.txt
@@ -2,6 +2,6 @@ [FAIL] abs int8 4D tensor promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'input' data type int8 must be one of [float32,float16,int32]." [FAIL] abs int32 4D tensor - assert_true: assert_array_approx_equals_ulp: test abs int32 actual 2147483647 should be close enough to expected 2147483646 by the acceptable 0 ULP distance, but they have 1 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test abs int32 actual 2147483647 should be close enough to expected 2147483646 by ULP distance: expected a number less than or equal to 0 but got 1 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt index a753779..28d4d598 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt
@@ -4,6 +4,6 @@ [FAIL] gather float32 1D tensor and int64 0D scalar indices default options promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, constant 'indices' data type int64 must be one of [float32,float16,int32,uint32,int8,uint8,int4,uint4]." [FAIL] gather float32 2D tensor and int32 0D out-of-bound positive indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual -66.05901336669922 should be close enough to expected 90.2870101928711 by the acceptable 0 ULP distance, but they have 2235085098 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual -66.05901336669922 should be close enough to expected 90.2870101928711 by ULP distance: expected a number less than or equal to 0n but got 2235085098n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherElements.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherElements.https.any_npu-expected.txt index 1a387fc..c3c893f 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherElements.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherElements.https.any_npu-expected.txt
@@ -2,8 +2,8 @@ [FAIL] gatherElements float32 2D input and uint32 indices options.axis=1 promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'indices' data type uint32 must be one of [int32]." [FAIL] gatherElements float32 3D input and int32 negative indices - assert_true: assert_array_approx_equals_ulp: test gatherElements float32 actual -66.05901336669922 should be close enough to expected 89.0337142944336 by the acceptable 0 ULP distance, but they have 2234920826 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherElements float32 actual -66.05901336669922 should be close enough to expected 89.0337142944336 by ULP distance: expected a number less than or equal to 0n but got 2234920826n [FAIL] gatherElements float32 1D input and int32 out-of-bounds indices - assert_true: assert_array_approx_equals_ulp: test gatherElements float32 actual -26.158037185668945 should be close enough to expected 51.79948425292969 by the acceptable 0 ULP distance, but they have 2216719957 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherElements float32 actual -26.158037185668945 should be close enough to expected 51.79948425292969 by ULP distance: expected a number less than or equal to 0n but got 2216719957n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt index 43ba1600..95341fc 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt
@@ -4,10 +4,10 @@ [FAIL] gatherND float32 4D input and 1D int64 indices promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, constant 'indices' data type int64 must be one of [float32,float16,int32,uint32,int8,uint8,int4,uint4]." [FAIL] gatherND float32 2D input and 2D negative indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 44.92119598388672 by the acceptable 0 ULP distance, but they have 2226638213 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 44.92119598388672 by ULP distance: expected a number less than or equal to 0n but got 2226638213n [FAIL] gatherND float32 1D input and 2D out-of-bounds indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by the acceptable 0 ULP distance, but they have 2229759677 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by ULP distance: expected a number less than or equal to 0n but got 2229759677n [FAIL] gatherND float32 2D input and 2D out-of-bounds indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by the acceptable 0 ULP distance, but they have 2229759677 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by ULP distance: expected a number less than or equal to 0n but got 2229759677n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/lstm.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/lstm.https.any_npu-expected.txt index 4f2fe75..0857e24 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/lstm.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/lstm.https.any_npu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] lstm float32 tensors steps=2 with all options - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by the acceptable 3 ULP distance, but they have 27754759 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by ULP distance: expected a number less than or equal to 3n but got 27754759n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_npu-expected.txt index bc3cdc4..0a0f2072 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_npu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] reduceL1 float32 1D constant tensor empty axes - assert_true: assert_array_approx_equals_ulp: test reduceL1 float32 actual -5.50882625579834 should be close enough to expected 5.50882625579834 by the acceptable 1 ULP distance, but they have 2170589340 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reduceL1 float32 actual -5.50882625579834 should be close enough to expected 5.50882625579834 by ULP distance: expected a number less than or equal to 1n but got 2170589340n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_npu-expected.txt index e4f6147..f308670 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_npu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] reduceL2 float32 1D constant tensor empty axes - assert_true: assert_array_approx_equals_ulp: test reduceL2 float32 actual -4.860228061676025 should be close enough to expected 4.860228061676025 by the acceptable 3 ULP distance, but they have 2167868922 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reduceL2 float32 actual -4.860228061676025 should be close enough to expected 4.860228061676025 by ULP distance: expected a number less than or equal to 3n but got 2167868922n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/abs.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/abs.https.any_gpu-expected.txt index cb5fabb..364ab1b 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/abs.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/abs.https.any_gpu-expected.txt
@@ -2,6 +2,6 @@ [FAIL] abs int8 4D tensor promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'input' data type int8 must be one of [float32,float16,int32]." [FAIL] abs int32 4D tensor - assert_true: assert_array_approx_equals_ulp: test abs int32 actual 2147483647 should be close enough to expected 2147483646 by the acceptable 0 ULP distance, but they have 1 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test abs int32 actual 2147483647 should be close enough to expected 2147483646 by ULP distance: expected a number less than or equal to 0 but got 1 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt index a753779..28d4d598 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt
@@ -4,6 +4,6 @@ [FAIL] gather float32 1D tensor and int64 0D scalar indices default options promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, constant 'indices' data type int64 must be one of [float32,float16,int32,uint32,int8,uint8,int4,uint4]." [FAIL] gather float32 2D tensor and int32 0D out-of-bound positive indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual -66.05901336669922 should be close enough to expected 90.2870101928711 by the acceptable 0 ULP distance, but they have 2235085098 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual -66.05901336669922 should be close enough to expected 90.2870101928711 by ULP distance: expected a number less than or equal to 0n but got 2235085098n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherElements.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherElements.https.any_gpu-expected.txt index 1a387fc..c3c893f 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherElements.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherElements.https.any_gpu-expected.txt
@@ -2,8 +2,8 @@ [FAIL] gatherElements float32 2D input and uint32 indices options.axis=1 promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'indices' data type uint32 must be one of [int32]." [FAIL] gatherElements float32 3D input and int32 negative indices - assert_true: assert_array_approx_equals_ulp: test gatherElements float32 actual -66.05901336669922 should be close enough to expected 89.0337142944336 by the acceptable 0 ULP distance, but they have 2234920826 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherElements float32 actual -66.05901336669922 should be close enough to expected 89.0337142944336 by ULP distance: expected a number less than or equal to 0n but got 2234920826n [FAIL] gatherElements float32 1D input and int32 out-of-bounds indices - assert_true: assert_array_approx_equals_ulp: test gatherElements float32 actual -26.158037185668945 should be close enough to expected 51.79948425292969 by the acceptable 0 ULP distance, but they have 2216719957 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherElements float32 actual -26.158037185668945 should be close enough to expected 51.79948425292969 by ULP distance: expected a number less than or equal to 0n but got 2216719957n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt index 43ba1600..95341fc 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt
@@ -4,10 +4,10 @@ [FAIL] gatherND float32 4D input and 1D int64 indices promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, constant 'indices' data type int64 must be one of [float32,float16,int32,uint32,int8,uint8,int4,uint4]." [FAIL] gatherND float32 2D input and 2D negative indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 44.92119598388672 by the acceptable 0 ULP distance, but they have 2226638213 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 44.92119598388672 by ULP distance: expected a number less than or equal to 0n but got 2226638213n [FAIL] gatherND float32 1D input and 2D out-of-bounds indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by the acceptable 0 ULP distance, but they have 2229759677 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by ULP distance: expected a number less than or equal to 0n but got 2229759677n [FAIL] gatherND float32 2D input and 2D out-of-bounds indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by the acceptable 0 ULP distance, but they have 2229759677 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual -66.05901336669922 should be close enough to expected 56.828636169433594 by ULP distance: expected a number less than or equal to 0n but got 2229759677n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/lstm.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/lstm.https.any_gpu-expected.txt index 4f2fe75..0857e24 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/lstm.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/lstm.https.any_gpu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] lstm float32 tensors steps=2 with all options - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by the acceptable 3 ULP distance, but they have 27754759 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by ULP distance: expected a number less than or equal to 3n but got 27754759n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_gpu-expected.txt index bc3cdc4..0a0f2072 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/reduce_l1.https.any_gpu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] reduceL1 float32 1D constant tensor empty axes - assert_true: assert_array_approx_equals_ulp: test reduceL1 float32 actual -5.50882625579834 should be close enough to expected 5.50882625579834 by the acceptable 1 ULP distance, but they have 2170589340 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reduceL1 float32 actual -5.50882625579834 should be close enough to expected 5.50882625579834 by ULP distance: expected a number less than or equal to 1n but got 2170589340n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_gpu-expected.txt index e4f6147..f308670 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/reduce_l2.https.any_gpu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] reduceL2 float32 1D constant tensor empty axes - assert_true: assert_array_approx_equals_ulp: test reduceL2 float32 actual -4.860228061676025 should be close enough to expected 4.860228061676025 by the acceptable 3 ULP distance, but they have 2167868922 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test reduceL2 float32 actual -4.860228061676025 should be close enough to expected 4.860228061676025 by ULP distance: expected a number less than or equal to 3n but got 2167868922n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/README.md b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/README.md index e78086e..b3e8af05 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/README.md +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/README.md
@@ -1,6 +1,6 @@ Currently on the mac x86 macmini bots(mac_rel, mac*-blink-rel), some of the tests have floating point precision issue and are failing with error message like: ``` -actual 47.25 should be close enough to expected 47.26926803588867 by the acceptable 27 ULP distance, but they have 5051 ULP distance expected true got false +actual 47.25 should be close enough to expected 47.26926803588867 by ULP distance: expected a number less than or equal to 27n but got 5051n ``` -This is not reproducible on intel macbooks. It's suspected to be an intel driver bug or a coreml bug on the particular hardware. Since it's only lossing some precision on a particular macmini configuration, we decide to leave the behavior as is. See more detail in crbug.com/331631226. \ No newline at end of file +This is not reproducible on intel macbooks. It's suspected to be an intel driver bug or a coreml bug on the particular hardware. Since it's only lossing some precision on a particular macmini configuration, we decide to leave the behavior as is. See more detail in crbug.com/331631226.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_gpu-expected.txt index 73e3a66..9c1a7c9d 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_gpu-expected.txt
@@ -4,15 +4,15 @@ [FAIL] convTranspose2d float32 4D input and filter tensors options.groups=2 options.strides=[2, 2] promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': convTranspose2d doesn't support dilations and groups." [FAIL] convTranspose2d float32 4D input and filter tensors options.padding - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 0.2787136137485504 by the acceptable 8 ULP distance, but they have 1049539469 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 0.2787136137485504 by ULP distance: expected a number less than or equal to 8n but got 1049539469n [FAIL] convTranspose2d float32 4D input and filter tensors options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': convTranspose2d doesn't support dilations and groups." [FAIL] convTranspose2d same output size different padding (padding=1, outputPadding=0)) - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by the acceptable 18 ULP distance, but they have 1065353216 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by ULP distance: expected a number less than or equal to 18n but got 1065353216n [FAIL] convTranspose2d same output size different padding (padding=2, outputPadding=2)) - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by the acceptable 18 ULP distance, but they have 1065353216 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by ULP distance: expected a number less than or equal to 18n but got 1065353216n [FAIL] convTranspose2d float16 4D input and filter tensors options.padding - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float16 actual 0 should be close enough to expected 0.27880859375 by the acceptable 8 ULP distance, but they have 13430 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float16 actual 0 should be close enough to expected 0.27880859375 by ULP distance: expected a number less than or equal to 8 but got 13430 [FAIL] convTranspose2d float16 4D input and filter tensors options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': convTranspose2d doesn't support dilations and groups." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt index f90e7b98..cc19ef40 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt
@@ -1,9 +1,9 @@ This is a testharness.js-based test. [FAIL] gather float32 2D tensor and int32 0D negative indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by the acceptable 0 ULP distance, but they have 1115954743 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n [FAIL] gather float32 2D tensor and int32 0D out-of-bound positive indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected 90.2870101928711 by the acceptable 0 ULP distance, but they have 1119130355 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected 90.2870101928711 by ULP distance: expected a number less than or equal to 0n but got 1119130355n [FAIL] gather float32 2D tensor and int32 0D out-of-bound negative indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by the acceptable 0 ULP distance, but they have 1115954743 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt index 7b6da10..0a12d07e 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gatherND.https.any_gpu-expected.txt
@@ -1,6 +1,6 @@ This is a testharness.js-based test. [FAIL] gatherND float32 4D input and 1D minimum indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual 0 should be close enough to expected -66.05901336669922 by the acceptable 0 ULP distance, but they have 1115954743 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n [FAIL] gatherND float32 2D input and 2D negative indices promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension." [FAIL] gatherND float32 1D input and 2D out-of-bounds indices
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gru.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gru.https.any_gpu-expected.txt index cb2b3a1..70254f1 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gru.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gru.https.any_gpu-expected.txt
@@ -1,9 +1,9 @@ This is a testharness.js-based test. [FAIL] gru float32 tensors steps=2 with options.bias, options.recurrentBias, options.direction='backward', options.activations=['relu', 'relu'] and options.returnSequence=true - assert_true: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by the acceptable 6 ULP distance, but they have 16778 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by ULP distance: expected a number less than or equal to 6n but got 16778n [FAIL] gru float32 tensors steps=2 with options.bias, options.recurrentBias, options.direction='both' and options.returnSequence=true - assert_true: assert_array_approx_equals_ulp: test gru float32 actual -0.375 should be close enough to expected -0.28068751096725464 by the acceptable 6 ULP distance, but they have 3164602 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gru float32 actual -0.375 should be close enough to expected -0.28068751096725464 by ULP distance: expected a number less than or equal to 6n but got 3164602n [FAIL] gru float32 tensors steps=2 with all options - assert_true: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by the acceptable 6 ULP distance, but they have 16778 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by ULP distance: expected a number less than or equal to 6n but got 16778n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/lstm.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/lstm.https.any_gpu-expected.txt index e53dd3b2..1cd8dc3 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/lstm.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/lstm.https.any_gpu-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. [FAIL] lstm float32 tensors steps=2 with all options - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by the acceptable 3 ULP distance, but they have 27754759 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by ULP distance: expected a number less than or equal to 3n but got 27754759n [FAIL] lstm float32 tensors steps=2 with bidirections - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 0.3696063756942749 should be close enough to expected 0.5764073133468628 by the acceptable 3 ULP distance, but they have 5657186 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 0.3696063756942749 should be close enough to expected 0.5764073133468628 by ULP distance: expected a number less than or equal to 3n but got 5657186n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/pooling.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/pooling.https.any_gpu-expected.txt index 727d407..7d6c7d69 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/pooling.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/pooling.https.any_gpu-expected.txt
@@ -1,24 +1,24 @@ This is a testharness.js-based test. [FAIL] averagePool2d float32 4D tensor options.padding - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 41.9493293762207 should be close enough to expected 52.43666076660156 by the acceptable 27 ULP distance, but they have 2749191 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 41.9493293762207 should be close enough to expected 52.43666076660156 by ULP distance: expected a number less than or equal to 27n but got 2749191n [FAIL] averagePool2d float32 4D tensor options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Pool2d in tflite doesn't support dilations." [FAIL] averagePool2d float32 4D tensor options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.roundingType=ceil and no padding - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 50.63130569458008 should be close enough to expected 40.29140853881836 by the acceptable 11 ULP distance, but they have 2710542 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 50.63130569458008 should be close enough to expected 40.29140853881836 by ULP distance: expected a number less than or equal to 11n but got 2710542n [FAIL] averagePool2d float32 4D tensor options.layout=nhwc and options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.layout=nhwc and options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.outputSizes ignores options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.outputSizes ignores options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.dilations with options.strides - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 28.626827239990234 should be close enough to expected 42.940242767333984 by the acceptable 11 ULP distance, but they have 4636433 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 28.626827239990234 should be close enough to expected 42.940242767333984 by ULP distance: expected a number less than or equal to 11n but got 4636433n [FAIL] l2Pool2d float32 4D constant tensor all positive default options promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'input' data type float32 must be one of []." [FAIL] l2Pool2d float32 4D tensor default all positive options @@ -50,8 +50,8 @@ [FAIL] maxPool2d float32 4D tensor options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Pool2d in tflite doesn't support dilations." [FAIL] maxPool2d float32 4D tensor options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by the acceptable 0 ULP distance, but they have 2229449938 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by ULP distance: expected a number less than or equal to 0n but got 2229449938n [FAIL] maxPool2d float32 4D tensor options.outputSizes ignores options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by the acceptable 0 ULP distance, but they have 2229449938 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by ULP distance: expected a number less than or equal to 0n but got 2229449938n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt index 5269be09..13cf7ab 100644 --- a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] batchNormalization float16 4D NHWC tensor all options - assert_true: assert_array_approx_equals_ulp: test batchNormalization float16 actual 199.5 should be close enough to expected 200.375 by the acceptable 6 ULP distance, but they have 7 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test batchNormalization float16 actual 199.5 should be close enough to expected 200.375 by ULP distance: expected a number less than or equal to 6 but got 7 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/cast.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/cast.https.any_gpu-expected.txt index af82d3ea..7a8f382 100644 --- a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/cast.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/cast.https.any_gpu-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. [FAIL] cast float16 4D tensor to int64 - assert_true: assert_array_approx_equals_ulp: test cast int64 actual 137438953475 should be close enough to expected 3 by the acceptable 0 ULP distance, but they have 137438953472 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test cast int64 actual 137438953475 should be close enough to expected 3 by ULP distance: expected a number less than or equal to 0n but got 137438953472n [FAIL] cast int64 4D tensor to float16 - assert_true: assert_array_approx_equals_ulp: test cast float16 actual 0 should be close enough to expected 1 by the acceptable 1 ULP distance, but they have 15360 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test cast float16 actual 0 should be close enough to expected 1 by ULP distance: expected a number less than or equal to 1 but got 15360 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/clamp.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/clamp.https.any_gpu-expected.txt index 2a3d0f7..aaddfe5 100644 --- a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/clamp.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/clamp.https.any_gpu-expected.txt
@@ -1,11 +1,11 @@ This is a testharness.js-based test. [FAIL] clamp int32 1D tensor - assert_true: assert_array_approx_equals_ulp: test clamp int32 actual 2147483647 should be close enough to expected 2147483645 by the acceptable 0 ULP distance, but they have 2 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test clamp int32 actual 2147483647 should be close enough to expected 2147483645 by ULP distance: expected a number less than or equal to 0 but got 2 [FAIL] clamp uint32 1D tensor - assert_true: assert_array_approx_equals_ulp: test clamp uint32 actual 4294967295 should be close enough to expected 4294967290 by the acceptable 0 ULP distance, but they have 5 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test clamp uint32 actual 4294967295 should be close enough to expected 4294967290 by ULP distance: expected a number less than or equal to 0 but got 5 [FAIL] clamp int64 1D tensor - assert_true: assert_array_approx_equals_ulp: test clamp int64 actual -4147483648 should be close enough to expected -2 by the acceptable 0 ULP distance, but they have 4147483646 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test clamp int64 actual -4147483648 should be close enough to expected -2 by ULP distance: expected a number less than or equal to 0n but got 4147483646n [FAIL] clamp uint64 1D tensor - assert_true: assert_array_approx_equals_ulp: test clamp uint64 actual 5294967295 should be close enough to expected 5294967290 by the acceptable 0 ULP distance, but they have 5 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test clamp uint64 actual 5294967295 should be close enough to expected 5294967290 by ULP distance: expected a number less than or equal to 0n but got 5n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv2d.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv2d.https.any_gpu-expected.txt index 9693870..8fd2230 100644 --- a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv2d.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/conv2d.https.any_gpu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] depthwise conv2d float32 4D input and filter tensors options.groups= input_channels - assert_true: assert_array_approx_equals_ulp: test conv2d float32 actual 0 should be close enough to expected 1.165167212486267 by the acceptable 8 ULP distance, but they have 1066738739 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test conv2d float32 actual 0 should be close enough to expected 1.165167212486267 by ULP distance: expected a number less than or equal to 8n but got 1066738739n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt index fd965e6..ec70e249 100644 --- a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/gather.https.any_gpu-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. [FAIL] gather float32 2D tensor and int32 0D out-of-bound positive indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 73.60064697265625 should be close enough to expected 90.2870101928711 by the acceptable 0 ULP distance, but they have 2187115 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 73.60064697265625 should be close enough to expected 90.2870101928711 by ULP distance: expected a number less than or equal to 0n but got 2187115n [FAIL] gather float32 2D tensor and int32 0D out-of-bound negative indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 73.60064697265625 should be close enough to expected -66.05901336669922 by the acceptable 0 ULP distance, but they have 2232897983 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 73.60064697265625 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 2232897983n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt index 759937bc..9374093 100644 --- a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt
@@ -1,9 +1,9 @@ This is a testharness.js-based test. [FAIL] layerNormalization float32 0D tensor default options - assert_true: assert_array_approx_equals_ulp: test layerNormalization float32 actual NaN should be close enough to expected 0 by the acceptable 14 ULP distance, but they have 2143289344 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test layerNormalization float32 actual NaN should be close enough to expected 0 by ULP distance: expected a number less than or equal to 14n but got 2143289344n [FAIL] layerNormalization float32 2D tensor axes=[] and options.bias - assert_true: assert_array_approx_equals_ulp: test layerNormalization float32 actual NaN should be close enough to expected 7.862982749938965 by the acceptable 14 ULP distance, but they have 1053057650 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test layerNormalization float32 actual NaN should be close enough to expected 7.862982749938965 by ULP distance: expected a number less than or equal to 14n but got 1053057650n [FAIL] layerNormalization float32 2D tensor axes=[] - assert_true: assert_array_approx_equals_ulp: test layerNormalization float32 actual NaN should be close enough to expected 0 by the acceptable 14 ULP distance, but they have 2143289344 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test layerNormalization float32 actual NaN should be close enough to expected 0 by ULP distance: expected a number less than or equal to 14n but got 2143289344n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/neg.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/neg.https.any_gpu-expected.txt index 93084ba..11e58aa 100644 --- a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/neg.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/neg.https.any_gpu-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. [FAIL] neg int32 4D tensor - assert_true: assert_array_approx_equals_ulp: test neg int32 actual -2147483648 should be close enough to expected -2147483646 by the acceptable 0 ULP distance, but they have 2 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test neg int32 actual -2147483648 should be close enough to expected -2147483646 by ULP distance: expected a number less than or equal to 0 but got 2 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/pooling.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/pooling.https.any_gpu-expected.txt index 6004f7b..4a090ab1 100644 --- a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/pooling.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/pooling.https.any_gpu-expected.txt
@@ -2,6 +2,6 @@ [FAIL] averagePool2d float32 4D tensor options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': DirectML: Dilations are not supported for average pooling operator." [FAIL] l2Pool2d float32 4D tensor options.dilations - assert_true: assert_array_approx_equals_ulp: test l2Pool2d float32 actual 194.45481872558594 should be close enough to expected 189.47933959960938 by the acceptable 11 ULP distance, but they have 326073 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test l2Pool2d float32 actual 194.45481872558594 should be close enough to expected 189.47933959960938 by ULP distance: expected a number less than or equal to 11n but got 326073n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt index 11c2c3b..f81fb80 100644 --- a/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/win11-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. [FAIL] lstm float32 tensors steps=2 with all options - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by the acceptable 3 ULP distance, but they have 27754759 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by ULP distance: expected a number less than or equal to 3n but got 27754759n [FAIL] lstm float32 tensors steps=2 with bidirections - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 0.3696063458919525 should be close enough to expected 0.5764073133468628 by the acceptable 3 ULP distance, but they have 5657187 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 0.3696063458919525 should be close enough to expected 0.5764073133468628 by ULP distance: expected a number less than or equal to 3n but got 5657187n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/resources/testharness.js b/third_party/blink/web_tests/resources/testharness.js index 8ef0574..cf380bc 100644 --- a/third_party/blink/web_tests/resources/testharness.js +++ b/third_party/blink/web_tests/resources/testharness.js
@@ -2279,7 +2279,6 @@ NetworkError: 19, AbortError: 20, URLMismatchError: 21, - QuotaExceededError: 22, TimeoutError: 23, InvalidNodeTypeError: 24, DataCloneError: 25, @@ -2294,7 +2293,8 @@ VersionError: 0, OperationError: 0, NotAllowedError: 0, - OptOutError: 0 + OptOutError: 0, + QuotaExceededError: 0 }; var code_name_map = {};
diff --git a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 8882c47..791460a0 100644 --- a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -172,6 +172,11 @@ getter highWaterMark getter size method constructor +interface CreateMonitor : EventTarget + attribute @@toStringTag + getter ondownloadprogress + method constructor + setter ondownloadprogress interface CropTarget attribute @@toStringTag method constructor
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/feature-policy-features-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/feature-policy-features-expected.txt index 0c495711..157be07 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/feature-policy-features-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/feature-policy-features-expected.txt
@@ -48,6 +48,7 @@ interest-cohort join-ad-interest-group keyboard-map +language-detector local-fonts magnetometer microphone @@ -60,15 +61,19 @@ private-state-token-redemption publickey-credentials-create publickey-credentials-get +rewriter run-ad-auction screen-wake-lock serial shared-storage shared-storage-select-url storage-access +summarizer sync-xhr +translator unload usb window-management +writer xr-spatial-tracking
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt index e1084b90..8f5c13d 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -172,6 +172,11 @@ [Worker] getter highWaterMark [Worker] getter size [Worker] method constructor +[Worker] interface CreateMonitor : EventTarget +[Worker] attribute @@toStringTag +[Worker] getter ondownloadprogress +[Worker] method constructor +[Worker] setter ondownloadprogress [Worker] interface CropTarget [Worker] attribute @@toStringTag [Worker] method constructor
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index e9cccf5..89f5441 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -1292,6 +1292,11 @@ getter highWaterMark getter size method constructor +interface CreateMonitor : EventTarget + attribute @@toStringTag + getter ondownloadprogress + method constructor + setter ondownloadprogress interface Credential attribute @@toStringTag getter id @@ -5309,6 +5314,16 @@ setter composite setter pseudoElement setter target +interface LanguageDetector + static method availability + static method create + attribute @@toStringTag + getter expectedInputLanguages + getter inputQuota + method constructor + method destroy + method detect + method measureInputUsage interface LargestContentfulPaint : PerformanceEntry attribute @@toStringTag getter element
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt index 4d1b520..e2724240 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -133,6 +133,11 @@ [Worker] getter highWaterMark [Worker] getter size [Worker] method constructor +[Worker] interface CreateMonitor : EventTarget +[Worker] attribute @@toStringTag +[Worker] getter ondownloadprogress +[Worker] method constructor +[Worker] setter ondownloadprogress [Worker] interface CropTarget [Worker] attribute @@toStringTag [Worker] method constructor
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_cpu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_cpu-expected.txt index 73e3a66..9c1a7c9d 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_cpu-expected.txt
@@ -4,15 +4,15 @@ [FAIL] convTranspose2d float32 4D input and filter tensors options.groups=2 options.strides=[2, 2] promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': convTranspose2d doesn't support dilations and groups." [FAIL] convTranspose2d float32 4D input and filter tensors options.padding - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 0.2787136137485504 by the acceptable 8 ULP distance, but they have 1049539469 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 0.2787136137485504 by ULP distance: expected a number less than or equal to 8n but got 1049539469n [FAIL] convTranspose2d float32 4D input and filter tensors options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': convTranspose2d doesn't support dilations and groups." [FAIL] convTranspose2d same output size different padding (padding=1, outputPadding=0)) - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by the acceptable 18 ULP distance, but they have 1065353216 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by ULP distance: expected a number less than or equal to 18n but got 1065353216n [FAIL] convTranspose2d same output size different padding (padding=2, outputPadding=2)) - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by the acceptable 18 ULP distance, but they have 1065353216 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by ULP distance: expected a number less than or equal to 18n but got 1065353216n [FAIL] convTranspose2d float16 4D input and filter tensors options.padding - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float16 actual 0 should be close enough to expected 0.27880859375 by the acceptable 8 ULP distance, but they have 13430 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float16 actual 0 should be close enough to expected 0.27880859375 by ULP distance: expected a number less than or equal to 8 but got 13430 [FAIL] convTranspose2d float16 4D input and filter tensors options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': convTranspose2d doesn't support dilations and groups." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt index f90e7b98..cc19ef40 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gather.https.any_cpu-expected.txt
@@ -1,9 +1,9 @@ This is a testharness.js-based test. [FAIL] gather float32 2D tensor and int32 0D negative indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by the acceptable 0 ULP distance, but they have 1115954743 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n [FAIL] gather float32 2D tensor and int32 0D out-of-bound positive indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected 90.2870101928711 by the acceptable 0 ULP distance, but they have 1119130355 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected 90.2870101928711 by ULP distance: expected a number less than or equal to 0n but got 1119130355n [FAIL] gather float32 2D tensor and int32 0D out-of-bound negative indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by the acceptable 0 ULP distance, but they have 1115954743 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt index 7b6da10..0a12d07e 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gatherND.https.any_cpu-expected.txt
@@ -1,6 +1,6 @@ This is a testharness.js-based test. [FAIL] gatherND float32 4D input and 1D minimum indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual 0 should be close enough to expected -66.05901336669922 by the acceptable 0 ULP distance, but they have 1115954743 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n [FAIL] gatherND float32 2D input and 2D negative indices promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension." [FAIL] gatherND float32 1D input and 2D out-of-bounds indices
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gru.https.any_cpu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gru.https.any_cpu-expected.txt index cb2b3a1..70254f1 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gru.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/gru.https.any_cpu-expected.txt
@@ -1,9 +1,9 @@ This is a testharness.js-based test. [FAIL] gru float32 tensors steps=2 with options.bias, options.recurrentBias, options.direction='backward', options.activations=['relu', 'relu'] and options.returnSequence=true - assert_true: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by the acceptable 6 ULP distance, but they have 16778 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by ULP distance: expected a number less than or equal to 6n but got 16778n [FAIL] gru float32 tensors steps=2 with options.bias, options.recurrentBias, options.direction='both' and options.returnSequence=true - assert_true: assert_array_approx_equals_ulp: test gru float32 actual -0.375 should be close enough to expected -0.28068751096725464 by the acceptable 6 ULP distance, but they have 3164602 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gru float32 actual -0.375 should be close enough to expected -0.28068751096725464 by ULP distance: expected a number less than or equal to 6n but got 3164602n [FAIL] gru float32 tensors steps=2 with all options - assert_true: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by the acceptable 6 ULP distance, but they have 16778 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by ULP distance: expected a number less than or equal to 6n but got 16778n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt index e53dd3b2..1cd8dc3 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/lstm.https.any_cpu-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. [FAIL] lstm float32 tensors steps=2 with all options - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by the acceptable 3 ULP distance, but they have 27754759 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by ULP distance: expected a number less than or equal to 3n but got 27754759n [FAIL] lstm float32 tensors steps=2 with bidirections - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 0.3696063756942749 should be close enough to expected 0.5764073133468628 by the acceptable 3 ULP distance, but they have 5657186 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 0.3696063756942749 should be close enough to expected 0.5764073133468628 by ULP distance: expected a number less than or equal to 3n but got 5657186n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/pooling.https.any_cpu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/pooling.https.any_cpu-expected.txt index 727d407..7d6c7d69 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/pooling.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/pooling.https.any_cpu-expected.txt
@@ -1,24 +1,24 @@ This is a testharness.js-based test. [FAIL] averagePool2d float32 4D tensor options.padding - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 41.9493293762207 should be close enough to expected 52.43666076660156 by the acceptable 27 ULP distance, but they have 2749191 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 41.9493293762207 should be close enough to expected 52.43666076660156 by ULP distance: expected a number less than or equal to 27n but got 2749191n [FAIL] averagePool2d float32 4D tensor options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Pool2d in tflite doesn't support dilations." [FAIL] averagePool2d float32 4D tensor options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.roundingType=ceil and no padding - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 50.63130569458008 should be close enough to expected 40.29140853881836 by the acceptable 11 ULP distance, but they have 2710542 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 50.63130569458008 should be close enough to expected 40.29140853881836 by ULP distance: expected a number less than or equal to 11n but got 2710542n [FAIL] averagePool2d float32 4D tensor options.layout=nhwc and options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.layout=nhwc and options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.outputSizes ignores options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.outputSizes ignores options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.dilations with options.strides - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 28.626827239990234 should be close enough to expected 42.940242767333984 by the acceptable 11 ULP distance, but they have 4636433 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 28.626827239990234 should be close enough to expected 42.940242767333984 by ULP distance: expected a number less than or equal to 11n but got 4636433n [FAIL] l2Pool2d float32 4D constant tensor all positive default options promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'input' data type float32 must be one of []." [FAIL] l2Pool2d float32 4D tensor default all positive options @@ -50,8 +50,8 @@ [FAIL] maxPool2d float32 4D tensor options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Pool2d in tflite doesn't support dilations." [FAIL] maxPool2d float32 4D tensor options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by the acceptable 0 ULP distance, but they have 2229449938 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by ULP distance: expected a number less than or equal to 0n but got 2229449938n [FAIL] maxPool2d float32 4D tensor options.outputSizes ignores options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by the acceptable 0 ULP distance, but they have 2229449938 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by ULP distance: expected a number less than or equal to 0n but got 2229449938n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_npu-expected.txt index 73e3a66..9c1a7c9d 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/conv_transpose2d.https.any_npu-expected.txt
@@ -4,15 +4,15 @@ [FAIL] convTranspose2d float32 4D input and filter tensors options.groups=2 options.strides=[2, 2] promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': convTranspose2d doesn't support dilations and groups." [FAIL] convTranspose2d float32 4D input and filter tensors options.padding - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 0.2787136137485504 by the acceptable 8 ULP distance, but they have 1049539469 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 0.2787136137485504 by ULP distance: expected a number less than or equal to 8n but got 1049539469n [FAIL] convTranspose2d float32 4D input and filter tensors options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': convTranspose2d doesn't support dilations and groups." [FAIL] convTranspose2d same output size different padding (padding=1, outputPadding=0)) - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by the acceptable 18 ULP distance, but they have 1065353216 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by ULP distance: expected a number less than or equal to 18n but got 1065353216n [FAIL] convTranspose2d same output size different padding (padding=2, outputPadding=2)) - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by the acceptable 18 ULP distance, but they have 1065353216 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float32 actual 0 should be close enough to expected 1 by ULP distance: expected a number less than or equal to 18n but got 1065353216n [FAIL] convTranspose2d float16 4D input and filter tensors options.padding - assert_true: assert_array_approx_equals_ulp: test convTranspose2d float16 actual 0 should be close enough to expected 0.27880859375 by the acceptable 8 ULP distance, but they have 13430 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test convTranspose2d float16 actual 0 should be close enough to expected 0.27880859375 by ULP distance: expected a number less than or equal to 8 but got 13430 [FAIL] convTranspose2d float16 4D input and filter tensors options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': convTranspose2d doesn't support dilations and groups." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt index f90e7b98..cc19ef40 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gather.https.any_npu-expected.txt
@@ -1,9 +1,9 @@ This is a testharness.js-based test. [FAIL] gather float32 2D tensor and int32 0D negative indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by the acceptable 0 ULP distance, but they have 1115954743 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n [FAIL] gather float32 2D tensor and int32 0D out-of-bound positive indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected 90.2870101928711 by the acceptable 0 ULP distance, but they have 1119130355 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected 90.2870101928711 by ULP distance: expected a number less than or equal to 0n but got 1119130355n [FAIL] gather float32 2D tensor and int32 0D out-of-bound negative indices default options - assert_true: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by the acceptable 0 ULP distance, but they have 1115954743 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gather float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt index 7b6da10..0a12d07e 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gatherND.https.any_npu-expected.txt
@@ -1,6 +1,6 @@ This is a testharness.js-based test. [FAIL] gatherND float32 4D input and 1D minimum indices - assert_true: assert_array_approx_equals_ulp: test gatherND float32 actual 0 should be close enough to expected -66.05901336669922 by the acceptable 0 ULP distance, but they have 1115954743 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gatherND float32 actual 0 should be close enough to expected -66.05901336669922 by ULP distance: expected a number less than or equal to 0n but got 1115954743n [FAIL] gatherND float32 2D input and 2D negative indices promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': TFLite doesn't support to gather input into one dimension." [FAIL] gatherND float32 1D input and 2D out-of-bounds indices
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gru.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gru.https.any_npu-expected.txt index cb2b3a1..70254f1 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gru.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/gru.https.any_npu-expected.txt
@@ -1,9 +1,9 @@ This is a testharness.js-based test. [FAIL] gru float32 tensors steps=2 with options.bias, options.recurrentBias, options.direction='backward', options.activations=['relu', 'relu'] and options.returnSequence=true - assert_true: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by the acceptable 6 ULP distance, but they have 16778 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by ULP distance: expected a number less than or equal to 6n but got 16778n [FAIL] gru float32 tensors steps=2 with options.bias, options.recurrentBias, options.direction='both' and options.returnSequence=true - assert_true: assert_array_approx_equals_ulp: test gru float32 actual -0.375 should be close enough to expected -0.28068751096725464 by the acceptable 6 ULP distance, but they have 3164602 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gru float32 actual -0.375 should be close enough to expected -0.28068751096725464 by ULP distance: expected a number less than or equal to 6n but got 3164602n [FAIL] gru float32 tensors steps=2 with all options - assert_true: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by the acceptable 6 ULP distance, but they have 16778 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test gru float32 actual -0.25 should be close enough to expected -0.24974998831748962 by ULP distance: expected a number less than or equal to 6n but got 16778n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/lstm.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/lstm.https.any_npu-expected.txt index e53dd3b2..1cd8dc3 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/lstm.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/lstm.https.any_npu-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. [FAIL] lstm float32 tensors steps=2 with all options - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by the acceptable 3 ULP distance, but they have 27754759 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 1 should be close enough to expected 10.469000816345215 by ULP distance: expected a number less than or equal to 3n but got 27754759n [FAIL] lstm float32 tensors steps=2 with bidirections - assert_true: assert_array_approx_equals_ulp: test lstm float32 actual 0.3696063756942749 should be close enough to expected 0.5764073133468628 by the acceptable 3 ULP distance, but they have 5657186 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test lstm float32 actual 0.3696063756942749 should be close enough to expected 0.5764073133468628 by ULP distance: expected a number less than or equal to 3n but got 5657186n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/pooling.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/pooling.https.any_npu-expected.txt index 727d407..7d6c7d69 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/pooling.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/pooling.https.any_npu-expected.txt
@@ -1,24 +1,24 @@ This is a testharness.js-based test. [FAIL] averagePool2d float32 4D tensor options.padding - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 41.9493293762207 should be close enough to expected 52.43666076660156 by the acceptable 27 ULP distance, but they have 2749191 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 41.9493293762207 should be close enough to expected 52.43666076660156 by ULP distance: expected a number less than or equal to 27n but got 2749191n [FAIL] averagePool2d float32 4D tensor options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Pool2d in tflite doesn't support dilations." [FAIL] averagePool2d float32 4D tensor options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.roundingType=ceil and no padding - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 50.63130569458008 should be close enough to expected 40.29140853881836 by the acceptable 11 ULP distance, but they have 2710542 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 50.63130569458008 should be close enough to expected 40.29140853881836 by ULP distance: expected a number less than or equal to 11n but got 2710542n [FAIL] averagePool2d float32 4D tensor options.layout=nhwc and options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.layout=nhwc and options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.outputSizes ignores options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.outputSizes ignores options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by the acceptable 11 ULP distance, but they have 4736288 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 36.13502502441406 should be close enough to expected 54.20252990722656 by ULP distance: expected a number less than or equal to 11n but got 4736288n [FAIL] averagePool2d float32 4D tensor options.dilations with options.strides - assert_true: assert_array_approx_equals_ulp: test averagePool2d float32 actual 28.626827239990234 should be close enough to expected 42.940242767333984 by the acceptable 11 ULP distance, but they have 4636433 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test averagePool2d float32 actual 28.626827239990234 should be close enough to expected 42.940242767333984 by ULP distance: expected a number less than or equal to 11n but got 4636433n [FAIL] l2Pool2d float32 4D constant tensor all positive default options promise_test: Unhandled rejection with value: object "TypeError: Unsupported data type, input 'input' data type float32 must be one of []." [FAIL] l2Pool2d float32 4D tensor default all positive options @@ -50,8 +50,8 @@ [FAIL] maxPool2d float32 4D tensor options.dilations promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Pool2d in tflite doesn't support dilations." [FAIL] maxPool2d float32 4D tensor options.roundingType=ceil - assert_true: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by the acceptable 0 ULP distance, but they have 2229449938 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by ULP distance: expected a number less than or equal to 0n but got 2229449938n [FAIL] maxPool2d float32 4D tensor options.outputSizes ignores options.roundingType=floor - assert_true: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by the acceptable 0 ULP distance, but they have 2229449938 ULP distance expected true got false + assert_less_than_equal: assert_array_approx_equals_ulp: test maxPool2d float32 actual 99.28312683105469 should be close enough to expected -39.03501892089844 by ULP distance: expected a number less than or equal to 0n but got 2229449938n Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index 8904cdb..4517dc6 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -1748,6 +1748,11 @@ [Worker] getter applicationServerKey [Worker] getter userVisibleOnly [Worker] method constructor +[Worker] interface QuotaExceededError : DOMException +[Worker] attribute @@toStringTag +[Worker] getter quota +[Worker] getter requested +[Worker] method constructor [Worker] interface RTCDataChannel : EventTarget [Worker] attribute @@toStringTag [Worker] getter binaryType
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index b68f2cde..8c083a2 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -7696,6 +7696,11 @@ getter applicationServerKey getter userVisibleOnly method constructor +interface QuotaExceededError : DOMException + attribute @@toStringTag + getter quota + getter requested + method constructor interface RTCCertificate attribute @@toStringTag getter expires
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt index bc445b7..ec6acef 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -1583,6 +1583,11 @@ [Worker] getter applicationServerKey [Worker] getter userVisibleOnly [Worker] method constructor +[Worker] interface QuotaExceededError : DOMException +[Worker] attribute @@toStringTag +[Worker] getter quota +[Worker] getter requested +[Worker] method constructor [Worker] interface RTCRtpAcks [Worker] attribute @@toStringTag [Worker] getter explicitCongestionNotification
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/containment.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/containment.html new file mode 100644 index 0000000..b168c22 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/containment.html
@@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<title>Canvas.drawElement: styles for children of canvas</title> +<link rel="help" href="https://github.com/WICG/html-in-canvas"> +<link rel="author" href="mailto:chrishtr@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + * { + contain: none !important; + position: absolute !important; + } +</style> +<canvas id=canvas width="200" height="200" layoutsubtree=true> + <div id=child1> + <div id=grandchild1></div> + </div> + <div id=child2> + <div id=grandchild2></div> + </div> +</canvas> +<script> +promise_test(async () => { + child_asserts = { + contain: 'paint', + position: 'static'}; + grandchild_asserts = { + contain: 'none', + position: 'absolute'}; + + for (a in child_asserts) { + assert_equals(getComputedStyle(child1)[a], child_asserts[a]); + assert_equals(getComputedStyle(child2)[a], child_asserts[a]); + } + for (a in grandchild_asserts) { + assert_equals(getComputedStyle(grandchild1)[a], grandchild_asserts[a]); + assert_equals(getComputedStyle(grandchild2)[a], grandchild_asserts[a]); + } + }, 'canvas child containment'); +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/draw-element-detached.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/draw-element-detached.html new file mode 100644 index 0000000..53c01dd89 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/draw-element-detached.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<title>Canvas.drawElement: Throw on lack of layout</title> +<link rel="help" href="https://github.com/WICG/html-in-canvas"> +<link rel="author" href="mailto:schenney@chromium.org"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +#child { + width: 100px; + height: 100px; + background: #01ff02; +} +</style> + +<script> + promise_test(async t => { + let canvas = window.document.createElement("canvas"); + canvas.setAttribute("layoutsubtree", "true"); + let child = window.document.createElement("div"); + child.setAttribute("id", "child"); + canvas.appendChild(child); + let ctx = canvas.getContext('2d'); + ctx.fillStyle = 'rgb(3, 4, 5)'; + ctx.fillRect(0, 0, 200, 200); + assert_throws_js(TypeError, + () => ctx.drawElement(child, 20, 30), + "Can't draw into a detached canvas."); + + }, 'canvas drawElement throws for a detached canvas due to lack of layout'); +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/draw-element-display-none.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/draw-element-display-none.html new file mode 100644 index 0000000..e549746 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/draw-element-display-none.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<title>Canvas.drawElement: Throw on display: none</title> +<link rel="help" href="https://github.com/WICG/html-in-canvas"> +<link rel="author" href="mailto:schenney@chromium.org"> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<style> +div { + width: 100px; + height: 100px; + background: green; +} +canvas { + background: grey; +} +.display-none { + display: none; +} +</style> + +<canvas id="canvas1" width="200" height="200" layoutsubtree=true> + <div id="child1" class="display-none"> + </div> +</canvas> +<canvas id="canvas2" class="display-none" width="200" height="200" layoutsubtree=true> + <div id="child2"> + </div> +</canvas> + + +<script> +promise_test(async () => { + assert_throws_js(TypeError, + () => canvas1.getContext("2d").drawElement(child1, 20, 30), + "Can't draw a display: none child."); + + assert_throws_js(TypeError, + () => canvas2.getContext("2d").drawElement(child2, 20, 30), + "Can't draw into a display-none <canvas>."); +}, "Canvas drawElement() should throw when not laid out."); +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/draw-element-missing-layout.html b/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/draw-element-missing-layout.html deleted file mode 100644 index 18a00be1..0000000 --- a/third_party/blink/web_tests/wpt_internal/html/canvas/drawElement/draw-element-missing-layout.html +++ /dev/null
@@ -1,33 +0,0 @@ -<!DOCTYPE html> -<title>Canvas.drawElement: Throw on lack of layout</title> -<link rel="help" href="https://github.com/WICG/html-in-canvas"> -<link rel="author" href="mailto:schenney@chromium.org"> - -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> - -<style> -#child { - width: 100px; - height: 100px; - background: #01ff02; -} -</style> - -<canvas id=canvas width="200" height="200"> - <div id=child></div> -</canvas> - -<script> - promise_test(async t => { - let ctx = canvas.getContext('2d'); - ctx.fillStyle = 'rgb(3, 4, 5)'; - ctx.fillRect(0, 0, 200, 200); - try { - ctx.drawElement(child, 20, 30); - assert_unreached('Should throw TypeError exception'); - } catch (e) { - assert_true(e instanceof TypeError, 'Exception should be a TypeError'); - } - }, 'canvas drawElement throws when the element is not laid out'); -</script>
diff --git a/third_party/blink/web_tests/wpt_internal/isolated-permissions-policy-stable/permissions_policy.https.html b/third_party/blink/web_tests/wpt_internal/isolated-permissions-policy-stable/permissions_policy.https.html index 052ccec..82e3f33 100644 --- a/third_party/blink/web_tests/wpt_internal/isolated-permissions-policy-stable/permissions_policy.https.html +++ b/third_party/blink/web_tests/wpt_internal/isolated-permissions-policy-stable/permissions_policy.https.html
@@ -59,6 +59,7 @@ 'interest-cohort', 'join-ad-interest-group', 'keyboard-map', + 'language-detector', 'local-fonts', 'magnetometer', 'microphone', @@ -71,16 +72,20 @@ 'private-state-token-redemption', 'publickey-credentials-create', 'publickey-credentials-get', + 'rewriter', 'run-ad-auction', 'screen-wake-lock', 'serial', 'shared-storage', 'shared-storage-select-url', 'storage-access', + 'summarizer', 'sync-xhr', + 'translator', 'unload', 'usb', 'window-management', + 'writer', 'xr-spatial-tracking', ]
diff --git a/third_party/boringssl/src b/third_party/boringssl/src index 6295694..02bc094 160000 --- a/third_party/boringssl/src +++ b/third_party/boringssl/src
@@ -1 +1 @@ -Subproject commit 62956948e445c5bc67d3f299e0003c34a3030523 +Subproject commit 02bc0949e5cac0e1ee82c6f365f5a6c3cfd0cfa9
diff --git a/third_party/catapult b/third_party/catapult index bbb14e4..2fa93b23 160000 --- a/third_party/catapult +++ b/third_party/catapult
@@ -1 +1 @@ -Subproject commit bbb14e46563c14a055b394f18b117e504e98d4ab +Subproject commit 2fa93b2332b7a27c3066bef8d7ba9de2a5e1ab2e
diff --git a/third_party/crabbyavif/BUILD.gn b/third_party/crabbyavif/BUILD.gn index d7fdceb..09d2dbc 100644 --- a/third_party/crabbyavif/BUILD.gn +++ b/third_party/crabbyavif/BUILD.gn
@@ -42,10 +42,22 @@ bindgen_flags = [ "no-doc-comments", "generate=functions,types,vars,methods,constructors,destructors", + "allowlist-item=ABGRToI420", + "allowlist-item=ABGRToJ400", + "allowlist-item=ABGRToJ420", + "allowlist-item=ABGRToJ422", "allowlist-item=AR30ToAB30", - "allowlist-item=ARGBToABGR", "allowlist-item=ARGBAttenuate", + "allowlist-item=ARGBToABGR", + "allowlist-item=ARGBToI400", + "allowlist-item=ARGBToI420", + "allowlist-item=ARGBToI422", + "allowlist-item=ARGBToI444", + "allowlist-item=ARGBToJ400", + "allowlist-item=ARGBToJ420", + "allowlist-item=ARGBToJ422", "allowlist-item=ARGBUnattenuate", + "allowlist-item=BGRAToI420", "allowlist-item=Convert16To8Plane", "allowlist-item=FilterMode", "allowlist-item=FilterMode_kFilterBilinear", @@ -54,6 +66,7 @@ "allowlist-item=HalfFloatPlane", "allowlist-item=I010AlphaToARGBMatrix", "allowlist-item=I010AlphaToARGBMatrixFilter", + "allowlist-item=I010ToAR30Matrix", "allowlist-item=I010ToARGBMatrix", "allowlist-item=I010ToARGBMatrixFilter", "allowlist-item=I012ToARGBMatrix", @@ -82,10 +95,21 @@ "allowlist-item=I444AlphaToARGBMatrix", "allowlist-item=I444ToARGBMatrix", "allowlist-item=I444ToRGB24Matrix", + "allowlist-item=NV12Scale", "allowlist-item=NV12ToARGBMatrix", + "allowlist-item=NV12ToRGB565Matrix", "allowlist-item=NV21ToARGBMatrix", "allowlist-item=P010ToAR30Matrix", "allowlist-item=P010ToARGBMatrix", + "allowlist-item=P010ToI010", + "allowlist-item=RAWToI420", + "allowlist-item=RAWToJ400", + "allowlist-item=RAWToJ420", + "allowlist-item=RGB24ToI420", + "allowlist-item=RGB24ToJ400", + "allowlist-item=RGB24ToJ420", + "allowlist-item=RGBAToI420", + "allowlist-item=RGBAToJ400", "allowlist-item=ScalePlane", "allowlist-item=ScalePlane_12", "allowlist-item=YuvConstants", @@ -132,15 +156,14 @@ "src/src/capi/types.rs", "src/src/codecs/dav1d.rs", "src/src/codecs/mod.rs", - "src/src/decoder/gainmap.rs", "src/src/decoder/item.rs", "src/src/decoder/mod.rs", "src/src/decoder/tile.rs", "src/src/decoder/track.rs", + "src/src/gainmap.rs", "src/src/image.rs", "src/src/internal_utils/io.rs", "src/src/internal_utils/mod.rs", - "src/src/internal_utils/pixels.rs", "src/src/internal_utils/stream.rs", "src/src/lib.rs", "src/src/parser/exif.rs", @@ -156,6 +179,11 @@ "src/src/reformat/scale.rs", "src/src/utils/clap.rs", "src/src/utils/mod.rs", + "src/src/utils/pixels.rs", + "src/src/utils/reader/mod.rs", + "src/src/utils/reader/y4m.rs", + "src/src/utils/writer/mod.rs", + "src/src/utils/writer/y4m.rs", ] features = [
diff --git a/third_party/crabbyavif/README.chromium b/third_party/crabbyavif/README.chromium index 3ef4cd2..99b29a08 100644 --- a/third_party/crabbyavif/README.chromium +++ b/third_party/crabbyavif/README.chromium
@@ -2,7 +2,7 @@ Short Name: crabbyavif URL: https://github.com/webmproject/CrabbyAvif Version: N/A -Revision: DEPS +Revision: b097e11df62db2a6b8561f60aeae0718901122cb License: Apache-2.0 License File: LICENSE Security Critical: yes
diff --git a/third_party/crabbyavif/src b/third_party/crabbyavif/src index 02d0fad..b097e11 160000 --- a/third_party/crabbyavif/src +++ b/third_party/crabbyavif/src
@@ -1 +1 @@ -Subproject commit 02d0fad2c512380b7270d6e704c86521075d7d54 +Subproject commit b097e11df62db2a6b8561f60aeae0718901122cb
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium index ec446c5..9f30607 100644 --- a/third_party/crashpad/README.chromium +++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@ Short Name: crashpad URL: https://crashpad.chromium.org/ Version: N/A -Revision: 3bc11fdb21b301d328dc0c063c5a30774adba098 +Revision: aed4e5d82c7082635a09bcc999760489e573b406 License: Apache-2.0 License File: crashpad/LICENSE Security Critical: yes
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS index 0268f149..9c4aa15c 100644 --- a/third_party/crashpad/crashpad/DEPS +++ b/third_party/crashpad/crashpad/DEPS
@@ -36,7 +36,7 @@ 'c912837e0d82b5ca4b6e790b573b3956d3744c1c', 'crashpad/third_party/edo/edo': { 'url': Var('chromium_git') + '/external/github.com/google/eDistantObject.git@' + - '727e556705278598fce683522beedbb9946bfda0', + '38e71ff183d76f702db6966fa7236c98831acd80', 'condition': 'checkout_ios', }, 'crashpad/third_party/googletest/googletest': @@ -47,7 +47,7 @@ '9719c1e1e676814c456b55f5f070eabad6709d31', 'crashpad/third_party/mini_chromium/mini_chromium': Var('chromium_git') + '/chromium/mini_chromium@' + - '15d1cace45803c0efb2a43630bf48bcdc15ad9e8', + '361ef33dcdfb1f2495fe6e44b9887fb9ab1d46af', 'crashpad/third_party/libfuzzer/src': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' + 'fda403cf93ecb8792cb1d061564d89a6553ca020',
diff --git a/third_party/crashpad/crashpad/build/fuchsia_envs.py b/third_party/crashpad/crashpad/build/fuchsia_envs.py index 8d95b78..753c322 100755 --- a/third_party/crashpad/crashpad/build/fuchsia_envs.py +++ b/third_party/crashpad/crashpad/build/fuchsia_envs.py
@@ -37,6 +37,8 @@ os.environ['SRC_ROOT'], 'third_party/fuchsia/sdk/linux-amd64/') os.environ['FUCHSIA_GN_SDK_ROOT'] = os.path.join( os.environ['SRC_ROOT'], 'third_party/fuchsia-gn-sdk/src') + os.environ['FUCHSIA_READELF'] = os.path.join(os.environ['SRC_ROOT'], + 'third_party/fuchsia/clang/linux-amd64/bin/llvm-readelf') return subprocess.run(args).returncode
diff --git a/third_party/crashpad/crashpad/client/BUILD.gn b/third_party/crashpad/crashpad/client/BUILD.gn index 78c3ded..a3ccc71 100644 --- a/third_party/crashpad/crashpad/client/BUILD.gn +++ b/third_party/crashpad/crashpad/client/BUILD.gn
@@ -32,6 +32,8 @@ if (crashpad_is_ios) { sources += [ + "crash_handler_base_ios.cc", + "crash_handler_base_ios.h", "crashpad_client_ios.cc", "ios_handler/exception_processor.h", "ios_handler/exception_processor.mm", @@ -44,6 +46,18 @@ "simulate_crash_ios.h", "upload_behavior_ios.h", ] + + if (!crashpad_is_tvos) { + sources += [ + "crash_handler_ios.cc", + "crash_handler_ios.h", + ] + } else { + sources += [ + "crash_handler_tvos.cc", + "crash_handler_tvos.h", + ] + } } if (crashpad_is_linux || crashpad_is_android) {
diff --git a/third_party/crashpad/crashpad/client/crash_handler_base_ios.cc b/third_party/crashpad/crashpad/client/crash_handler_base_ios.cc new file mode 100644 index 0000000..6b349ca --- /dev/null +++ b/third_party/crashpad/crashpad/client/crash_handler_base_ios.cc
@@ -0,0 +1,127 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "client/crash_handler_base_ios.h" + +#include "base/logging.h" +#include "util/posix/signals.h" + +namespace crashpad { + +CrashHandlerBase::CrashHandlerBase() = default; +CrashHandlerBase::~CrashHandlerBase() = default; + +bool CrashHandlerBase::Initialize( + const base::FilePath& database, + const std::string& url, + const std::map<std::string, std::string>& annotations, + internal::InProcessHandler::ProcessPendingReportsObservationCallback + callback) { + INITIALIZATION_STATE_SET_INITIALIZING(initialized_); + if (!in_process_handler().Initialize(database, url, annotations, callback)) { + LOG(ERROR) << "Unable to initialize Crashpad."; + return false; + } + if (!DoInitialize()) { + return false; + } + INITIALIZATION_STATE_SET_VALID(initialized_); + return true; +} + +void CrashHandlerBase::ProcessIntermediateDumps( + const std::map<std::string, std::string>& annotations, + const UserStreamDataSources* user_stream_sources) { + in_process_handler_.ProcessIntermediateDumps(annotations, + user_stream_sources); +} + +void CrashHandlerBase::ProcessIntermediateDump( + const base::FilePath& file, + const std::map<std::string, std::string>& annotations) { + in_process_handler_.ProcessIntermediateDump(file, annotations); +} + +void CrashHandlerBase::DumpWithoutCrash(NativeCPUContext* context, + bool process_dump) { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + base::FilePath path; + if (!in_process_handler_.DumpExceptionFromSimulatedMachException( + context, kMachExceptionSimulated, &path)) { + return; + } + + if (process_dump) { + in_process_handler_.ProcessIntermediateDump(path); + } +} + +void CrashHandlerBase::DumpWithoutCrashAtPath(NativeCPUContext* context, + const base::FilePath& path) { + in_process_handler_.DumpExceptionFromSimulatedMachExceptionAtPath( + context, kMachExceptionSimulated, path); +} + +void CrashHandlerBase::StartProcessingPendingReports( + UploadBehavior upload_behavior) { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + in_process_handler_.StartProcessingPendingReports(upload_behavior); +} + +void CrashHandlerBase::SetExceptionCallbackForTesting(void (*callback)()) { + in_process_handler_.SetExceptionCallbackForTesting(callback); +} + +void CrashHandlerBase::HandleAndReraiseSignal(int signo, + siginfo_t* siginfo, + ucontext_t* context, + struct sigaction* old_action) { + in_process_handler_.DumpExceptionFromSignal(siginfo, context); + + // Always call system handler. + Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, old_action); +} + +void CrashHandlerBase::HandleUncaughtNSException(const uint64_t* frames, + const size_t num_frames) { + in_process_handler_.DumpExceptionFromNSExceptionWithFrames(frames, + num_frames); + // After uncaught exceptions are reported, the system immediately triggers a + // call to std::terminate()/abort(). Remove the abort handler so a second + // dump isn't generated. + CHECK(Signals::InstallDefaultHandler(SIGABRT)); +} + +void CrashHandlerBase::HandleUncaughtNSExceptionWithContext( + NativeCPUContext* context) { + base::FilePath path; + in_process_handler_.DumpExceptionFromSimulatedMachException( + context, kMachExceptionFromNSException, &path); + + // After uncaught exceptions are reported, the system immediately triggers a + // call to std::terminate()/abort(). Remove the abort handler so a second + // dump isn't generated. + CHECK(Signals::InstallDefaultHandler(SIGABRT)); +} + +void CrashHandlerBase::HandleUncaughtNSExceptionWithContextAtPath( + NativeCPUContext* context, + const base::FilePath& path) { + in_process_handler_.DumpExceptionFromSimulatedMachExceptionAtPath( + context, kMachExceptionFromNSException, path); +} + +bool CrashHandlerBase::MoveIntermediateDumpAtPathToPending( + const base::FilePath& path) { + if (in_process_handler_.MoveIntermediateDumpAtPathToPending(path)) { + // After uncaught exceptions are reported, the system immediately triggers + // a call to std::terminate()/abort(). Remove the abort handler so a + // second dump isn't generated. + CHECK(Signals::InstallDefaultHandler(SIGABRT)); + return true; + } + return false; +} + +} // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/crash_handler_base_ios.h b/third_party/crashpad/crashpad/client/crash_handler_base_ios.h new file mode 100644 index 0000000..0aea1925 --- /dev/null +++ b/third_party/crashpad/crashpad/client/crash_handler_base_ios.h
@@ -0,0 +1,89 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CRASHPAD_CLIENT_CRASH_HANDLER_BASE_IOS_H_ +#define CRASHPAD_CLIENT_CRASH_HANDLER_BASE_IOS_H_ + +#include <stdint.h> +#include <sys/signal.h> + +#include <map> +#include <string> + +#include "base/files/file_path.h" +#include "client/ios_handler/exception_processor.h" +#include "client/ios_handler/in_process_handler.h" +#include "client/upload_behavior_ios.h" +#include "util/misc/capture_context.h" +#include "util/misc/initialization_state_dcheck.h" + +namespace crashpad { + +// Base class shared by the iOS and tvOS CrashHandler implementations. +class CrashHandlerBase : public ObjcExceptionDelegate { + public: + CrashHandlerBase(const CrashHandlerBase&) = delete; + CrashHandlerBase& operator=(const CrashHandlerBase&) = delete; + + bool Initialize( + const base::FilePath& database, + const std::string& url, + const std::map<std::string, std::string>& annotations, + internal::InProcessHandler::ProcessPendingReportsObservationCallback + callback); + + void ProcessIntermediateDumps( + const std::map<std::string, std::string>& annotations, + const UserStreamDataSources* user_stream_sources); + + void ProcessIntermediateDump( + const base::FilePath& file, + const std::map<std::string, std::string>& annotations); + + void DumpWithoutCrash(NativeCPUContext* context, bool process_dump); + + void DumpWithoutCrashAtPath(NativeCPUContext* context, + const base::FilePath& path); + + void StartProcessingPendingReports(UploadBehavior upload_behavior); + + void SetExceptionCallbackForTesting(void (*callback)()); + + protected: + CrashHandlerBase(); + virtual ~CrashHandlerBase(); + + // Subclasses are expected to install signal handlers and set up Mach ports in + // this function. + virtual bool DoInitialize() = 0; + + void HandleAndReraiseSignal(int signo, + siginfo_t* siginfo, + ucontext_t* context, + struct sigaction* old_action); + + internal::InProcessHandler& in_process_handler() { + return in_process_handler_; + } + + private: + // ObjcExceptionDelegate overrides: + void HandleUncaughtNSException(const uint64_t* frames, + const size_t num_frames) override; + + void HandleUncaughtNSExceptionWithContext(NativeCPUContext* context) override; + + void HandleUncaughtNSExceptionWithContextAtPath( + NativeCPUContext* context, + const base::FilePath& path) override; + + bool MoveIntermediateDumpAtPathToPending(const base::FilePath& path) override; + + internal::InProcessHandler in_process_handler_; + InitializationStateDcheck initialized_; +}; + +} // namespace crashpad + +#endif // CRASHPAD_CLIENT_CRASH_HANDLER_BASE_IOS_H_
diff --git a/third_party/crashpad/crashpad/client/crash_handler_ios.cc b/third_party/crashpad/crashpad/client/crash_handler_ios.cc new file mode 100644 index 0000000..f149ae7 --- /dev/null +++ b/third_party/crashpad/crashpad/client/crash_handler_ios.cc
@@ -0,0 +1,307 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "client/crash_handler_ios.h" + +#include <sys/sysctl.h> +#include <unistd.h> + +#include <iterator> + +#include "base/apple/mach_logging.h" +#include "util/ios/raw_logging.h" +#include "util/mach/mach_extensions.h" +#include "util/mach/mach_message.h" +#include "util/mach/mach_message_server.h" +#include "util/posix/signals.h" + +namespace { + +bool IsBeingDebugged() { + int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; + size_t len = sizeof(kinfo_proc); + kinfo_proc kern_proc_info; + if (sysctl(mib, std::size(mib), &kern_proc_info, &len, nullptr, 0) == 0) { + return kern_proc_info.kp_proc.p_flag & P_TRACED; + } + return false; +} + +} // namespace + +namespace crashpad { + +CrashHandler::ThreadSafeScopedMachPortWithReceiveRight:: + ThreadSafeScopedMachPortWithReceiveRight() + : port_(NewMachPort(MACH_PORT_RIGHT_RECEIVE)) {} + +CrashHandler::ThreadSafeScopedMachPortWithReceiveRight:: + ~ThreadSafeScopedMachPortWithReceiveRight() { + reset(); +} + +mach_port_t CrashHandler::ThreadSafeScopedMachPortWithReceiveRight::get() { + return port_.load(); +} +void CrashHandler::ThreadSafeScopedMachPortWithReceiveRight::reset() { + mach_port_t old_port = port_.exchange(MACH_PORT_NULL); + if (old_port == MACH_PORT_NULL) { + // Already reset, nothing to do. + return; + } + kern_return_t kr = mach_port_mod_refs( + mach_task_self(), old_port, MACH_PORT_RIGHT_RECEIVE, -1); + MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) + << "ThreadSafeScopedMachPortWithReceiveRight mach_port_mod_refs"; + kr = mach_port_deallocate(mach_task_self(), old_port); + MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) + << "ThreadSafeScopedMachPortWithReceiveRight mach_port_deallocate"; +} + +CrashHandler* CrashHandler::instance_ = nullptr; + +CrashHandler::CrashHandler() = default; + +CrashHandler::~CrashHandler() { + UninstallObjcExceptionPreprocessor(); + // Reset the SIGPIPE handler only if the current handler is the + // one installed by DoInitialize(). In other words, if an + // application has set its own SIGPIPE handler after initializing + // Crashpad, there is no need to change the signal handler here. + struct sigaction sa; + if (sigaction(SIGPIPE, nullptr, &sa) == 0 && + sa.sa_sigaction == CatchAndReraiseSignalDefaultAction) { + Signals::InstallDefaultHandler(SIGPIPE); + } + Signals::InstallDefaultHandler(SIGABRT); + UninstallMachExceptionHandler(); +} + +// static +CrashHandler* CrashHandler::Get() { + if (!instance_) + instance_ = new CrashHandler(); + return instance_; +} + +// static +void CrashHandler::ResetForTesting() { + delete instance_; + instance_ = nullptr; +} + +bool CrashHandler::DoInitialize() { + if (!InstallMachExceptionHandler() || + // xnu turns hardware faults into Mach exceptions, so the only signal + // left to register is SIGABRT, which never starts off as a hardware + // fault. Installing a handler for other signals would lead to + // recording exceptions twice. As a consequence, Crashpad will not + // generate intermediate dumps for anything manually calling + // raise(SIG*). In practice, this doesn’t actually happen for crash + // signals that originate as hardware faults. + !Signals::InstallHandler( + SIGABRT, CatchAndReraiseSignal, 0, &old_action_)) { + return false; + } + + // For applications that haven't ignored or set a handler for SIGPIPE: + // It’s OK for an application to set its own SIGPIPE handler (including + // SIG_IGN) before initializing Crashpad, because Crashpad will discover the + // existing handler and not install its own. + // It’s OK for Crashpad to install its own SIGPIPE handler and for the + // application to subsequently install its own (including SIG_IGN) + // afterwards, because its handler will replace Crashpad’s. + // This is useful to cover the default situation where nobody installs a + // SIGPIPE handler and the disposition is at SIG_DFL, because SIGPIPE is a + // “kill” signal (bsd/sys/signalvar.h sigprop). In that case, without + // Crashpad, SIGPIPE results in a silent and unreported kill (and not even + // ReportCrash will record it), but developers probably want to be alerted to + // the condition. + struct sigaction sa; + if (sigaction(SIGPIPE, nullptr, &sa) == 0 && sa.sa_handler == SIG_DFL) { + Signals::InstallHandler( + SIGPIPE, CatchAndReraiseSignalDefaultAction, 0, nullptr); + } + + InstallObjcExceptionPreprocessor(this); + return true; +} + +bool CrashHandler::InstallMachExceptionHandler() { + mach_port_t exception_port = exception_port_.get(); + if (exception_port == MACH_PORT_NULL) { + return false; + } + + kern_return_t kr = mach_port_insert_right(mach_task_self(), + exception_port, + exception_port, + MACH_MSG_TYPE_MAKE_SEND); + if (kr != KERN_SUCCESS) { + MACH_LOG(ERROR, kr) << "mach_port_insert_right"; + return false; + } + + // TODO: Use SwapExceptionPort instead and put back EXC_MASK_BREAKPOINT. + // Until then, remove |EXC_MASK_BREAKPOINT| while attached to a debugger. + exception_mask_t mask = + ExcMaskAll() & + ~(EXC_MASK_EMULATION | EXC_MASK_SOFTWARE | EXC_MASK_RPC_ALERT | + EXC_MASK_GUARD | (IsBeingDebugged() ? EXC_MASK_BREAKPOINT : 0)); + + ExceptionPorts exception_ports(ExceptionPorts::kTargetTypeTask, TASK_NULL); + if (!exception_ports.GetExceptionPorts(mask, &original_handlers_) || + !exception_ports.SetExceptionPort( + mask, + exception_port, + EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, + MACHINE_THREAD_STATE)) { + return false; + } + + mach_handler_running_ = true; + Start(); + return true; +} + +void CrashHandler::UninstallMachExceptionHandler() { + mach_handler_running_ = false; + exception_port_.reset(); + Join(); +} + +// Thread: + +void CrashHandler::ThreadMain() { + UniversalMachExcServer universal_mach_exc_server(this); + while (mach_handler_running_) { + mach_msg_return_t mr = + MachMessageServer::Run(&universal_mach_exc_server, + exception_port_.get(), + MACH_MSG_OPTION_NONE, + MachMessageServer::kPersistent, + MachMessageServer::kReceiveLargeIgnore, + kMachMessageTimeoutWaitIndefinitely); + MACH_CHECK( + mach_handler_running_ + ? mr == MACH_SEND_INVALID_DEST // This shouldn't happen for + // exception messages that come + // from the kernel itself, but if + // something else in-process sends + // exception messages and breaks, + // handle that case. + : (mr == MACH_RCV_PORT_CHANGED || // Port was closed while the + // thread was listening. + mr == MACH_RCV_INVALID_NAME), // Port was closed before the + // thread started listening. + mr) + << "MachMessageServer::Run"; + } +} + +// UniversalMachExcServer::Interface: + +kern_return_t CrashHandler::CatchMachException( + exception_behavior_t behavior, + exception_handler_t exception_port, + thread_t thread, + task_t task, + exception_type_t exception, + const mach_exception_data_type_t* code, + mach_msg_type_number_t code_count, + thread_state_flavor_t* flavor, + ConstThreadState old_state, + mach_msg_type_number_t old_state_count, + thread_state_t new_state, + mach_msg_type_number_t* new_state_count, + const mach_msg_trailer_t* trailer, + bool* destroy_complex_request) { + *destroy_complex_request = true; + + // TODO(justincohen): Forward exceptions to original_handlers_ with + // UniversalExceptionRaise. + + // iOS shouldn't have any child processes, but just in case, those will + // inherit the task exception ports, and this process isn’t prepared to + // handle them + if (task != mach_task_self()) { + CRASHPAD_RAW_LOG("MachException task != mach_task_self()"); + return KERN_FAILURE; + } + + HandleMachException(behavior, + thread, + exception, + code, + code_count, + *flavor, + old_state, + old_state_count); + + // Respond with KERN_FAILURE so the system will continue to handle this + // exception. xnu will turn this Mach exception into a signal and take the + // default action to terminate the process. However, if sigprocmask is + // called before this Mach exception returns (such as by another thread + // calling abort, see: Libc-1506.40.4/stdlib/FreeBSD/abort.c), the Mach + // exception will be converted into a signal but delivery will be blocked. + // Since concurrent exceptions lead to the losing thread sleeping + // indefinitely, if the abort thread never returns, the thread that + // triggered this Mach exception will repeatedly trap and the process will + // never terminate. If the abort thread didn’t have a user-space signal + // handler that slept forever, the abort would terminate the process even if + // all other signals had been blocked. Instead, unblock all signals + // corresponding to all Mach exceptions Crashpad is registered for before + // returning KERN_FAILURE. There is still racy behavior possible with this + // call to sigprocmask, but the repeated calls to CatchMachException here + // will eventually lead to termination. + sigset_t unblock_set; + sigemptyset(&unblock_set); + sigaddset(&unblock_set, SIGILL); // EXC_BAD_INSTRUCTION + sigaddset(&unblock_set, SIGTRAP); // EXC_BREAKPOINT + sigaddset(&unblock_set, SIGFPE); // EXC_ARITHMETIC + sigaddset(&unblock_set, SIGBUS); // EXC_BAD_ACCESS + sigaddset(&unblock_set, SIGSEGV); // EXC_BAD_ACCESS + if (sigprocmask(SIG_UNBLOCK, &unblock_set, nullptr) != 0) { + CRASHPAD_RAW_LOG("sigprocmask"); + } + return KERN_FAILURE; +} + +void CrashHandler::HandleMachException(exception_behavior_t behavior, + thread_t thread, + exception_type_t exception, + const mach_exception_data_type_t* code, + mach_msg_type_number_t code_count, + thread_state_flavor_t flavor, + ConstThreadState old_state, + mach_msg_type_number_t old_state_count) { + in_process_handler().DumpExceptionFromMachException(behavior, + thread, + exception, + code, + code_count, + flavor, + old_state, + old_state_count); +} + +// static +void CrashHandler::CatchAndReraiseSignal(int signo, + siginfo_t* siginfo, + void* context) { + Get()->HandleAndReraiseSignal(signo, + siginfo, + reinterpret_cast<ucontext_t*>(context), + &(Get()->old_action_)); +} + +// static +void CrashHandler::CatchAndReraiseSignalDefaultAction(int signo, + siginfo_t* siginfo, + void* context) { + Get()->HandleAndReraiseSignal( + signo, siginfo, reinterpret_cast<ucontext_t*>(context), nullptr); +} + +} // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/crash_handler_ios.h b/third_party/crashpad/crashpad/client/crash_handler_ios.h new file mode 100644 index 0000000..35e1753d --- /dev/null +++ b/third_party/crashpad/crashpad/client/crash_handler_ios.h
@@ -0,0 +1,109 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CRASHPAD_CLIENT_CRASH_HANDLER_IOS_H_ +#define CRASHPAD_CLIENT_CRASH_HANDLER_IOS_H_ + +#include <atomic> + +#include "client/crash_handler_base_ios.h" +#include "util/mach/exc_server_variants.h" +#include "util/mach/exception_ports.h" +#include "util/thread/thread.h" + +namespace crashpad { + +// A base class for signal handler and Mach exception server. +class CrashHandler : public Thread, + public UniversalMachExcServer::Interface, + public CrashHandlerBase { + public: + CrashHandler(const CrashHandler&) = delete; + CrashHandler& operator=(const CrashHandler&) = delete; + + static CrashHandler* Get(); + + static void ResetForTesting(); + + private: + // Thread-safe version of `base::apple::ScopedMachReceiveRight` which + // allocates the Mach port upon construction and deallocates it upon + // destruction. + class ThreadSafeScopedMachPortWithReceiveRight { + public: + ThreadSafeScopedMachPortWithReceiveRight(); + + ThreadSafeScopedMachPortWithReceiveRight( + const ThreadSafeScopedMachPortWithReceiveRight&) = delete; + ThreadSafeScopedMachPortWithReceiveRight& operator=( + const ThreadSafeScopedMachPortWithReceiveRight&) = delete; + + ~ThreadSafeScopedMachPortWithReceiveRight(); + + mach_port_t get(); + void reset(); + + private: + std::atomic<mach_port_t> port_; + }; + + CrashHandler(); + + ~CrashHandler() override; + + bool DoInitialize() override; + + bool InstallMachExceptionHandler(); + + void UninstallMachExceptionHandler(); + + // Thread: + + void ThreadMain() override; + + // UniversalMachExcServer::Interface: + + kern_return_t CatchMachException(exception_behavior_t behavior, + exception_handler_t exception_port, + thread_t thread, + task_t task, + exception_type_t exception, + const mach_exception_data_type_t* code, + mach_msg_type_number_t code_count, + thread_state_flavor_t* flavor, + ConstThreadState old_state, + mach_msg_type_number_t old_state_count, + thread_state_t new_state, + mach_msg_type_number_t* new_state_count, + const mach_msg_trailer_t* trailer, + bool* destroy_complex_request) override; + + void HandleMachException(exception_behavior_t behavior, + thread_t thread, + exception_type_t exception, + const mach_exception_data_type_t* code, + mach_msg_type_number_t code_count, + thread_state_flavor_t flavor, + ConstThreadState old_state, + mach_msg_type_number_t old_state_count); + + // The signal handler installed at OS-level. + static void CatchAndReraiseSignal(int signo, + siginfo_t* siginfo, + void* context); + + static void CatchAndReraiseSignalDefaultAction(int signo, + siginfo_t* siginfo, + void* context); + + ThreadSafeScopedMachPortWithReceiveRight exception_port_; + ExceptionPorts::ExceptionHandlerVector original_handlers_; + struct sigaction old_action_ = {}; + static CrashHandler* instance_; + std::atomic<bool> mach_handler_running_ = false; +}; + +} // namespace crashpad + +#endif // CRASHPAD_CLIENT_CRASH_HANDLER_IOS_H_
diff --git a/third_party/crashpad/crashpad/client/crash_handler_tvos.cc b/third_party/crashpad/crashpad/client/crash_handler_tvos.cc new file mode 100644 index 0000000..3b92fab --- /dev/null +++ b/third_party/crashpad/crashpad/client/crash_handler_tvos.cc
@@ -0,0 +1,97 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "client/crash_handler_tvos.h" + +#include <sys/signal.h> + +#include "util/posix/signals.h" +#include "util/thread/thread.h" + +namespace crashpad { + +CrashHandler* CrashHandler::instance_ = nullptr; + +CrashHandler::CrashHandler() = default; + +CrashHandler::~CrashHandler() { + UninstallObjcExceptionPreprocessor(); + for (int signo = 1; signo < NSIG; ++signo) { + if (!Signals::IsCrashSignal(signo)) { + Signals::RestoreOrResetHandler(signo, + old_actions_.ActionForSignal(signo)); + } else if (signo == SIGPIPE) { + // Reset the SIGPIPE handler only if the current handler is the one + // installed by DoInitialize(). In other words, if an application has set + // its own SIGPIPE handler after initializing Crashpad, there is no need + // to change the signal handler here. + struct sigaction sa; + if (sigaction(SIGPIPE, nullptr, &sa) == 0 && + sa.sa_sigaction == CatchAndReraiseSignal) { + Signals::InstallDefaultHandler(SIGPIPE); + } + } + } +} + +// static +CrashHandler* CrashHandler::Get() { + if (!instance_) { + instance_ = new CrashHandler; + } + return instance_; +} + +// static +void CrashHandler::ResetForTesting() { + delete instance_; + instance_ = nullptr; +} + +uint64_t CrashHandler::GetThreadIdForTesting() { + return Thread::GetThreadIdForTesting(); +} + +bool CrashHandler::DoInitialize() { + if (!Signals::InstallCrashHandlers(CatchAndReraiseSignal, + /*flags=*/0, + &old_actions_)) { + LOG(ERROR) << "Unable to install crash handlers"; + return false; + } + + // For applications that haven't ignored or set a handler for SIGPIPE: + // It’s OK for an application to set its own SIGPIPE handler (including + // SIG_IGN) before initializing Crashpad, because Crashpad will discover the + // existing handler and not install its own. + // It’s OK for Crashpad to install its own SIGPIPE handler and for the + // application to subsequently install its own (including SIG_IGN) + // afterwards, because its handler will replace Crashpad’s. + // This is useful to cover the default situation where nobody installs a + // SIGPIPE handler and the disposition is at SIG_DFL, because SIGPIPE is a + // “kill” signal (bsd/sys/signalvar.h sigprop). In that case, without + // Crashpad, SIGPIPE results in a silent and unreported kill (and not even + // ReportCrash will record it), but developers probably want to be alerted to + // the condition. + struct sigaction sa; + if (sigaction(SIGPIPE, nullptr, &sa) == 0 && sa.sa_handler == SIG_DFL) { + Signals::InstallHandler(SIGPIPE, CatchAndReraiseSignal, 0, nullptr); + } + + InstallObjcExceptionPreprocessor(this); + return true; +} + +// static +void CrashHandler::CatchAndReraiseSignal(int signo, + siginfo_t* siginfo, + void* context) { + CrashHandler* self = Get(); + self->HandleAndReraiseSignal(signo, + siginfo, + reinterpret_cast<ucontext_t*>(context), + self->old_actions_.ActionForSignal(signo)); +} + +} // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/crash_handler_tvos.h b/third_party/crashpad/crashpad/client/crash_handler_tvos.h new file mode 100644 index 0000000..61e2718 --- /dev/null +++ b/third_party/crashpad/crashpad/client/crash_handler_tvos.h
@@ -0,0 +1,44 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CRASHPAD_CLIENT_CRASH_HANDLER_TVOS_H_ +#define CRASHPAD_CLIENT_CRASH_HANDLER_TVOS_H_ + +#include "client/crash_handler_base_ios.h" +#include "util/posix/signals.h" + +namespace crashpad { + +// A crash handler based on POSIX signals. +// The APIs to handle Mach exceptions are not available to third-party +// applications on tvOS. +class CrashHandler final : public CrashHandlerBase { + public: + CrashHandler(const CrashHandler&) = delete; + CrashHandler& operator=(const CrashHandler&) = delete; + + static CrashHandler* Get(); + + static void ResetForTesting(); + + uint64_t GetThreadIdForTesting(); + + private: + CrashHandler(); + ~CrashHandler() override; + + bool DoInitialize() override; + + // The signal handler installed at OS-level. + static void CatchAndReraiseSignal(int signo, + siginfo_t* siginfo, + void* context); + + Signals::OldActions old_actions_ = {}; + static CrashHandler* instance_; +}; + +} // namespace crashpad + +#endif // CRASHPAD_CLIENT_CRASH_HANDLER_TVOS_H_
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_ios.cc b/third_party/crashpad/crashpad/client/crashpad_client_ios.cc index c9a0226..fbff1a3 100644 --- a/third_party/crashpad/crashpad/client/crashpad_client_ios.cc +++ b/third_party/crashpad/crashpad/client/crashpad_client_ios.cc
@@ -14,432 +14,17 @@ #include "client/crashpad_client.h" -#include <signal.h> -#include <unistd.h> - -#include <atomic> -#include <iterator> - -#include "base/apple/mach_logging.h" -#include "base/logging.h" -#include "client/ios_handler/exception_processor.h" +#include "build/buildflag.h" #include "client/ios_handler/in_process_handler.h" -#include "util/ios/raw_logging.h" -#include "util/mach/exc_server_variants.h" -#include "util/mach/exception_ports.h" -#include "util/mach/mach_extensions.h" -#include "util/mach/mach_message.h" -#include "util/mach/mach_message_server.h" -#include "util/misc/initialization_state_dcheck.h" -#include "util/posix/signals.h" -#include "util/thread/thread.h" -namespace { - -bool IsBeingDebugged() { - kinfo_proc kern_proc_info; - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; - size_t len = sizeof(kern_proc_info); - if (sysctl(mib, std::size(mib), &kern_proc_info, &len, nullptr, 0) == 0) - return kern_proc_info.kp_proc.p_flag & P_TRACED; - return false; -} - -} // namespace +#if !BUILDFLAG(IS_IOS_TVOS) +#include "client/crash_handler_ios.h" +#else +#include "client/crash_handler_tvos.h" +#endif namespace crashpad { -namespace { - -// Thread-safe version of `base::apple::ScopedMachReceiveRight` which allocates -// the Mach port upon construction and deallocates it upon destruction. -class ThreadSafeScopedMachPortWithReceiveRight { - public: - ThreadSafeScopedMachPortWithReceiveRight() - : port_(NewMachPort(MACH_PORT_RIGHT_RECEIVE)) {} - - ThreadSafeScopedMachPortWithReceiveRight( - const ThreadSafeScopedMachPortWithReceiveRight&) = delete; - ThreadSafeScopedMachPortWithReceiveRight& operator=( - const ThreadSafeScopedMachPortWithReceiveRight&) = delete; - - ~ThreadSafeScopedMachPortWithReceiveRight() { reset(); } - - mach_port_t get() { return port_.load(); } - void reset() { - mach_port_t old_port = port_.exchange(MACH_PORT_NULL); - if (old_port == MACH_PORT_NULL) { - // Already reset, nothing to do. - return; - } - kern_return_t kr = mach_port_mod_refs( - mach_task_self(), old_port, MACH_PORT_RIGHT_RECEIVE, -1); - MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) - << "ThreadSafeScopedMachPortWithReceiveRight mach_port_mod_refs"; - kr = mach_port_deallocate(mach_task_self(), old_port); - MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) - << "ThreadSafeScopedMachPortWithReceiveRight mach_port_deallocate"; - } - - private: - std::atomic<mach_port_t> port_; -}; - -// A base class for signal handler and Mach exception server. -class CrashHandler : public Thread, - public UniversalMachExcServer::Interface, - public ObjcExceptionDelegate { - public: - CrashHandler(const CrashHandler&) = delete; - CrashHandler& operator=(const CrashHandler&) = delete; - - static CrashHandler* Get() { - if (!instance_) - instance_ = new CrashHandler(); - return instance_; - } - - static void ResetForTesting() { - delete instance_; - instance_ = nullptr; - } - - bool Initialize( - const base::FilePath& database, - const std::string& url, - const std::map<std::string, std::string>& annotations, - internal::InProcessHandler::ProcessPendingReportsObservationCallback - callback) { - INITIALIZATION_STATE_SET_INITIALIZING(initialized_); - if (!in_process_handler_.Initialize(database, url, annotations, callback) || - !InstallMachExceptionHandler() || - // xnu turns hardware faults into Mach exceptions, so the only signal - // left to register is SIGABRT, which never starts off as a hardware - // fault. Installing a handler for other signals would lead to - // recording exceptions twice. As a consequence, Crashpad will not - // generate intermediate dumps for anything manually calling - // raise(SIG*). In practice, this doesn’t actually happen for crash - // signals that originate as hardware faults. - !Signals::InstallHandler( - SIGABRT, CatchAndReraiseSignal, 0, &old_action_)) { - LOG(ERROR) << "Unable to initialize Crashpad."; - return false; - } - - // For applications that haven't ignored or set a handler for SIGPIPE: - // It’s OK for an application to set its own SIGPIPE handler (including - // SIG_IGN) before initializing Crashpad, because Crashpad will discover the - // existing handler and not install its own. - // It’s OK for Crashpad to install its own SIGPIPE handler and for the - // application to subsequently install its own (including SIG_IGN) - // afterwards, because its handler will replace Crashpad’s. - // This is useful to cover the default situation where nobody installs a - // SIGPIPE handler and the disposition is at SIG_DFL, because SIGPIPE is a - // “kill” signal (bsd/sys/signalvar.h sigprop). In that case, without - // Crashpad, SIGPIPE results in a silent and unreported kill (and not even - // ReportCrash will record it), but developers probably want to be alerted - // to the conditon. - struct sigaction sa; - if (sigaction(SIGPIPE, nullptr, &sa) == 0 && sa.sa_handler == SIG_DFL) { - Signals::InstallHandler( - SIGPIPE, CatchAndReraiseSignalDefaultAction, 0, nullptr); - } - - InstallObjcExceptionPreprocessor(this); - INITIALIZATION_STATE_SET_VALID(initialized_); - return true; - } - - void ProcessIntermediateDumps( - const std::map<std::string, std::string>& annotations, - const UserStreamDataSources* user_stream_sources) { - in_process_handler_.ProcessIntermediateDumps(annotations, - user_stream_sources); - } - - void ProcessIntermediateDump( - const base::FilePath& file, - const std::map<std::string, std::string>& annotations) { - in_process_handler_.ProcessIntermediateDump(file, annotations); - } - - void DumpWithoutCrash(NativeCPUContext* context, bool process_dump) { - INITIALIZATION_STATE_DCHECK_VALID(initialized_); - base::FilePath path; - if (!in_process_handler_.DumpExceptionFromSimulatedMachException( - context, kMachExceptionSimulated, &path)) { - return; - } - - if (process_dump) { - in_process_handler_.ProcessIntermediateDump(path); - } - } - - void DumpWithoutCrashAtPath(NativeCPUContext* context, - const base::FilePath& path) { - in_process_handler_.DumpExceptionFromSimulatedMachExceptionAtPath( - context, kMachExceptionSimulated, path); - } - - void StartProcessingPendingReports(UploadBehavior upload_behavior) { - INITIALIZATION_STATE_DCHECK_VALID(initialized_); - in_process_handler_.StartProcessingPendingReports(upload_behavior); - } - - void SetExceptionCallbackForTesting(void (*callback)()) { - in_process_handler_.SetExceptionCallbackForTesting(callback); - } - - uint64_t GetThreadIdForTesting() { return Thread::GetThreadIdForTesting(); } - - private: - CrashHandler() = default; - - ~CrashHandler() { - UninstallObjcExceptionPreprocessor(); - Signals::InstallDefaultHandler(SIGABRT); - UninstallMachExceptionHandler(); - } - - bool InstallMachExceptionHandler() { - mach_port_t exception_port = exception_port_.get(); - if (exception_port == MACH_PORT_NULL) { - return false; - } - - kern_return_t kr = mach_port_insert_right(mach_task_self(), - exception_port, - exception_port, - MACH_MSG_TYPE_MAKE_SEND); - if (kr != KERN_SUCCESS) { - MACH_LOG(ERROR, kr) << "mach_port_insert_right"; - return false; - } - - // TODO: Use SwapExceptionPort instead and put back EXC_MASK_BREAKPOINT. - // Until then, remove |EXC_MASK_BREAKPOINT| while attached to a debugger. - exception_mask_t mask = - ExcMaskAll() & - ~(EXC_MASK_EMULATION | EXC_MASK_SOFTWARE | EXC_MASK_RPC_ALERT | - EXC_MASK_GUARD | (IsBeingDebugged() ? EXC_MASK_BREAKPOINT : 0)); - - ExceptionPorts exception_ports(ExceptionPorts::kTargetTypeTask, TASK_NULL); - if (!exception_ports.GetExceptionPorts(mask, &original_handlers_) || - !exception_ports.SetExceptionPort( - mask, - exception_port, - EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, - MACHINE_THREAD_STATE)) { - return false; - } - - mach_handler_running_ = true; - Start(); - return true; - } - - void UninstallMachExceptionHandler() { - mach_handler_running_ = false; - exception_port_.reset(); - Join(); - } - - // Thread: - - void ThreadMain() override { - UniversalMachExcServer universal_mach_exc_server(this); - while (mach_handler_running_) { - mach_msg_return_t mr = - MachMessageServer::Run(&universal_mach_exc_server, - exception_port_.get(), - MACH_MSG_OPTION_NONE, - MachMessageServer::kPersistent, - MachMessageServer::kReceiveLargeIgnore, - kMachMessageTimeoutWaitIndefinitely); - MACH_CHECK( - mach_handler_running_ - ? mr == MACH_SEND_INVALID_DEST // This shouldn't happen for - // exception messages that come - // from the kernel itself, but if - // something else in-process sends - // exception messages and breaks, - // handle that case. - : (mr == MACH_RCV_PORT_CHANGED || // Port was closed while the - // thread was listening. - mr == MACH_RCV_INVALID_NAME), // Port was closed before the - // thread started listening. - mr) - << "MachMessageServer::Run"; - } - } - - // UniversalMachExcServer::Interface: - - kern_return_t CatchMachException(exception_behavior_t behavior, - exception_handler_t exception_port, - thread_t thread, - task_t task, - exception_type_t exception, - const mach_exception_data_type_t* code, - mach_msg_type_number_t code_count, - thread_state_flavor_t* flavor, - ConstThreadState old_state, - mach_msg_type_number_t old_state_count, - thread_state_t new_state, - mach_msg_type_number_t* new_state_count, - const mach_msg_trailer_t* trailer, - bool* destroy_complex_request) override { - *destroy_complex_request = true; - - // TODO(justincohen): Forward exceptions to original_handlers_ with - // UniversalExceptionRaise. - - // iOS shouldn't have any child processes, but just in case, those will - // inherit the task exception ports, and this process isn’t prepared to - // handle them - if (task != mach_task_self()) { - CRASHPAD_RAW_LOG("MachException task != mach_task_self()"); - return KERN_FAILURE; - } - - HandleMachException(behavior, - thread, - exception, - code, - code_count, - *flavor, - old_state, - old_state_count); - - // Respond with KERN_FAILURE so the system will continue to handle this - // exception. xnu will turn this Mach exception into a signal and take the - // default action to terminate the process. However, if sigprocmask is - // called before this Mach exception returns (such as by another thread - // calling abort, see: Libc-1506.40.4/stdlib/FreeBSD/abort.c), the Mach - // exception will be converted into a signal but delivery will be blocked. - // Since concurrent exceptions lead to the losing thread sleeping - // indefinitely, if the abort thread never returns, the thread that - // triggered this Mach exception will repeatedly trap and the process will - // never terminate. If the abort thread didn’t have a user-space signal - // handler that slept forever, the abort would terminate the process even if - // all other signals had been blocked. Instead, unblock all signals - // corresponding to all Mach exceptions Crashpad is registered for before - // returning KERN_FAILURE. There is still racy behavior possible with this - // call to sigprocmask, but the repeated calls to CatchMachException here - // will eventually lead to termination. - sigset_t unblock_set; - sigemptyset(&unblock_set); - sigaddset(&unblock_set, SIGILL); // EXC_BAD_INSTRUCTION - sigaddset(&unblock_set, SIGTRAP); // EXC_BREAKPOINT - sigaddset(&unblock_set, SIGFPE); // EXC_ARITHMETIC - sigaddset(&unblock_set, SIGBUS); // EXC_BAD_ACCESS - sigaddset(&unblock_set, SIGSEGV); // EXC_BAD_ACCESS - if (sigprocmask(SIG_UNBLOCK, &unblock_set, nullptr) != 0) { - CRASHPAD_RAW_LOG("sigprocmask"); - } - return KERN_FAILURE; - } - - void HandleMachException(exception_behavior_t behavior, - thread_t thread, - exception_type_t exception, - const mach_exception_data_type_t* code, - mach_msg_type_number_t code_count, - thread_state_flavor_t flavor, - ConstThreadState old_state, - mach_msg_type_number_t old_state_count) { - in_process_handler_.DumpExceptionFromMachException(behavior, - thread, - exception, - code, - code_count, - flavor, - old_state, - old_state_count); - } - - void HandleUncaughtNSException(const uint64_t* frames, - const size_t num_frames) override { - in_process_handler_.DumpExceptionFromNSExceptionWithFrames(frames, - num_frames); - // After uncaught exceptions are reported, the system immediately triggers a - // call to std::terminate()/abort(). Remove the abort handler so a second - // dump isn't generated. - CHECK(Signals::InstallDefaultHandler(SIGABRT)); - } - - void HandleUncaughtNSExceptionWithContext( - NativeCPUContext* context) override { - base::FilePath path; - in_process_handler_.DumpExceptionFromSimulatedMachException( - context, kMachExceptionFromNSException, &path); - - // After uncaught exceptions are reported, the system immediately triggers a - // call to std::terminate()/abort(). Remove the abort handler so a second - // dump isn't generated. - CHECK(Signals::InstallDefaultHandler(SIGABRT)); - } - - void HandleUncaughtNSExceptionWithContextAtPath( - NativeCPUContext* context, - const base::FilePath& path) override { - in_process_handler_.DumpExceptionFromSimulatedMachExceptionAtPath( - context, kMachExceptionFromNSException, path); - } - - bool MoveIntermediateDumpAtPathToPending( - const base::FilePath& path) override { - if (in_process_handler_.MoveIntermediateDumpAtPathToPending(path)) { - // After uncaught exceptions are reported, the system immediately triggers - // a call to std::terminate()/abort(). Remove the abort handler so a - // second dump isn't generated. - CHECK(Signals::InstallDefaultHandler(SIGABRT)); - return true; - } - return false; - } - - // The signal handler installed at OS-level. - static void CatchAndReraiseSignal(int signo, - siginfo_t* siginfo, - void* context) { - Get()->HandleAndReraiseSignal(signo, - siginfo, - reinterpret_cast<ucontext_t*>(context), - &(Get()->old_action_)); - } - - static void CatchAndReraiseSignalDefaultAction(int signo, - siginfo_t* siginfo, - void* context) { - Get()->HandleAndReraiseSignal( - signo, siginfo, reinterpret_cast<ucontext_t*>(context), nullptr); - } - - void HandleAndReraiseSignal(int signo, - siginfo_t* siginfo, - ucontext_t* context, - struct sigaction* old_action) { - in_process_handler_.DumpExceptionFromSignal(siginfo, context); - - // Always call system handler. - Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, old_action); - } - - ThreadSafeScopedMachPortWithReceiveRight exception_port_; - ExceptionPorts::ExceptionHandlerVector original_handlers_; - struct sigaction old_action_ = {}; - internal::InProcessHandler in_process_handler_; - static CrashHandler* instance_; - std::atomic<bool> mach_handler_running_ = false; - InitializationStateDcheck initialized_; -}; - -CrashHandler* CrashHandler::instance_ = nullptr; - -} // namespace - CrashpadClient::CrashpadClient() {} CrashpadClient::~CrashpadClient() {}
diff --git a/third_party/crashpad/crashpad/test/fuchsia_crashpad_tests.cml b/third_party/crashpad/crashpad/test/fuchsia_crashpad_tests.cml index d231f8f..bfcedb3 100644 --- a/third_party/crashpad/crashpad/test/fuchsia_crashpad_tests.cml +++ b/third_party/crashpad/crashpad/test/fuchsia_crashpad_tests.cml
@@ -1,6 +1,17 @@ -// Copyright 2022 The Fuchsia Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +// Copyright 2022 The Crashpad Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + { include: [ "//src/sys/test_runners/elf/ambient_exec.shard.cml",
diff --git a/third_party/crashpad/crashpad/test/ios/crash_type_xctest.mm b/third_party/crashpad/crashpad/test/ios/crash_type_xctest.mm index b6d1bff..330b9f6 100644 --- a/third_party/crashpad/crashpad/test/ios/crash_type_xctest.mm +++ b/third_party/crashpad/crashpad/test/ios/crash_type_xctest.mm
@@ -159,6 +159,7 @@ - (void)testTrap { [rootObject_ crashTrap]; +#if !BUILDFLAG(IS_IOS_TVOS) #if defined(ARCH_CPU_X86_64) [self verifyCrashReportException:EXC_BAD_INSTRUCTION]; #elif defined(ARCH_CPU_ARM64) @@ -166,6 +167,12 @@ #else #error Port to your CPU architecture #endif +#else // !BUILDFLAG(IS_IOS_TVOS) + [self verifyCrashReportException:EXC_SOFT_SIGNAL]; + NSNumber* report_exception; + XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]); + XCTAssertEqual(report_exception.intValue, SIGTRAP); +#endif } - (void)testAbort { @@ -178,7 +185,14 @@ - (void)testBadAccess { [rootObject_ crashBadAccess]; +#if !BUILDFLAG(IS_IOS_TVOS) [self verifyCrashReportException:EXC_BAD_ACCESS]; +#else + [self verifyCrashReportException:EXC_SOFT_SIGNAL]; + NSNumber* report_exception; + XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]); + XCTAssertEqual(report_exception.intValue, SIGSEGV); +#endif } - (void)testException { @@ -250,7 +264,14 @@ - (void)testCatchUIGestureEnvironmentNSException { // Tap the button with the string UIGestureEnvironmentException. +#if !BUILDFLAG(IS_IOS_TVOS) [app_.buttons[@"UIGestureEnvironmentException"] tap]; +#else + // tvOS does not have [XCUIElement tap]. This version assumes there is just + // one big button with "UIGestureEnvironmentException" as title, so we can + // just press Select on the remote to activate it. + [XCUIRemote.sharedRemote pressButton:XCUIRemoteButtonSelect]; +#endif [self verifyCrashReportException:crashpad::kMachExceptionFromNSException]; NSDictionary* dict = [rootObject_ getAnnotations]; XCTAssertTrue([[dict[@"objects"][0] valueForKeyPath:@"exceptionReason"] @@ -280,10 +301,21 @@ isEqualToString:@"NSGenericException"]); } +// This test cannot run correctly on tvOS: it is impossible to catch this stack +// overflow as a Mach exception (like we do on iOS), and sigaltstack() is also +// forbidden so we cannot detect it with POSIX signals either. +// Per xnu-11215.81.4/bsd/uxkern/ux_exception.c's handle_ux_exception(), when a +// stack overflow is detected but no alternate stack is specified, the kernel +// will reset SIGSEGV to SIG_DFL before delivering the signal, so we are never +// able to capture this crash. Even if we do pass SA_ONSTACK to sigaction(), we +// will just crash a bit later, as we are still using the same stack that has +// already overflown. +#if !BUILDFLAG(IS_IOS_TVOS) - (void)testRecursion { [rootObject_ crashRecursion]; [self verifyCrashReportException:EXC_BAD_ACCESS]; } +#endif - (void)testClientAnnotations { [rootObject_ crashKillAbort];
diff --git a/third_party/crashpad/crashpad/third_party/edo/BUILD.gn b/third_party/crashpad/crashpad/third_party/edo/BUILD.gn index aac3e87..9744cbc98 100644 --- a/third_party/crashpad/crashpad/third_party/edo/BUILD.gn +++ b/third_party/crashpad/crashpad/third_party/edo/BUILD.gn
@@ -1,6 +1,16 @@ -# Copyright 2018 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Copyright 2025 The Crashpad Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import("../../build/crashpad_buildconfig.gni")
diff --git a/third_party/crashpad/crashpad/third_party/ninja/ninja b/third_party/crashpad/crashpad/third_party/ninja/ninja index 402ab2a1..ca087460 100755 --- a/third_party/crashpad/crashpad/third_party/ninja/ninja +++ b/third_party/crashpad/crashpad/third_party/ninja/ninja
@@ -1,8 +1,18 @@ #!/bin/sh -# Copyright 2022 Google Inc. All rights reserved -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. +# Copyright 2022 The Crashpad Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. set -eu
diff --git a/third_party/crashpad/crashpad/util/BUILD.gn b/third_party/crashpad/crashpad/util/BUILD.gn index 1bb36a4..31eb3d7 100644 --- a/third_party/crashpad/crashpad/util/BUILD.gn +++ b/third_party/crashpad/crashpad/util/BUILD.gn
@@ -19,7 +19,7 @@ import("//build/config/sanitizers/sanitizers.gni") } -if (crashpad_is_apple) { +if (crashpad_is_apple && !crashpad_is_tvos) { if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) { import("//build/config/sysroot.gni") } else { @@ -334,29 +334,37 @@ "mac/sysctl.h", "mac/xattr.cc", "mac/xattr.h", - "mach/composite_mach_message_server.cc", - "mach/composite_mach_message_server.h", - "mach/exc_client_variants.cc", - "mach/exc_client_variants.h", - "mach/exc_server_variants.cc", - "mach/exc_server_variants.h", - "mach/exception_behaviors.cc", - "mach/exception_behaviors.h", - "mach/exception_ports.cc", - "mach/exception_ports.h", "mach/mach_extensions.cc", "mach/mach_extensions.h", - "mach/mach_message.cc", - "mach/mach_message.h", - "mach/mach_message_server.cc", - "mach/mach_message_server.h", - "mach/symbolic_constants_mach.cc", - "mach/symbolic_constants_mach.h", "misc/capture_context_mac.S", "misc/clock_mac.cc", "misc/paths_mac.cc", "synchronization/semaphore_mac.cc", ] + + # Exclude files related to Mach exceptions when building for tvOS. Mach + # messaging APIs are not available to third-party applications on tvOS so + # crashes are handled via POSIX signals. + if (!crashpad_is_tvos) { + sources += [ + "mach/composite_mach_message_server.cc", + "mach/composite_mach_message_server.h", + "mach/exc_client_variants.cc", + "mach/exc_client_variants.h", + "mach/exc_server_variants.cc", + "mach/exc_server_variants.h", + "mach/exception_behaviors.cc", + "mach/exception_behaviors.h", + "mach/exception_ports.cc", + "mach/exception_ports.h", + "mach/mach_message.cc", + "mach/mach_message.h", + "mach/mach_message_server.cc", + "mach/mach_message_server.h", + "mach/symbolic_constants_mach.cc", + "mach/symbolic_constants_mach.h", + ] + } } if (crashpad_is_mac && !crashpad_is_in_fuchsia) { @@ -593,10 +601,11 @@ if (crashpad_is_apple) { include_dirs += [ "$root_gen_dir" ] - deps += [ - ":mig_output", - "../build:apple_enable_arc", - ] + deps += [ "../build:apple_enable_arc" ] + + if (!crashpad_is_tvos) { + deps += [ ":mig_output" ] + } } if (crashpad_is_mac && !crashpad_is_in_fuchsia) { @@ -823,14 +832,19 @@ if (crashpad_is_apple) { sources += [ "mac/xattr_test.cc", - "mach/composite_mach_message_server_test.cc", - "mach/exc_server_variants_test.cc", - "mach/exception_behaviors_test.cc", - "mach/mach_extensions_test.cc", - "mach/mach_message_test.cc", - "mach/symbolic_constants_mach_test.cc", "misc/capture_context_test_util_mac.cc", ] + + if (!crashpad_is_tvos) { + sources += [ + "mach/composite_mach_message_server_test.cc", + "mach/exc_server_variants_test.cc", + "mach/exception_behaviors_test.cc", + "mach/mach_extensions_test.cc", + "mach/mach_message_test.cc", + "mach/symbolic_constants_mach_test.cc", + ] + } } if (crashpad_is_mac) {
diff --git a/third_party/crashpad/crashpad/util/posix/signals.cc b/third_party/crashpad/crashpad/util/posix/signals.cc index e24bb60..58f957c 100644 --- a/third_party/crashpad/crashpad/util/posix/signals.cc +++ b/third_party/crashpad/crashpad/util/posix/signals.cc
@@ -278,14 +278,8 @@ } // static -void Signals::RestoreHandlerAndReraiseSignalOnReturn( - const siginfo_t* siginfo, - const struct sigaction* old_action) { - // Failures in this function should _exit(kFailureExitCode). This is a quick - // and quiet failure. This function runs in signal handler context, and it’s - // difficult to safely be loud from a signal handler. - constexpr int kFailureExitCode = 191; - +bool Signals::RestoreOrResetHandler(int sig, + const struct sigaction* old_action) { struct sigaction default_action; sigemptyset(&default_action.sa_mask); default_action.sa_flags = 0; @@ -297,9 +291,25 @@ // Try to restore restore_action. If that fails and restore_action was // old_action, the problem may have been that old_action was bogus, so try to // set the default action. - const int sig = siginfo->si_signo; if (sigaction(sig, restore_action, nullptr) != 0 && old_action && sigaction(sig, &default_action, nullptr) != 0) { + return false; + } + return true; +} + +// static +void Signals::RestoreHandlerAndReraiseSignalOnReturn( + const siginfo_t* siginfo, + const struct sigaction* old_action) { + // Failures in this function should _exit(kFailureExitCode). This is a quick + // and quiet failure. This function runs in signal handler context, and it’s + // difficult to safely be loud from a signal handler. + constexpr int kFailureExitCode = 191; + + const int sig = siginfo->si_signo; + + if (!RestoreOrResetHandler(sig, old_action)) { _exit(kFailureExitCode); }
diff --git a/third_party/crashpad/crashpad/util/posix/signals.h b/third_party/crashpad/crashpad/util/posix/signals.h index e12ad72b..934b312 100644 --- a/third_party/crashpad/crashpad/util/posix/signals.h +++ b/third_party/crashpad/crashpad/util/posix/signals.h
@@ -196,6 +196,24 @@ //! \note This function is safe to call from a signal handler. static bool WillSignalReraiseAutonomously(const siginfo_t* siginfo); + //! \brief Restores a previous signal action or reinstalls the default signal + //! handler for a given signal. + //! + //! Attempts to reinstate the action given by \a old_action and, in case of + //! failure or if \a old_actiono is `nullptr`, resets the handler for \a sig + //! to the default action. + //! + //! \param[in] sig The signal to manage. + //! \param[in] old_action The previous action for the signal, which will be + //! re-established as the signal’s action. May be `nullptr`, which directs + //! the default action for the signal to be used. + //! + //! \return `true` on success, `false` if `sigaction()` fails. + //! + //! \note This function is safe to call from a signal handler. + static bool RestoreOrResetHandler(int sig, + const struct sigaction* old_action); + //! \brief Restores a previous signal action and arranges to re-raise a signal //! on return from a signal handler. //!
diff --git a/third_party/dawn b/third_party/dawn index 3ae10bb..e9424a0 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit 3ae10bb874bd495b9334b42a1c1bddec00ec53cb +Subproject commit e9424a009a62bacb7ba8e027bf7c8c3de4fb19d9
diff --git a/third_party/depot_tools b/third_party/depot_tools index a9cc320..c273e3e 160000 --- a/third_party/depot_tools +++ b/third_party/depot_tools
@@ -1 +1 @@ -Subproject commit a9cc320bf761323906c614f7040cb1dc22fcc858 +Subproject commit c273e3eb6202ef710a9cbf48fc99437a56a13631
diff --git a/third_party/llvm-libc/src b/third_party/llvm-libc/src index 27ee073..9aefa1c 160000 --- a/third_party/llvm-libc/src +++ b/third_party/llvm-libc/src
@@ -1 +1 @@ -Subproject commit 27ee0730164e6f101985f057c6ad23a9ba7710f6 +Subproject commit 9aefa1cede964571c0b0ef41460cc5c3bbc6b4b8
diff --git a/third_party/ml_dtypes/BUILD.gn b/third_party/ml_dtypes/BUILD.gn new file mode 100644 index 0000000..de8771f --- /dev/null +++ b/third_party/ml_dtypes/BUILD.gn
@@ -0,0 +1,29 @@ +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/sanitizers/sanitizers.gni") + +config("ml_dtypes-includes") { + include_dirs = [ + "src", + "src/ml_dtypes", + ] +} + +static_library("ml_dtypes") { + sources = [ + "src/ml_dtypes/include/float8.h", + "src/ml_dtypes/include/intn.h", + "src/ml_dtypes/include/mxfloat.h", + ] + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ + ":ml_dtypes-includes", + "//build/config/compiler:no_chromium_code", + "//third_party/eigen3:eigen_includes", + ] + + public_configs = [ ":ml_dtypes-includes" ] +}
diff --git a/third_party/ml_dtypes/DEPS b/third_party/ml_dtypes/DEPS new file mode 100644 index 0000000..2fdad449 --- /dev/null +++ b/third_party/ml_dtypes/DEPS
@@ -0,0 +1,4 @@ +# checkdeps.py shouldn't check include paths for files in these dirs: +skip_child_includes = [ + 'src', +]
diff --git a/third_party/ml_dtypes/DIR_METADATA b/third_party/ml_dtypes/DIR_METADATA new file mode 100644 index 0000000..c23828c --- /dev/null +++ b/third_party/ml_dtypes/DIR_METADATA
@@ -0,0 +1,6 @@ +monorail: { + component: "Internals>OptimizationGuide" +} +buganizer_public: { + component_id: 1456757 +}
diff --git a/third_party/ml_dtypes/OWNERS b/third_party/ml_dtypes/OWNERS new file mode 100644 index 0000000..a3ecffc6f --- /dev/null +++ b/third_party/ml_dtypes/OWNERS
@@ -0,0 +1 @@ +file://third_party/tflite/OWNERS
diff --git a/third_party/ml_dtypes/README.chromium b/third_party/ml_dtypes/README.chromium new file mode 100644 index 0000000..eaf45581 --- /dev/null +++ b/third_party/ml_dtypes/README.chromium
@@ -0,0 +1,19 @@ +Name: ml_dtypes +Short Name: ml_dtypes +URL: https://github.com/jax-ml/ml_dtypes +Version: 57e857e85df34d463f2c778810dc4b876750c5e0 +Date: 2025-05-07 +License: Apache-2.0 +License File: src/LICENSE +Security Critical: Yes +Shipped: yes +CPEPrefix: unknown + +Description: +ml_dtypes is a stand-alone implementation of several NumPy dtype extensions used +in machine learning libraries. + +Local Modifications: +Only a portion of the upstream library is copied here, namely the include +headers which serve as glue code between TFLite and Eigen. See also update.sh +in this directory.
diff --git a/third_party/ml_dtypes/src/LICENSE b/third_party/ml_dtypes/src/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/third_party/ml_dtypes/src/LICENSE
@@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
diff --git a/third_party/ml_dtypes/src/ml_dtypes/include/float8.h b/third_party/ml_dtypes/src/ml_dtypes/include/float8.h new file mode 100644 index 0000000..7696c05 --- /dev/null +++ b/third_party/ml_dtypes/src/ml_dtypes/include/float8.h
@@ -0,0 +1,1843 @@ +/* Copyright 2022 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef ML_DTYPES_FLOAT8_H_ +#define ML_DTYPES_FLOAT8_H_ + +// 8-bit Floating Point Interchange Format, as described by +// https://arxiv.org/abs/2209.05433 +// https://www.opencompute.org/documents/ocp-8-bit-floating-point-specification-ofp8-revision-1-0-2023-12-01-pdf-1 +// https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf + +#include <algorithm> +#include <climits> +#include <cmath> +#include <cstdint> +#include <limits> +#include <ostream> +#include <type_traits> +#include <utility> + +#ifdef __has_include +#if __has_include(<version>) +#include <version> +#endif +#endif + +#if (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L) +#include <bit> +#endif + +#include "Eigen/Core" + +namespace ml_dtypes { +namespace float8_internal { + +// Forward-declarations of classes. +class float8_e3m4; +class float8_e4m3; +class float8_e4m3fn; +class float8_e4m3fnuz; +class float8_e4m3b11fnuz; +class float8_e5m2; +class float8_e5m2fnuz; +class float8_e8m0fnu; + +template <typename Derived> +class float8_base { + protected: + // Constructor tag to allow constexpr construction from bit representation. + struct ConstructFromRepTag {}; + constexpr float8_base(uint8_t rep, ConstructFromRepTag) : rep_{rep} {} + + public: + static constexpr int kBits = 8; + constexpr float8_base() : rep_(0) {} + + template <typename T> + explicit EIGEN_DEVICE_FUNC float8_base( + T i, std::enable_if_t<std::is_integral_v<T>, int> = 0) + : float8_base(ConvertFrom(static_cast<float>(i)).rep(), + ConstructFromRepTag{}) {} + template <typename T> + explicit EIGEN_DEVICE_FUNC float8_base( + T f, std::enable_if_t<std::is_floating_point_v<T>, int> = 0) + : float8_base(ConvertFrom(f).rep(), ConstructFromRepTag{}) {} + explicit EIGEN_DEVICE_FUNC float8_base(Eigen::bfloat16 bf16) + : float8_base(ConvertFrom(bf16).rep(), ConstructFromRepTag{}) {} + explicit EIGEN_DEVICE_FUNC float8_base(Eigen::half f16) + : float8_base(ConvertFrom(f16).rep(), ConstructFromRepTag{}) {} + + constexpr uint8_t rep() const { return rep_; } + + template <typename T, + typename EnableIf = std::enable_if<std::is_arithmetic_v<T>>> + explicit EIGEN_DEVICE_FUNC operator T() const { + return static_cast<T>(static_cast<float>(derived())); + } + explicit EIGEN_DEVICE_FUNC operator double() const { + return ConvertTo<double>(derived()); + } + EIGEN_DEVICE_FUNC operator float() const { + return ConvertTo<float>(derived()); + } + EIGEN_DEVICE_FUNC operator Eigen::bfloat16() const { + return ConvertTo<Eigen::bfloat16>(derived()); + } + EIGEN_DEVICE_FUNC operator Eigen::half() const { + return ConvertTo<Eigen::half>(derived()); + } + explicit EIGEN_DEVICE_FUNC operator bool() const { + return (rep() & 0x7F) != 0; + } + + constexpr Derived operator-() const { + return Derived(static_cast<uint8_t>(rep() ^ 0x80), ConstructFromRepTag{}); + } + + constexpr const Derived& derived() const { + return *static_cast<const Derived*>(this); + } + + constexpr Derived& derived() { return *static_cast<Derived*>(this); } + + static constexpr Derived FromRep(uint8_t rep) { + return Derived(rep, ConstructFromRepTag{}); + } + + // Conversions allowing saturation and truncation. + template <bool kSaturate = false, bool kTruncate = false, typename From> + static inline EIGEN_DEVICE_FUNC Derived ConvertFrom(From from); + + template <typename To, bool kSaturate = false, bool kTruncate = false> + static inline EIGEN_DEVICE_FUNC To ConvertTo(Derived from); + + // Operators via float32. + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Derived + operator+(const Derived& other) const { + return Derived{float{derived()} + float{other}}; + } + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Derived + operator-(const Derived& other) const { + return Derived{float{derived()} - float{other}}; + } + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Derived + operator*(const Derived& other) const { + return Derived{float{derived()} * float{other}}; + } + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Derived + operator/(const Derived& other) const { + return Derived{float{derived()} / float{other}}; + } + + constexpr bool operator==(const Derived& other) const { + return Compare(derived(), other) == Ordering::kEquivalent; + } + + constexpr bool operator!=(const Derived& other) const { + return Compare(derived(), other) != Ordering::kEquivalent; + } + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator<( + const Derived& other) const { + return Compare(derived(), other) == Ordering::kLess; + } + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator<=( + const Derived& other) const { + return Compare(derived(), other) <= Ordering::kEquivalent; + } + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator>( + const Derived& other) const { + return Compare(derived(), other) == Ordering::kGreater; + } + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator>=( + const Derived& other) const { + Ordering ordering = Compare(derived(), other); + return ordering == Ordering::kGreater || ordering == Ordering::kEquivalent; + } + + // Compound assignment. + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Derived& operator+=( + const Derived& other) { + derived() = derived() + other; + return derived(); + } + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Derived& operator-=( + const Derived& other) { + derived() = derived() - other; + return derived(); + } + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Derived& operator*=( + const Derived& other) { + derived() = derived() * other; + return derived(); + } + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Derived& operator/=( + const Derived& other) { + derived() = derived() / other; + return derived(); + } + + private: + static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC std::pair<uint8_t, uint8_t> + SignAndMagnitude(Derived x) { + const uint8_t x_abs_bits = + Eigen::numext::bit_cast<uint8_t>(Eigen::numext::abs(x)); + const uint8_t x_bits = Eigen::numext::bit_cast<uint8_t>(x); + const uint8_t x_sign = (x_bits ^ x_abs_bits) << (CHAR_BIT - Derived::kBits); + return {x_sign, x_abs_bits}; + } + static EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC int8_t + SignAndMagnitudeToTwosComplement(uint8_t sign, uint8_t magnitude) { + return magnitude ^ (static_cast<int8_t>(sign) < 0 ? -1 : 0); + } + + enum Ordering : int8_t { + kLess = -1, + kEquivalent = 0, + kGreater = 1, + kUnordered = 2, + }; + + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC friend Ordering Compare( + const Derived& lhs, const Derived& rhs) { + if (Eigen::numext::isnan(lhs) || Eigen::numext::isnan(rhs)) { + return Ordering::kUnordered; + } + auto [lhs_sign, lhs_mag] = SignAndMagnitude(lhs); + auto [rhs_sign, rhs_mag] = SignAndMagnitude(rhs); + if (lhs_mag == 0 && rhs_mag == 0) { + return Ordering::kEquivalent; + } + int8_t lhs_twos_complement = + SignAndMagnitudeToTwosComplement(lhs_sign, lhs_mag); + int8_t rhs_twos_complement = + SignAndMagnitudeToTwosComplement(rhs_sign, rhs_mag); + if (lhs_twos_complement < rhs_twos_complement) { + return Ordering::kLess; + } + if (lhs_twos_complement > rhs_twos_complement) { + return Ordering::kGreater; + } + return Ordering::kEquivalent; + } + + uint8_t rep_; +}; + +template <typename T> +using RequiresIsDerivedFromFloat8Base = + std::enable_if_t<std::is_base_of_v<float8_base<T>, T>, int>; + +class float8_e3m4 : public float8_base<float8_e3m4> { + // Exponent: 3, Mantissa: 4, bias: 3. + // IEEE 754. + private: + using Base = float8_base<float8_e3m4>; + friend class float8_base<float8_e3m4>; + using Base::Base; + + public: + template <typename T, RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float8_e3m4(T f8) : float8_e3m4(ConvertFrom(f8)) {} +}; + +class float8_e4m3 : public float8_base<float8_e4m3> { + // Exponent: 4, Mantissa: 3, bias: 7. + // IEEE 754. + private: + using Base = float8_base<float8_e4m3>; + friend class float8_base<float8_e4m3>; + using Base::Base; + + public: + template <typename T, RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float8_e4m3(T f8) : float8_e4m3(ConvertFrom(f8)) {} +}; + +class float8_e4m3fn : public float8_base<float8_e4m3fn> { + // Exponent: 4, Mantissa: 3, bias: 7. + // Extended range: no inf, NaN represented by 0bS111'1111. + // The "fn" suffix is for consistency with the corresponding LLVM/MLIR type, + // signaling this type is not consistent with IEEE-754. The "f" indicates + // it is finite values only. The "n" indicates it includes NaNs, but only + // at the outer range. + private: + using Base = float8_base<float8_e4m3fn>; + friend class float8_base<float8_e4m3fn>; + using Base::Base; + + public: + template <typename T, RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float8_e4m3fn(T f8) + : float8_e4m3fn(ConvertFrom(f8)) {} +}; + +class float8_e4m3b11fnuz : public float8_base<float8_e4m3b11fnuz> { + // Exponent: 4, Mantissa: 3, bias: 11. + // Extended range: no inf, NaN represented by 0b1000'0000. + private: + using Base = float8_base<float8_e4m3b11fnuz>; + friend class float8_base<float8_e4m3b11fnuz>; + using Base::Base; + + public: + template <typename T, RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float8_e4m3b11fnuz(T f8) + : float8_e4m3b11fnuz(ConvertFrom(f8)) {} + + constexpr float8_e4m3b11fnuz operator-() const { + if ((rep() & 0x7f) == 0x00) { + return *this; + } + return Base::operator-(); + } + + float8_e4m3b11fnuz operator-(const float8_e4m3b11fnuz& other) const { + return Base::operator-(other); + } + + explicit EIGEN_DEVICE_FUNC operator bool() const { return rep() != 0; } +}; + +// Legacy name used in XLA (TODO(jewillco): remove). +using float8_e4m3b11 = float8_e4m3b11fnuz; + +class float8_e4m3fnuz : public float8_base<float8_e4m3fnuz> { + // 8-bit floating point with 3 bit mantissa. + // + // An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits + // mantissa. The suffix "fnuz" is consistent with LLVM/MLIR naming and is + // derived from the differences to IEEE floating point conventions. `F` is + // for "finite" (no infinities), `N` for with special NaN encoding, `UZ` for + // unsigned zero. + // + // This type has the following characteristics: + // * bit encoding: S1E4M3 - `0bSEEEEMMM` + // * exponent bias: 8 + // * infinities: Not supported + // * NaNs: Supported with sign bit set to 1, exponent bits and mantissa bits + // set to all 0s - `0b10000000` + // * denormals when exponent is 0 + private: + using Base = float8_base<float8_e4m3fnuz>; + friend class float8_base<float8_e4m3fnuz>; + using Base::Base; + + public: + template <typename T, RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float8_e4m3fnuz(T f8) + : float8_e4m3fnuz(ConvertFrom(f8)) {} + + constexpr float8_e4m3fnuz operator-() const { + if ((rep() & 0x7f) == 0x00) { + return *this; + } + return Base::operator-(); + } + + float8_e4m3fnuz operator-(const float8_e4m3fnuz& other) const { + return Base::operator-(other); + } + + explicit EIGEN_DEVICE_FUNC operator bool() const { return rep() != 0; } +}; + +class float8_e5m2 : public float8_base<float8_e5m2> { + // Exponent: 5, Mantissa: 2, bias: 15. + // IEEE 754. + private: + using Base = float8_base<float8_e5m2>; + friend class float8_base<float8_e5m2>; + using Base::Base; + + public: + template <typename T, RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float8_e5m2(T f8) : float8_e5m2(ConvertFrom(f8)) {} +}; + +class float8_e5m2fnuz : public float8_base<float8_e5m2fnuz> { + // 8-bit floating point with 2 bit mantissa. + // + // An 8-bit floating point type with 1 sign bit, 5 bits exponent and 2 bits + // mantissa. The suffix "fnuz" is consistent with LLVM/MLIR naming and is + // derived from the differences to IEEE floating point conventions. `F` is + // for "finite" (no infinities), `N` for with special NaN encoding, `UZ` for + // unsigned zero. + // + // This type has the following characteristics: + // * bit encoding: S1E5M2 - `0bSEEEEEMM` + // * exponent bias: 16 + // * infinities: Not supported + // * NaNs: Supported with sign bit set to 1, exponent bits and mantissa bits + // set to all 0s - `0b10000000` + // * denormals when exponent is 0 + private: + using Base = float8_base<float8_e5m2fnuz>; + friend class float8_base<float8_e5m2fnuz>; + using Base::Base; + + public: + template <typename T, RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float8_e5m2fnuz(T f8) + : float8_e5m2fnuz(ConvertFrom(f8)) {} + + constexpr float8_e5m2fnuz operator-() const { + if ((rep() & 0x7f) == 0x00) { + return *this; + } + return Base::operator-(); + } + + float8_e5m2fnuz operator-(const float8_e5m2fnuz& other) const { + return Base::operator-(other); + } + + explicit EIGEN_DEVICE_FUNC operator bool() const { return rep() != 0; } +}; + +class float8_e8m0fnu : public float8_base<float8_e8m0fnu> { + // 8-bit floating point with 8 bit exponent, no sign and zero mantissa. + // + // See: + // https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf + // + // An 8-bit floating point type with no sign bit, 8 bits exponent and 0 bits + // mantissa. The suffix "fnuz" is consistent with LLVM/MLIR naming and is + // derived from the differences to IEEE floating point conventions. `F` is + // for "finite" (no infinities), `N` for with special NaN encoding, `U` for + // unsigned. + // + // This type has the following characteristics: + // * bit encoding: S0E8M0 - `0bEEEEEEEE` + // * exponent bias: 127 + // * infinities: Not supported + // * NaNs: Supported with exponent bits set to 1s - `0b11111111` + private: + using Base = float8_base<float8_e8m0fnu>; + friend class float8_base<float8_e8m0fnu>; + using Base::Base; + + public: + template <typename T, RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float8_e8m0fnu(T f8) + : float8_e8m0fnu(ConvertFrom(f8)) {} + + constexpr float8_e8m0fnu operator-() const { + // No negative numbers supported in E8M0 => NaN + return float8_e8m0fnu::FromRep(0xFF); + } + + float8_e8m0fnu operator-(const float8_e8m0fnu& other) const { + return Base::operator-(other); + } + + explicit EIGEN_DEVICE_FUNC operator bool() const { + // No zero supported in E8M0 format. + return true; + } + + // Comparison simplified to uint8_t compare. + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator<( + const float8_e8m0fnu& other) const { + if (Eigen::numext::isnan(*this) || Eigen::numext::isnan(other)) { + return false; + } + return rep() < other.rep(); + } + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator<=( + const float8_e8m0fnu& other) const { + if (Eigen::numext::isnan(*this) || Eigen::numext::isnan(other)) { + return false; + } + return rep() <= other.rep(); + } + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator>( + const float8_e8m0fnu& other) const { + if (Eigen::numext::isnan(*this) || Eigen::numext::isnan(other)) { + return false; + } + return rep() > other.rep(); + } + EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator>=( + const float8_e8m0fnu& other) const { + if (Eigen::numext::isnan(*this) || Eigen::numext::isnan(other)) { + return false; + } + return rep() >= other.rep(); + } +}; + +constexpr double ConstexprAbs(double x) { return x < 0.0 ? -x : x; } + +constexpr double ConstexprCeil(double x) { + constexpr double kIntegerThreshold = + uint64_t{1} << (std::numeric_limits<double>::digits - 1); + // Too big or NaN inputs get returned unchanged. + if (!(ConstexprAbs(x) < kIntegerThreshold)) { + return x; + } + const double x_trunc = static_cast<double>(static_cast<int64_t>(x)); + return x_trunc < x ? x_trunc + 1.0 : x_trunc; +} + +constexpr double ConstexprFloor(double x) { return -ConstexprCeil(-x); } + +constexpr double kLog10Of2 = 0.3010299956639812; +// C17 5.2.4.2.2p11: +// "number of decimal digits, q, such that any floating-point number with q +// decimal digits can be rounded into a floating-point number with p radix b +// digits and back again without change to the q decimal digits" +// floor((p - 1) * log10(2)); +constexpr int Digits10FromDigits(int digits) { + return static_cast<int>(ConstexprFloor((digits - 1) * kLog10Of2)); +} + +// C17 5.2.4.2.2p11: +// "number of decimal digits, n, such that any floating-point number with p +// radix b digits can be rounded to a floating-point number with n decimal +// digits and back again without change to the value" +// ceil(1 + p * log10(2)); +constexpr int MaxDigits10FromDigits(int digits) { + return static_cast<int>(ConstexprCeil(1.0 + (digits * kLog10Of2))); +} + +// C17 5.2.4.2.2p11: +// "minimum negative integer such that 10 raised to that power is in the range +// of normalized floating-point numbers" +// ceil(log10(2**(emin - 1))) == ceil((emin - 1) * log10(2)); +constexpr int MinExponent10FromMinExponent(int min_exponent) { + return static_cast<int>(ConstexprCeil((min_exponent - 1) * kLog10Of2)); +} + +// C17 5.2.4.2.2p11: +// "maximum integer such that 10 raised to that power is in the range of +// representable finite floating-point numbers" +// floor(log10((1 - 2**-p) * 2**emax)) == floor(log10(1 - 2**-p) + +// emax * log10(2)) +constexpr int MaxExponent10FromMaxExponentAndDigits(int max_exponent, + int digits) { + // We only support digits in {1,2,3,4,5}. This table would grow if we wanted + // to handle more values. + constexpr double kLog10OfOnePredecessor[] = { + // log10(1 - 2**-1) + -0.3010299956639812, + // log10(1 - 2**-2) + -0.12493873660829993, + // log10(1 - 2**-3) + -0.057991946977686754, + // log10(1 - 2**-4) + -0.028028723600243537, + // log10(1 - 2**-5) + -0.013788284485633295, + }; + return static_cast<int>(ConstexprFloor(kLog10OfOnePredecessor[digits - 1] + + max_exponent * kLog10Of2)); +} + +// Structures for use in specializing std::numeric_limits. +struct numeric_limits_float8_base { + // NOLINTBEGIN: these names must match std::numeric_limits. + static inline constexpr const bool is_specialized = true; + static inline constexpr const bool is_signed = true; + static inline constexpr const bool is_integer = false; + static inline constexpr const bool is_exact = false; + static inline constexpr const bool has_quiet_NaN = true; + static inline constexpr const std::float_denorm_style has_denorm = + std::denorm_present; + static inline constexpr const bool has_denorm_loss = false; + static inline constexpr const std::float_round_style round_style = + std::round_to_nearest; + static inline constexpr const bool is_bounded = true; + static inline constexpr const bool is_modulo = false; + static inline constexpr const int radix = std::numeric_limits<float>::radix; + static inline constexpr const bool traps = std::numeric_limits<float>::traps; + static inline constexpr const bool tinyness_before = + std::numeric_limits<float>::tinyness_before; + // NOLINTEND +}; + +struct numeric_limits_float8_e3m4 : public numeric_limits_float8_base { + private: + static inline constexpr const int kExponentBias = 3; + static inline constexpr const int kMantissaBits = 4; + + public: + // NOLINTBEGIN: these names must match std::numeric_limits. + static inline constexpr const int digits = kMantissaBits + 1; + static inline constexpr const int digits10 = Digits10FromDigits(digits); + static inline constexpr const int max_digits10 = + MaxDigits10FromDigits(digits); + static inline constexpr const int min_exponent = (1 - kExponentBias) + 1; + static inline constexpr const int min_exponent10 = + MinExponent10FromMinExponent(min_exponent); + static inline constexpr const int max_exponent = 0b111 - kExponentBias; + static inline constexpr const int max_exponent10 = + MaxExponent10FromMaxExponentAndDigits(max_exponent, digits); + static inline constexpr const bool is_iec559 = true; + static inline constexpr const bool has_infinity = true; + static inline constexpr const bool has_signaling_NaN = true; + // NOLINTEND + + // 1.0 * 2^(0b001 - 3) = 1.0 * 2^-2 = 1/4 (min normal) + static constexpr float8_e3m4 min() { + return float8_e3m4::FromRep(1 << kMantissaBits); + } + // -(1 + 0b1111 * 2^-2) * 2^(0b110 - 3) = -(1 + 15/16) * 2^3 = -15.5 + static constexpr float8_e3m4 lowest() { + return float8_e3m4::FromRep(0b1'110'1111); + } + // (1 + 0b1111 * 2^-2) * 2^(0b110 - 3) = (1 + 15/16) * 2^3 = 15.5 + static constexpr float8_e3m4 max() { + return float8_e3m4::FromRep(0b0'110'1111); + } + // (1 + 1/16) * 2^0 - 1.0 = 1.0 + 1/16 - 1.0 = 1/16 + // Encoded as denormal number 2^-2 * 1/4 + static constexpr float8_e3m4 epsilon() { + return float8_e3m4::FromRep(0b0'000'0100); + } + // 1.0 * 2^-1 = 0.5 + static constexpr float8_e3m4 round_error() { + return float8_e3m4::FromRep((-1 + kExponentBias) << kMantissaBits); + } + static constexpr float8_e3m4 infinity() { + return float8_e3m4::FromRep(0b0'111'0000); + } + static constexpr float8_e3m4 quiet_NaN() { + // IEEE 754-2019 6.2.1: "All binary NaN bit strings have the sign bit S set + // to 0 or 1 and all the bits of the biased exponent field E set to 1 + // (see 3.4). A quiet NaN bit string should be encoded with the first bit + // (d1) of the trailing significand field T being 1." + return float8_e3m4::FromRep(0b0'111'1000); + } + static constexpr float8_e3m4 signaling_NaN() { + // IEEE 754-2019 6.2.1: "A signaling NaN bit string should be encoded with + // the first bit of the trailing significand field being 0." + return float8_e3m4::FromRep(0b0'111'0100); + } + // 2^(-2) * 2^(-4) = 2^-6 = 1/64 (min denormal) + static constexpr float8_e3m4 denorm_min() { + return float8_e3m4::FromRep(0b0'000'0001); + } +}; + +struct numeric_limits_float8_e4m3 : public numeric_limits_float8_base { + private: + static inline constexpr const int kExponentBias = 7; + static inline constexpr const int kMantissaBits = 3; + + public: + // NOLINTBEGIN: these names must match std::numeric_limits. + static inline constexpr const int digits = kMantissaBits + 1; + static inline constexpr const int digits10 = Digits10FromDigits(digits); + static inline constexpr const int max_digits10 = + MaxDigits10FromDigits(digits); + static inline constexpr const int min_exponent = (1 - kExponentBias) + 1; + static inline constexpr const int min_exponent10 = + MinExponent10FromMinExponent(min_exponent); + static inline constexpr const int max_exponent = 0b1111 - kExponentBias; + static inline constexpr const int max_exponent10 = + MaxExponent10FromMaxExponentAndDigits(max_exponent, digits); + static inline constexpr const bool is_iec559 = true; + static inline constexpr const bool has_infinity = true; + static inline constexpr const bool has_signaling_NaN = true; + // NOLINTEND + + // 1.0 * 2^(0b0001 - 7) = 1.0 * 2^-6 = 1/64 (min normal) + static constexpr float8_e4m3 min() { + return float8_e4m3::FromRep(1 << kMantissaBits); + } + // -(1 + 0b111 * 2^-2) * 2^(0b1110 - 7) = -(1 + 7/8) * 2^7 = -240 + static constexpr float8_e4m3 lowest() { + return float8_e4m3::FromRep(0b1'1110'111); + } + // (1 + 0b111 * 2^-2) * 2^(0b1110 - 7) = (1 + 7/8) * 2^7 = 240 + static constexpr float8_e4m3 max() { + return float8_e4m3::FromRep(0b0'1110'111); + } + // 1.0 * 2^-3 = 0.125 + static constexpr float8_e4m3 epsilon() { + return float8_e4m3::FromRep((-kMantissaBits + kExponentBias) + << kMantissaBits); + } + // 1.0 * 2^-1 = 0.5 + static constexpr float8_e4m3 round_error() { + return float8_e4m3::FromRep((-1 + kExponentBias) << kMantissaBits); + } + static constexpr float8_e4m3 infinity() { + return float8_e4m3::FromRep(0b0'1111'000); + } + static constexpr float8_e4m3 quiet_NaN() { + // IEEE 754-2019 6.2.1: "All binary NaN bit strings have the sign bit S set + // to 0 or 1 and all the bits of the biased exponent field E set to 1 + // (see 3.4). A quiet NaN bit string should be encoded with the first bit + // (d1) of the trailing significand field T being 1." + return float8_e4m3::FromRep(0b0'1111'100); + } + static constexpr float8_e4m3 signaling_NaN() { + // IEEE 754-2019 6.2.1: "A signaling NaN bit string should be encoded with + // the first bit of the trailing significand field being 0." + return float8_e4m3::FromRep(0b0'1111'001); + } + // 2^(-6) * 2^(-3) = 2^-9 = 1/512 (min denormal) + static constexpr float8_e4m3 denorm_min() { + return float8_e4m3::FromRep(0b0'0000'001); + } +}; + +struct numeric_limits_float8_e4m3fn : public numeric_limits_float8_base { + private: + static inline constexpr const int kExponentBias = 7; + static inline constexpr const int kMantissaBits = 3; + + public: + // NOLINTBEGIN: these names must match std::numeric_limits. + static inline constexpr const int digits = kMantissaBits + 1; + static inline constexpr const int digits10 = Digits10FromDigits(digits); + static inline constexpr const int max_digits10 = + MaxDigits10FromDigits(digits); + static inline constexpr const int min_exponent = (1 - kExponentBias) + 1; + static inline constexpr const int min_exponent10 = + MinExponent10FromMinExponent(min_exponent); + static inline constexpr const int max_exponent = + (0b1111 - kExponentBias) + 1; // Extended format. + static inline constexpr const int max_exponent10 = + MaxExponent10FromMaxExponentAndDigits(max_exponent, digits); + static inline constexpr const bool is_iec559 = false; + static inline constexpr const bool has_infinity = false; + static inline constexpr const bool has_signaling_NaN = false; + // NOLINTEND + + // 1.0 * 2^(0b0001 - 7) = 1.0 * 2^-6 = 0.015625 + static constexpr float8_e4m3fn min() { + return float8_e4m3fn::FromRep(0b0'0001 << kMantissaBits); + } + // -(1 + 0b110 * 2^-3) * 2^(0b1111 - 7) = -1.75 * 2^8 = 448 + static constexpr float8_e4m3fn lowest() { + return float8_e4m3fn::FromRep(0b1'1111'110); + } + // (1 + 0b110 * 2^-3) * 2**(0b1111 - 7) = 1.75 * 2^8 = 448 + static constexpr float8_e4m3fn max() { + return float8_e4m3fn::FromRep(0b0'1111'110); + } + // 1.0 * 2^-3 = 0.125 + static constexpr float8_e4m3fn epsilon() { + return float8_e4m3fn::FromRep((-kMantissaBits + kExponentBias) + << kMantissaBits); + } + // 1.0 * 2^-1 = 0.5 + static constexpr float8_e4m3fn round_error() { + return float8_e4m3fn::FromRep((-1 + kExponentBias) << kMantissaBits); + } + static constexpr float8_e4m3fn infinity() { + return float8_e4m3fn::FromRep(0b0'1111'111); + } + // NaN. + static constexpr float8_e4m3fn quiet_NaN() { + return float8_e4m3fn::FromRep(0b0'1111'111); + } + static constexpr float8_e4m3fn signaling_NaN() { + return float8_e4m3fn::FromRep(0b0'1111'111); + } + // 1.0 * 2^(-7 - 3 + 1) = 1.0 * 2^-9 = 0.001953125 + static constexpr float8_e4m3fn denorm_min() { + return float8_e4m3fn::FromRep(0b0'0000'001); + } +}; + +struct numeric_limits_float8_e4m3b11fnuz : public numeric_limits_float8_base { + private: + static inline constexpr const int kExponentBias = 11; + static inline constexpr const int kMantissaBits = 3; + + public: + // NOLINTBEGIN: these names must match std::numeric_limits. + static inline constexpr const int digits = kMantissaBits + 1; + static inline constexpr const int digits10 = Digits10FromDigits(digits); + static inline constexpr const int max_digits10 = + MaxDigits10FromDigits(digits); + static inline constexpr const int min_exponent = (1 - kExponentBias) + 1; + static inline constexpr const int min_exponent10 = + MinExponent10FromMinExponent(min_exponent); + static inline constexpr const int max_exponent = + (0b1111 - kExponentBias) + 1; // Extended format. + static inline constexpr const int max_exponent10 = + MaxExponent10FromMaxExponentAndDigits(max_exponent, digits); + static inline constexpr const bool is_iec559 = false; + static inline constexpr const bool has_infinity = false; + static inline constexpr const bool has_signaling_NaN = false; + // NOLINTEND + + // 1.0 * 2^(0b0001 - 11) = 1.0 * 2^-10 = 0.0009765625 + static constexpr float8_e4m3b11fnuz min() { + return float8_e4m3b11fnuz::FromRep(1 << kMantissaBits); + } + // -(1 + 0b111 * 2^-3) * 2^(0b1111 - 11) = -1.875 * 2^4 = -30 + static constexpr float8_e4m3b11fnuz lowest() { + return float8_e4m3b11fnuz::FromRep(0b1'1111'111); + } + // (1 + 0b111 * 2^-3) * 2^(0b1111 - 11) = 1.875 * 2^4 = 30 + static constexpr float8_e4m3b11fnuz max() { + return float8_e4m3b11fnuz::FromRep(0b0'1111'111); + } + // 1.0 * 2^-3 = 0.125 + static constexpr float8_e4m3b11fnuz epsilon() { + return float8_e4m3b11fnuz::FromRep((-kMantissaBits + kExponentBias) + << kMantissaBits); + } + // 1.0 * 2^-1 = 0.5 + static constexpr float8_e4m3b11fnuz round_error() { + return float8_e4m3b11fnuz::FromRep((-1 + kExponentBias) << kMantissaBits); + } + static constexpr float8_e4m3b11fnuz infinity() { + return float8_e4m3b11fnuz::FromRep(0b1'0000'000); + } + // NaN. + static constexpr float8_e4m3b11fnuz quiet_NaN() { + return float8_e4m3b11fnuz::FromRep(0b1'0000'000); + } + static constexpr float8_e4m3b11fnuz signaling_NaN() { + return float8_e4m3b11fnuz::FromRep(0b1'0000'000); + } + // 1.0 * 2^(-11 - 3 + 1) = 1.0 * 2^-13 = 0.0001220703125 + static constexpr float8_e4m3b11fnuz denorm_min() { + return float8_e4m3b11fnuz::FromRep(0b0'0000'001); + } +}; + +struct numeric_limits_float8_e4m3fnuz : public numeric_limits_float8_base { + private: + static inline constexpr const int kExponentBias = 8; + static inline constexpr const int kMantissaBits = 3; + + public: + // NOLINTBEGIN: these names must match std::numeric_limits. + static inline constexpr const int digits = kMantissaBits + 1; + static inline constexpr const int digits10 = Digits10FromDigits(digits); + static inline constexpr const int max_digits10 = + MaxDigits10FromDigits(digits); + static inline constexpr const int min_exponent = (1 - kExponentBias) + 1; + static inline constexpr const int min_exponent10 = + MinExponent10FromMinExponent(min_exponent); + static inline constexpr const int max_exponent = + (0b1111 - kExponentBias) + 1; // Extended format. + static inline constexpr const int max_exponent10 = + MaxExponent10FromMaxExponentAndDigits(max_exponent, digits); + static inline constexpr const bool is_iec559 = false; + static inline constexpr const bool has_infinity = false; + static inline constexpr const bool has_signaling_NaN = false; + // NOLINTEND + + static constexpr float8_e4m3fnuz min() { + return float8_e4m3fnuz::FromRep(0x08); + } + static constexpr float8_e4m3fnuz lowest() { + return float8_e4m3fnuz::FromRep(0xFF); + } + static constexpr float8_e4m3fnuz max() { + return float8_e4m3fnuz::FromRep(0x7F); + } + static constexpr float8_e4m3fnuz epsilon() { + return float8_e4m3fnuz::FromRep((-kMantissaBits + kExponentBias) + << kMantissaBits); + } + static constexpr float8_e4m3fnuz round_error() { + return float8_e4m3fnuz::FromRep((-1 + kExponentBias) << kMantissaBits); + } + static constexpr float8_e4m3fnuz infinity() { + return float8_e4m3fnuz::FromRep(0x80); + } + // NaN. + static constexpr float8_e4m3fnuz quiet_NaN() { + return float8_e4m3fnuz::FromRep(0x80); + } + static constexpr float8_e4m3fnuz signaling_NaN() { + return float8_e4m3fnuz::FromRep(0x80); + } + static constexpr float8_e4m3fnuz denorm_min() { + return float8_e4m3fnuz::FromRep(0x01); + } +}; + +struct numeric_limits_float8_e5m2 : public numeric_limits_float8_base { + private: + static inline constexpr const int kExponentBias = 15; + static inline constexpr const int kMantissaBits = 2; + + public: + // NOLINTBEGIN: these names must match std::numeric_limits. + static inline constexpr const int digits = kMantissaBits + 1; + static inline constexpr const int digits10 = Digits10FromDigits(digits); + static inline constexpr const int max_digits10 = + MaxDigits10FromDigits(digits); + static inline constexpr const int min_exponent = (1 - kExponentBias) + 1; + static inline constexpr const int min_exponent10 = + MinExponent10FromMinExponent(min_exponent); + static inline constexpr const int max_exponent = 0b11111 - kExponentBias; + static inline constexpr const int max_exponent10 = + MaxExponent10FromMaxExponentAndDigits(max_exponent, digits); + static inline constexpr const bool is_iec559 = true; + static inline constexpr const bool has_infinity = true; + static inline constexpr const bool has_signaling_NaN = true; + // NOLINTEND + + // 1.0 * 2^(0b00001 - 15) = 1.0 * 2^-14 = 0.00006103515625 + static constexpr float8_e5m2 min() { + return float8_e5m2::FromRep(1 << kMantissaBits); + } + // -(1 + 0b11 * 2^-2) * 2^(0b11110 - 15) = -1.75 * 2^15 = -57344 + static constexpr float8_e5m2 lowest() { + return float8_e5m2::FromRep(0b1'11110'11); + } + // (1 + 0b11 * 2^-2) * 2^(0b11110 - 15) = 1.75 * 2^15 = 57344 + static constexpr float8_e5m2 max() { + return float8_e5m2::FromRep(0b0'11110'11); + } + // 1.0 * 2^-2 = 0.25 + static constexpr float8_e5m2 epsilon() { + return float8_e5m2::FromRep((-kMantissaBits + kExponentBias) + << kMantissaBits); + } + // 1.0 * 2^-1 = 0.5 + static constexpr float8_e5m2 round_error() { + return float8_e5m2::FromRep((-1 + kExponentBias) << kMantissaBits); + } + static constexpr float8_e5m2 infinity() { + return float8_e5m2::FromRep(0b0'11111'00); + } + static constexpr float8_e5m2 quiet_NaN() { + // IEEE 754-2019 6.2.1: "All binary NaN bit strings have the sign bit S set + // to 0 or 1 and all the bits of the biased exponent field E set to 1 + // (see 3.4). A quiet NaN bit string should be encoded with the first bit + // (d1) of the trailing significand field T being 1." + return float8_e5m2::FromRep(0b0'11111'10); + } + static constexpr float8_e5m2 signaling_NaN() { + // IEEE 754-2019 6.2.1: "A signaling NaN bit string should be encoded with + // the first bit of the trailing significand field being 0." + return float8_e5m2::FromRep(0b0'11111'01); + } + // 1.0 * 2^(-15 - 2 + 1) = 1.0 * 2^-16 = 0.0000152587890625 + static constexpr float8_e5m2 denorm_min() { + return float8_e5m2::FromRep(0b0'00000'01); + } +}; + +struct numeric_limits_float8_e5m2fnuz : public numeric_limits_float8_base { + private: + static inline constexpr const int kExponentBias = 16; + static inline constexpr const int kMantissaBits = 2; + + public: + // NOLINTBEGIN: these names must match std::numeric_limits. + static inline constexpr const int digits = kMantissaBits + 1; + static inline constexpr const int digits10 = Digits10FromDigits(digits); + static inline constexpr const int max_digits10 = + MaxDigits10FromDigits(digits); + static inline constexpr const int min_exponent = (1 - kExponentBias) + 1; + static inline constexpr const int min_exponent10 = + MinExponent10FromMinExponent(min_exponent); + static inline constexpr const int max_exponent = + (0b11111 - kExponentBias) + 1; + static inline constexpr const int max_exponent10 = + MaxExponent10FromMaxExponentAndDigits(max_exponent, digits); + static inline constexpr const bool is_iec559 = false; + static inline constexpr const bool has_infinity = false; + static inline constexpr const bool has_signaling_NaN = false; + // NOLINTEND + + static constexpr float8_e5m2fnuz min() { + return float8_e5m2fnuz::FromRep(0x04); + } + static constexpr float8_e5m2fnuz lowest() { + return float8_e5m2fnuz::FromRep(0xFF); + } + static constexpr float8_e5m2fnuz max() { + return float8_e5m2fnuz::FromRep(0x7F); + } + static constexpr float8_e5m2fnuz epsilon() { + return float8_e5m2fnuz::FromRep((-kMantissaBits + kExponentBias) + << kMantissaBits); + } + static constexpr float8_e5m2fnuz round_error() { + return float8_e5m2fnuz::FromRep((-1 + kExponentBias) << kMantissaBits); + } + static constexpr float8_e5m2fnuz infinity() { + return float8_e5m2fnuz::FromRep(0x80); + } // NaN. + static constexpr float8_e5m2fnuz quiet_NaN() { + return float8_e5m2fnuz::FromRep(0x80); + } + static constexpr float8_e5m2fnuz signaling_NaN() { + return float8_e5m2fnuz::FromRep(0x80); + } + static constexpr float8_e5m2fnuz denorm_min() { + return float8_e5m2fnuz::FromRep(0x01); + } +}; + +struct numeric_limits_float8_e8m0fnu : public numeric_limits_float8_base { + private: + static inline constexpr const int kExponentBias = 127; + static inline constexpr const int kMantissaBits = 0; + + public: + // NOLINTBEGIN: these names must match std::numeric_limits. + static inline constexpr const bool is_signed = false; + static inline constexpr const std::float_denorm_style has_denorm = + std::denorm_absent; + static inline constexpr const int digits = kMantissaBits + 1; + static inline constexpr const int digits10 = Digits10FromDigits(digits); + static inline constexpr const int max_digits10 = + MaxDigits10FromDigits(digits); + // 2**-127 smallest valid normalized value.. + static inline constexpr const int min_exponent = -kExponentBias + 1; + static inline constexpr const int min_exponent10 = + MinExponent10FromMinExponent(min_exponent); + // 128 encoding using for NaN + static inline constexpr const int max_exponent = kExponentBias + 1; + static inline constexpr const int max_exponent10 = + MaxExponent10FromMaxExponentAndDigits(max_exponent, digits); + static inline constexpr const bool is_iec559 = false; + static inline constexpr const bool has_infinity = false; + static inline constexpr const bool has_signaling_NaN = false; + // NOLINTEND + + static constexpr float8_e8m0fnu min() { + return float8_e8m0fnu::FromRep(0x00); + } + static constexpr float8_e8m0fnu lowest() { + return float8_e8m0fnu::FromRep(0x00); + } + static constexpr float8_e8m0fnu max() { + return float8_e8m0fnu::FromRep(0xfe); + } + static constexpr float8_e8m0fnu epsilon() { + return float8_e8m0fnu::FromRep((-kMantissaBits + kExponentBias) + << kMantissaBits); + } + static constexpr float8_e8m0fnu round_error() { + return float8_e8m0fnu::FromRep((-1 + kExponentBias) << kMantissaBits); + } + static constexpr float8_e8m0fnu infinity() { + return float8_e8m0fnu::FromRep(0xFF); + } // NaN. + static constexpr float8_e8m0fnu quiet_NaN() { + return float8_e8m0fnu::FromRep(0xFF); + } + static constexpr float8_e8m0fnu signaling_NaN() { + return float8_e8m0fnu::FromRep(0xFF); + } + static constexpr float8_e8m0fnu denorm_min() { + // No denorm => smallest value. + return float8_e8m0fnu::FromRep(0x00); + } +}; + +} // namespace float8_internal +} // namespace ml_dtypes + +namespace std { +// Standard-library overrides. Note that these are picked up by Eigen as well. +template <> +struct numeric_limits<ml_dtypes::float8_internal::float8_e3m4> + : public ml_dtypes::float8_internal::numeric_limits_float8_e3m4 {}; + +template <> +struct numeric_limits<ml_dtypes::float8_internal::float8_e4m3> + : public ml_dtypes::float8_internal::numeric_limits_float8_e4m3 {}; + +template <> +struct numeric_limits<ml_dtypes::float8_internal::float8_e4m3fn> + : public ml_dtypes::float8_internal::numeric_limits_float8_e4m3fn {}; + +template <> +struct numeric_limits<ml_dtypes::float8_internal::float8_e4m3b11fnuz> + : public ml_dtypes::float8_internal::numeric_limits_float8_e4m3b11fnuz {}; + +template <> +struct numeric_limits<ml_dtypes::float8_internal::float8_e4m3fnuz> + : public ml_dtypes::float8_internal::numeric_limits_float8_e4m3fnuz {}; + +template <> +struct numeric_limits<ml_dtypes::float8_internal::float8_e5m2> + : public ml_dtypes::float8_internal::numeric_limits_float8_e5m2 {}; + +template <> +struct numeric_limits<ml_dtypes::float8_internal::float8_e5m2fnuz> + : public ml_dtypes::float8_internal::numeric_limits_float8_e5m2fnuz {}; + +template <> +struct numeric_limits<ml_dtypes::float8_internal::float8_e8m0fnu> + : public ml_dtypes::float8_internal::numeric_limits_float8_e8m0fnu {}; +} // namespace std + +namespace ml_dtypes { +namespace float8_internal { + +constexpr inline float8_e3m4 abs(const float8_e3m4& a) { + return float8_e3m4::FromRep(a.rep() & 0b0'111'1111); +} + +constexpr inline bool(isnan)(const float8_e3m4& a) { + return abs(a).rep() > std::numeric_limits<float8_e3m4>::infinity().rep(); +} + +constexpr inline float8_e4m3 abs(const float8_e4m3& a) { + return float8_e4m3::FromRep(a.rep() & 0b0'1111'111); +} + +constexpr inline bool(isnan)(const float8_e4m3& a) { + return abs(a).rep() > std::numeric_limits<float8_e4m3>::infinity().rep(); +} + +// Free-functions for use with ADL and in Eigen. +constexpr inline float8_e4m3fn abs(const float8_e4m3fn& a) { + return float8_e4m3fn::FromRep(a.rep() & 0b0'1111'111); +} + +constexpr inline bool(isnan)(const float8_e4m3fn& a) { + return abs(a).rep() == std::numeric_limits<float8_e4m3fn>::quiet_NaN().rep(); +} + +constexpr inline float8_e4m3b11fnuz abs(const float8_e4m3b11fnuz& a) { + return (a.rep() & 0b0'1111'111) == 0 + ? float8_e4m3b11fnuz::FromRep(a.rep()) + : float8_e4m3b11fnuz::FromRep(a.rep() & 0b0'1111'111); +} + +constexpr inline bool(isnan)(const float8_e4m3b11fnuz& a) { + return a.rep() == std::numeric_limits<float8_e4m3b11fnuz>::quiet_NaN().rep(); +} + +constexpr inline float8_e4m3fnuz abs(const float8_e4m3fnuz& a) { + return (a.rep() & 0x7F) == 0 ? float8_e4m3fnuz::FromRep(a.rep()) + : float8_e4m3fnuz::FromRep(a.rep() & 0x7F); +} + +constexpr inline bool(isnan)(const float8_e4m3fnuz& a) { + return abs(a).rep() == + std::numeric_limits<float8_e4m3fnuz>::quiet_NaN().rep(); +} + +constexpr inline float8_e5m2 abs(const float8_e5m2& a) { + return float8_e5m2::FromRep(a.rep() & 0b0'11111'11); +} + +constexpr inline bool(isnan)(const float8_e5m2& a) { + return abs(a).rep() > std::numeric_limits<float8_e5m2>::infinity().rep(); +} + +constexpr inline float8_e5m2fnuz abs(const float8_e5m2fnuz& a) { + return (a.rep() & 0x7F) == 0 ? float8_e5m2fnuz::FromRep(a.rep()) + : float8_e5m2fnuz::FromRep(a.rep() & 0x7F); +} + +constexpr inline bool(isnan)(const float8_e5m2fnuz& a) { + return a.rep() == 0x80; +} + +constexpr inline float8_e8m0fnu abs(const float8_e8m0fnu& a) { return a; } + +constexpr inline bool(isnan)(const float8_e8m0fnu& a) { + return a.rep() == 0xff; +} + +template <typename Float8> +constexpr inline bool(isinf)(const float8_base<Float8>& a) { + if constexpr (std::numeric_limits<Float8>::has_infinity) { + return abs(a.derived()).rep() == + std::numeric_limits<Float8>::infinity().rep(); + } else { + // No inf representation. + return false; + } +} + +template <typename Float8> +constexpr inline bool(isfinite)(const float8_base<Float8>& a) { + return !isnan(a.derived()) && !isinf(a.derived()); +} + +template <typename Float8> +std::ostream& operator<<(std::ostream& os, const float8_base<Float8>& f8) { + os << static_cast<float>(f8.derived()); + return os; +} + +//============================================================================== +// Inline conversion routines between float8 and other types. +//============================================================================== + +template <typename T> +bool constexpr IsPowerOfTwo(T x) { + return (x != 0) && ((x & (x - 1)) == 0); +} +// Helper for getting a bytes size which is a power of two. +template <int Size> +struct NextPowerOfTwo { + static constexpr int value = Size; +}; +template <> +struct NextPowerOfTwo<3> { + static constexpr int value = 4; +}; +template <> +struct NextPowerOfTwo<5> { + static constexpr int value = 8; +}; +template <> +struct NextPowerOfTwo<6> { + static constexpr int value = 8; +}; +template <> +struct NextPowerOfTwo<7> { + static constexpr int value = 8; +}; + +// Helper for getting a bit representation provided a byte size. +template <int kNumBytes> +using GetUnsignedInteger = + typename Eigen::numext::get_integer_by_size<kNumBytes>::unsigned_type; + +// Converts between two floating-point types. +template <typename From, typename To, bool kSaturate, bool kTruncate, + typename EnableIf = void> +struct ConvertImpl; + +// Convert to same type. We need explicit specializations for all combinations +// of template parameters to avoid ambiguities. +template <typename Scalar> +struct IdentityConversion { + static EIGEN_DEVICE_FUNC inline Scalar run(Scalar from) { return from; } +}; + +template <typename Scalar, bool kSaturate, bool kTruncate> +struct ConvertImpl<Scalar, Scalar, /*kSaturate=*/kSaturate, + /*kTruncate=*/kTruncate> + : public IdentityConversion<Scalar> {}; + +template <typename Float> +struct TraitsBase { + using BitsType = GetUnsignedInteger<sizeof(Float)>; + static constexpr bool kIsSigned = std::numeric_limits<Float>::is_signed; + static constexpr bool kHasZero = true; + + static constexpr int kBits = sizeof(Float) * CHAR_BIT; + static constexpr int kMantissaBits = Eigen::NumTraits<Float>::digits() - 1; + // Extra bit used in exponent for unsigned float. + static constexpr int kExponentBits = + kBits - kMantissaBits - static_cast<int>(kIsSigned); + static constexpr BitsType kExponentMask = ((BitsType{1} << kExponentBits) - 1) + << kMantissaBits; + static constexpr BitsType kMantissaMask = (BitsType{1} << kMantissaBits) - 1; + static constexpr int kExponentBias = (1 << (kExponentBits - 1)) - 1; +}; + +template <typename Float> +struct Traits : public TraitsBase<Float> {}; + +template <> +struct Traits<float8_e4m3b11fnuz> : public TraitsBase<float8_e4m3b11fnuz> { + static constexpr int kExponentBias = 11; +}; + +template <> +struct Traits<float8_e4m3fnuz> : public TraitsBase<float8_e4m3fnuz> { + using Base = TraitsBase<float8_e4m3fnuz>; + static constexpr int kExponentBias = Base::kExponentBias + 1; +}; + +template <> +struct Traits<float8_e5m2fnuz> : public TraitsBase<float8_e5m2fnuz> { + using Base = TraitsBase<float8_e5m2fnuz>; + static constexpr int kExponentBias = Base::kExponentBias + 1; +}; + +template <> +struct Traits<float8_e8m0fnu> : public TraitsBase<float8_e8m0fnu> { + using Base = TraitsBase<float8_e8m0fnu>; + // No zero in E8MO OCP MX format description. + static constexpr bool kHasZero = false; +}; + +template <typename Bits> +constexpr inline Bits RoundBitsToNearestEven(Bits bits, int roundoff, + bool use_implicit_bit) { + // Round to nearest even by adding a bias term. + // Consider a bit pattern + // FFF...FLRTT...T, + // where bits RTT...T need to be rounded-off. We add a bias term to the + // bit pattern s.t. a carry is introduced to round up only if + // - L is 1, R is 1, OR + // - L is 0, R is 1, any T is one. + // We do this by adding L to a bit pattern consisting of all T = 1. + // + // When rounding to zero mantissa (E8M0 type), the L bit is implicitly 1 (do + // not use the exponent bits for rounding). Add only the R bit in this case. + Bits bias = !use_implicit_bit + ? ((bits >> roundoff) & 1) + (Bits{1} << (roundoff - 1)) - 1 + : Bits{1} << (roundoff - 1); + return bits + bias; +} + +#if (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L) +using std::countl_zero; +#else +static constexpr inline int countl_zero(uint64_t x) { + int zeroes = 60; + if (x >> 32) { + zeroes -= 32; + x >>= 32; + } + if (x >> 16) { + zeroes -= 16; + x >>= 16; + } + if (x >> 8) { + zeroes -= 8; + x >>= 8; + } + if (x >> 4) { + zeroes -= 4; + x >>= 4; + } + return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[x] + zeroes; +} +static constexpr inline int countl_zero(uint32_t x) { + int zeroes = 28; + if (x >> 16) { + zeroes -= 16; + x >>= 16; + } + if (x >> 8) { + zeroes -= 8; + x >>= 8; + } + if (x >> 4) { + zeroes -= 4; + x >>= 4; + } + return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[x] + zeroes; +} +static constexpr inline int countl_zero(uint16_t x) { + int zeroes = 12; + if (x >> 8) { + zeroes -= 8; + x >>= 8; + } + if (x >> 4) { + zeroes -= 4; + x >>= 4; + } + return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[x] + zeroes; +} +static constexpr inline int countl_zero(uint8_t x) { + int zeroes = 4; + if (x >> 4) { + zeroes -= 4; + x >>= 4; + } + return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[x] + zeroes; +} +#endif + +template <typename From, typename To, bool kSaturate, bool kTruncate> +struct ConvertImpl<From, To, kSaturate, kTruncate, + std::enable_if_t<!std::is_same_v<From, To>>> { + using FromTraits = Traits<From>; + using FromBits = typename FromTraits::BitsType; + static constexpr bool kFromIsSigned = FromTraits::kIsSigned; + static constexpr bool kFromHasZero = FromTraits::kHasZero; + static constexpr int kFromBits = FromTraits::kBits; + static constexpr int kFromMantissaBits = FromTraits::kMantissaBits; + static constexpr int kFromExponentBits = FromTraits::kExponentBits; + static constexpr int kFromExponentBias = FromTraits::kExponentBias; + static constexpr FromBits kFromExponentMask = FromTraits::kExponentMask; + + using ToTraits = Traits<To>; + using ToBits = typename ToTraits::BitsType; + static constexpr bool kToIsSigned = ToTraits::kIsSigned; + static constexpr bool kToHasZero = ToTraits::kHasZero; + static constexpr int kToBits = ToTraits::kBits; + static constexpr int kToMantissaBits = ToTraits::kMantissaBits; + static constexpr int kToExponentBits = ToTraits::kExponentBits; + static constexpr int kToExponentBias = ToTraits::kExponentBias; + static constexpr ToBits kToExponentMask = ToTraits::kExponentMask; + + // `WideBits` is wide enough to accommodate the largest exponent and mantissa + // in either `From` or `To`. + static constexpr int kWideBits = + (std::max(kToMantissaBits, kFromMantissaBits)) + // Max significand. + (std::max(kToExponentBits, kFromExponentBits)); // Max exponent. + static constexpr int kWideBytesRaw = (kWideBits + (CHAR_BIT - 1)) / CHAR_BIT; + // Need a power of two (i.e. not 3 bytes). + static constexpr int kWideBytes = NextPowerOfTwo<kWideBytesRaw>::value; + + using WideBits = GetUnsignedInteger<kWideBytes>; + static_assert(!std::is_void_v<WideBits>, + "`WideBits` type can not be void type."); + + static constexpr int kExponentOffset = kToExponentBias - kFromExponentBias; + static constexpr int kDigitShift = kToMantissaBits - kFromMantissaBits; + + static EIGEN_DEVICE_FUNC inline To run(From from) { + // Shift bits to destination type, without sign bit. + const bool from_sign_bit = + Eigen::numext::bit_cast<FromBits>(from) >> (kFromBits - 1) && + kFromIsSigned; + const FromBits from_bits = + Eigen::numext::bit_cast<FromBits>(Eigen::numext::abs(from)); + + // Special values, preserving sign. + if (Eigen::numext::isinf(from)) { + return from_sign_bit ? -Eigen::NumTraits<To>::infinity() + : Eigen::NumTraits<To>::infinity(); + } + if (Eigen::numext::isnan(from)) { + return from_sign_bit ? -Eigen::NumTraits<To>::quiet_NaN() + : Eigen::NumTraits<To>::quiet_NaN(); + } + // Dealing with zero, when `From` has one. + if (from_bits == 0 && kFromHasZero) { + if constexpr (kToHasZero) { + // Keep the sign, if `To` supports it. + return from_sign_bit && kToIsSigned ? -To{} : To{}; + } else { + return kSaturate ? std::numeric_limits<To>::denorm_min() + : Eigen::NumTraits<To>::quiet_NaN(); + } + } + // `To` unsigned floating format: NaN or saturate. + if constexpr (!kToIsSigned && kFromIsSigned) { + if (from_sign_bit) { + return kSaturate ? std::numeric_limits<To>::lowest() + : Eigen::NumTraits<To>::quiet_NaN(); + } + } + + const int biased_from_exponent = from_bits >> kFromMantissaBits; + const bool to_zero_mantissa = kToMantissaBits == 0; + + // `To` supports more exponents near zero which means that some subnormal + // values in `From` may become normal. + if constexpr (std::numeric_limits<To>::min_exponent < + std::numeric_limits<From>::min_exponent) { + if (biased_from_exponent == 0) { + // Subnormals. + WideBits bits = from_bits; + + // Determine exponent in target type. + const int msb = + sizeof(from_bits) * CHAR_BIT - countl_zero(from_bits) - 1; + const int normalization_factor = kFromMantissaBits - msb; + const int biased_exponent = kExponentOffset - normalization_factor + 1; + if (biased_exponent <= 0) { + // Result is subnormal. Adjust the subnormal bits to account for + // the difference in exponent bias. + if constexpr (kExponentOffset < sizeof(WideBits) * CHAR_BIT) { + bits <<= kExponentOffset; + } + } else { + // Result is normal. Shift the mantissa to account for the number of + // leading zero digits, and clear the hidden bit. + bits <<= normalization_factor; + bits &= ~(WideBits{1} << kFromMantissaBits); + // Insert the exponent bits. + bits |= static_cast<WideBits>(biased_exponent) << kFromMantissaBits; + } + + // Truncate/round mantissa if necessary. + if constexpr (kDigitShift >= 0) { + bits <<= kDigitShift; + } else { + if constexpr (!kTruncate) { + // When converting float to e8m0, the bits represent a denormal, + // so don't use the implicit mantissa bit for rounding. + bits = RoundBitsToNearestEven( + bits, -kDigitShift, to_zero_mantissa && kExponentOffset != 0); + } + bits >>= -kDigitShift; + } + To to = Eigen::numext::bit_cast<To>(static_cast<ToBits>(bits)); + return from_sign_bit ? -to : to; + } + } + // `To` supports fewer exponents near zero which means that some values in + // `From` may become subnormal. + if constexpr (std::numeric_limits<To>::min_exponent > + std::numeric_limits<From>::min_exponent) { + const int unbiased_exponent = biased_from_exponent - kFromExponentBias; + const int biased_to_exponent = unbiased_exponent + kToExponentBias; + // Subnormals and zero. + if (biased_to_exponent <= 0) { + // Round and shift mantissa down. + // Zero exponent valid if From has no zero representation. + FromBits from_has_leading_one = + (biased_from_exponent > 0 || !kFromHasZero ? 1 : 0); + int exponent_shift = + -kDigitShift - biased_to_exponent + from_has_leading_one; + // Insert the implicit leading 1 bit on the mantissa for normalized + // inputs. + FromBits rounded_from_bits = + (from_bits & FromTraits::kMantissaMask) | + (from_has_leading_one << kFromMantissaBits); + ToBits bits = 0; + if (exponent_shift > 0) { + // To avoid UB, limit rounding and shifting to the full mantissa plus + // leading 1. + if (exponent_shift <= kFromMantissaBits + 1) { + if constexpr (!kTruncate) { + // NOTE: we need to round again from the original from_bits, + // otherwise the lower precision bits may already be lost. There + // is an edge-case where rounding to a normalized value would + // normally round down, but for a subnormal, we need to round up. + rounded_from_bits = RoundBitsToNearestEven(rounded_from_bits, + exponent_shift, false); + } + bits = rounded_from_bits >> exponent_shift; + } + } else { + bits = rounded_from_bits << -exponent_shift; + } + // Insert sign and return. + To to = Eigen::numext::bit_cast<To>(bits); + return from_sign_bit ? -to : to; + } + } + + // Round the mantissa if it is shrinking. + WideBits rounded_from_bits = from_bits; + if constexpr (kDigitShift < 0) { + if constexpr (!kTruncate) { + rounded_from_bits = + RoundBitsToNearestEven(from_bits, -kDigitShift, to_zero_mantissa); + } + // Zero-out tail bits. + rounded_from_bits &= ~((WideBits{1} << (-kDigitShift)) - 1); + } + + // Re-bias the exponent. + rounded_from_bits += static_cast<WideBits>(kExponentOffset) + << kFromMantissaBits; + + ToBits bits; + // Check for overflows by aligning the significands. We always align the + // narrower significand to the wider significand. + const WideBits kToHighestRep = + Eigen::numext::bit_cast<ToBits>(Eigen::NumTraits<To>::highest()); + WideBits aligned_highest{kToHighestRep}; + if constexpr (kDigitShift < 0) { + aligned_highest <<= -kDigitShift; + // Shift down, all dropped bits should already be zero. + bits = static_cast<ToBits>(rounded_from_bits >> -kDigitShift); + } else if constexpr (kDigitShift >= 0) { + // Shift up, inserting zeros in the newly created digits. + rounded_from_bits <<= kDigitShift; + bits = static_cast<ToBits>(rounded_from_bits); + } + + To to = Eigen::numext::bit_cast<To>(bits); + // `From` supports larger values than `To`, we may overflow. + if constexpr (std::make_pair(std::numeric_limits<To>::max_exponent, + std::numeric_limits<To>::digits) < + std::make_pair(std::numeric_limits<From>::max_exponent, + std::numeric_limits<From>::digits)) { + if (rounded_from_bits > aligned_highest) { + // Overflowed values map to highest or infinity depending on kSaturate. + to = kSaturate ? Eigen::NumTraits<To>::highest() + : Eigen::NumTraits<To>::infinity(); + } + } + // Insert sign bit. + return from_sign_bit ? -to : to; + } +}; + +// Saturation has no impact when casting e4m3fn to e5m2. +template <bool kTruncate> +struct ConvertImpl<float8_e4m3fn, float8_e5m2, true, kTruncate> { + static EIGEN_DEVICE_FUNC inline float8_e5m2 run(float8_e4m3fn from) { + return ConvertImpl<float8_e4m3fn, float8_e5m2, false, kTruncate>::run(from); + } +}; + +template <bool kSaturate, bool kTruncate> +struct ConvertImpl<Eigen::half, float8_e5m2, kSaturate, kTruncate> { + static EIGEN_DEVICE_FUNC inline float8_e5m2 run(Eigen::half from) { + uint16_t from_bits = Eigen::numext::bit_cast<uint16_t>(from); + + // Special values (Inf or NaN). + uint16_t abs_bits = from_bits & 0x7FFF; + if (abs_bits == 0x7C00) { + return float8_e5m2::FromRep(from_bits >> 8); + } else if (abs_bits > 0x7C00) { + // IEEE 754-2019 6.2.1: "A quiet NaN bit string should be encoded with the + // first bit (d1) of the trailing significand field T being 1." + // IEEE 754-2019 6.2.3: "Conversion of a quiet NaN to a floating-point + // format of the same or a different radix that does not allow the payload + // to be preserved, shall return a quiet NaN [...]" + return float8_e5m2::FromRep((from_bits >> 8) | 0b0'00000'10); + } + + if constexpr (!kTruncate) { + from_bits = RoundBitsToNearestEven(from_bits, 8, false); + // Rounding can cause an overflow to infinity. Clamp to the largest finite + // value if saturation is requested. + if constexpr (kSaturate) { + const float8_e5m2 kHighest = Eigen::NumTraits<float8_e5m2>::highest(); + if ((from_bits & 0x7F00) > static_cast<uint16_t>(kHighest.rep()) << 8) { + const bool from_sign_bit = from_bits >> 15; + return from_sign_bit ? -kHighest : kHighest; + } + } + } + return float8_e5m2::FromRep(from_bits >> 8); + } +}; + +// Direct casts of e5m2 to Eigen::half simply shifts bits over. +template <bool kSaturate, bool kTruncate> +struct ConvertImpl<float8_e5m2, Eigen::half, kSaturate, kTruncate> { + static EIGEN_DEVICE_FUNC inline Eigen::half run(float8_e5m2 from) { + return Eigen::numext::bit_cast<Eigen::half>( + static_cast<uint16_t>(static_cast<uint16_t>(from.rep()) << 8)); + } +}; + +template <typename Derived> +template <bool kSaturate, bool kTruncate, typename From> +EIGEN_DEVICE_FUNC Derived float8_base<Derived>::ConvertFrom(const From from) { + // We are rounding long double -> float -> float8. This can induce + // double-rounding which may alter the results. We can correct for this using + // a trick explained in: Boldo, Sylvie, and Guillaume Melquiond. "When double + // rounding is odd." 17th IMACS World Congress. 2005. + if constexpr (std::is_floating_point_v<From> && + sizeof(From) > sizeof(double)) { + // binary64, float80, binary128, etc. end up here. + static_assert(std::numeric_limits<From>::digits >= + std::numeric_limits<float>::digits + 2); + static_assert(std::numeric_limits<float>::min_exponent >= + std::numeric_limits<From>::min_exponent + 2); + static_assert(std::numeric_limits<float>::is_iec559); + static_assert(std::numeric_limits<float>::radix == 2); + const bool is_negative = std::signbit(from); + const From abs_wide = std::fabs(from); + float abs_narrow = static_cast<float>(abs_wide); + const From abs_narrow_as_wide = static_cast<From>(abs_narrow); + + uint32_t narrow_bits = Eigen::numext::bit_cast<uint32_t>(abs_narrow); + // We can keep the narrow value as-is if narrowing was exact (no rounding + // error), the wide value was NaN (the narrow value is also NaN and should + // be preserved) or if we rounded to the odd value. + const bool keep_narrow = (abs_wide == abs_narrow_as_wide) || + std::isnan(abs_narrow) || (narrow_bits & 1); + // We morally performed a round-down if `abs_narrow` is smaller than + // `abs_wide`. + const bool narrow_is_rd = abs_wide > abs_narrow_as_wide; + // If the narrow value is odd or exact, pick it. + // Otherwise, narrow is even and corresponds to either the rounded-up or + // rounded-down value. If narrow is the rounded-down value, we want the + // rounded-up value as it will be odd. + narrow_bits += keep_narrow ? 0 : narrow_is_rd ? 1 : -1; + abs_narrow = Eigen::numext::bit_cast<float>(narrow_bits); + return ConvertImpl<float, Derived, kSaturate, kTruncate>::run( + is_negative ? -abs_narrow : abs_narrow); + } else { + return ConvertImpl<From, Derived, kSaturate, kTruncate>::run(from); + } +} + +template <typename Derived> +template <typename To, bool kSaturate, bool kTruncate> +EIGEN_DEVICE_FUNC To float8_base<Derived>::ConvertTo(Derived from) { + return ConvertImpl<Derived, To, kSaturate, kTruncate>::run(from); +} + +} // namespace float8_internal + +// Exported types. +using float8_e3m4 = float8_internal::float8_e3m4; +using float8_e4m3 = float8_internal::float8_e4m3; +using float8_e4m3fn = float8_internal::float8_e4m3fn; +using float8_e4m3fnuz = float8_internal::float8_e4m3fnuz; +using float8_e4m3b11fnuz = float8_internal::float8_e4m3b11fnuz; +using float8_e5m2 = float8_internal::float8_e5m2; +using float8_e5m2fnuz = float8_internal::float8_e5m2fnuz; +using float8_e8m0fnu = float8_internal::float8_e8m0fnu; + +} // namespace ml_dtypes + +// Work-around for isinf/isnan/isfinite issue on aarch64. +namespace Eigen { +namespace internal { + +template <> +EIGEN_DEVICE_FUNC inline bool isinf_impl<ml_dtypes::float8_e3m4>( + const ml_dtypes::float8_e3m4& x) { + return ml_dtypes::float8_internal::isinf(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isinf_impl<ml_dtypes::float8_e4m3>( + const ml_dtypes::float8_e4m3& x) { + return ml_dtypes::float8_internal::isinf(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isinf_impl<ml_dtypes::float8_e4m3fn>( + const ml_dtypes::float8_e4m3fn& x) { + return ml_dtypes::float8_internal::isinf(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isinf_impl<ml_dtypes::float8_e4m3b11fnuz>( + const ml_dtypes::float8_e4m3b11fnuz& x) { + return ml_dtypes::float8_internal::isinf(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isinf_impl<ml_dtypes::float8_e4m3fnuz>( + const ml_dtypes::float8_e4m3fnuz& x) { + return ml_dtypes::float8_internal::isinf(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isinf_impl<ml_dtypes::float8_e5m2>( + const ml_dtypes::float8_e5m2& x) { + return ml_dtypes::float8_internal::isinf(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isinf_impl<ml_dtypes::float8_e5m2fnuz>( + const ml_dtypes::float8_e5m2fnuz& x) { + return ml_dtypes::float8_internal::isinf(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isinf_impl<ml_dtypes::float8_e8m0fnu>( + const ml_dtypes::float8_e8m0fnu& x) { + return ml_dtypes::float8_internal::isinf(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isnan_impl<ml_dtypes::float8_e3m4>( + const ml_dtypes::float8_e3m4& x) { + return ml_dtypes::float8_internal::isnan(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isnan_impl<ml_dtypes::float8_e4m3>( + const ml_dtypes::float8_e4m3& x) { + return ml_dtypes::float8_internal::isnan(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isnan_impl<ml_dtypes::float8_e4m3fn>( + const ml_dtypes::float8_e4m3fn& x) { + return ml_dtypes::float8_internal::isnan(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isnan_impl<ml_dtypes::float8_e4m3b11fnuz>( + const ml_dtypes::float8_e4m3b11fnuz& x) { + return ml_dtypes::float8_internal::isnan(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isnan_impl<ml_dtypes::float8_e4m3fnuz>( + const ml_dtypes::float8_e4m3fnuz& x) { + return ml_dtypes::float8_internal::isnan(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isnan_impl<ml_dtypes::float8_e5m2>( + const ml_dtypes::float8_e5m2& x) { + return ml_dtypes::float8_internal::isnan(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isnan_impl<ml_dtypes::float8_e5m2fnuz>( + const ml_dtypes::float8_e5m2fnuz& x) { + return ml_dtypes::float8_internal::isnan(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isnan_impl<ml_dtypes::float8_e8m0fnu>( + const ml_dtypes::float8_e8m0fnu& x) { + return ml_dtypes::float8_internal::isnan(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isfinite_impl<ml_dtypes::float8_e3m4>( + const ml_dtypes::float8_e3m4& x) { + return ml_dtypes::float8_internal::isfinite(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isfinite_impl<ml_dtypes::float8_e4m3>( + const ml_dtypes::float8_e4m3& x) { + return ml_dtypes::float8_internal::isfinite(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isfinite_impl<ml_dtypes::float8_e4m3fn>( + const ml_dtypes::float8_e4m3fn& x) { + return ml_dtypes::float8_internal::isfinite(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isfinite_impl<ml_dtypes::float8_e4m3b11fnuz>( + const ml_dtypes::float8_e4m3b11fnuz& x) { + return ml_dtypes::float8_internal::isfinite(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isfinite_impl<ml_dtypes::float8_e4m3fnuz>( + const ml_dtypes::float8_e4m3fnuz& x) { + return ml_dtypes::float8_internal::isfinite(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isfinite_impl<ml_dtypes::float8_e5m2>( + const ml_dtypes::float8_e5m2& x) { + return ml_dtypes::float8_internal::isfinite(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isfinite_impl<ml_dtypes::float8_e5m2fnuz>( + const ml_dtypes::float8_e5m2fnuz& x) { + return ml_dtypes::float8_internal::isfinite(x); +} + +template <> +EIGEN_DEVICE_FUNC inline bool isfinite_impl<ml_dtypes::float8_e8m0fnu>( + const ml_dtypes::float8_e8m0fnu& x) { + return ml_dtypes::float8_internal::isfinite(x); +} + +} // namespace internal +} // namespace Eigen + +#endif // ML_DTYPES_FLOAT8_H_
diff --git a/third_party/ml_dtypes/src/ml_dtypes/include/intn.h b/third_party/ml_dtypes/src/ml_dtypes/include/intn.h new file mode 100644 index 0000000..e201fd97 --- /dev/null +++ b/third_party/ml_dtypes/src/ml_dtypes/include/intn.h
@@ -0,0 +1,321 @@ +/* Copyright 2023 The ml_dtypes Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef ML_DTYPES_INTN_H_ +#define ML_DTYPES_INTN_H_ + +#include <cstdint> +#include <limits> +#include <optional> +#include <ostream> +#include <sstream> +#include <string> +#include <type_traits> + +namespace ml_dtypes { + +// Stores the n-bit integer value in the low n bits of a byte. The upper +// bits are left unspecified and ignored. +template <int N, typename UnderlyingTy> +struct intN { + private: + UnderlyingTy v_; + using SignedUnderlyingTy = std::make_signed_t<UnderlyingTy>; + using UnsignedUnderlyingTy = std::make_unsigned_t<UnderlyingTy>; + static constexpr int kUnderlyingBits = + std::numeric_limits<UnsignedUnderlyingTy>::digits; + + static_assert( + std::is_same_v<UnderlyingTy, uint8_t> || + std::is_same_v<UnderlyingTy, int8_t>, + "The underyling type must be a signed or unsigned 8-bit integer."); + + // Mask the upper bits. + static inline constexpr UnderlyingTy Mask(UnderlyingTy v) { + return static_cast<UnsignedUnderlyingTy>( + static_cast<UnsignedUnderlyingTy>(v) << (kUnderlyingBits - N)) >> + (kUnderlyingBits - N); + } + + // Mask the upper bits and sign-extend for signed types. + static inline constexpr UnderlyingTy ExtendToFullWidth(UnderlyingTy v) { + return static_cast<UnderlyingTy>(static_cast<UnderlyingTy>(v) + << (kUnderlyingBits - N)) >> + (kUnderlyingBits - N); + } + + // Casts to the corresponding UnderlyingTy value. + inline constexpr UnderlyingTy IntValue() const { + return ExtendToFullWidth(v_); + } + + public: + constexpr intN() noexcept : v_(0) {} + constexpr intN(const intN& other) noexcept = default; + constexpr intN(intN&& other) noexcept = default; + constexpr intN& operator=(const intN& other) = default; + constexpr intN& operator=(intN&&) = default; + + explicit constexpr intN(UnderlyingTy val) : v_(Mask(val)) {} + template <typename T> + explicit constexpr intN(T t) : intN(static_cast<UnderlyingTy>(t)) {} + + using underlying_type = UnderlyingTy; + static constexpr int bits = N; + static constexpr int digits = std::is_signed_v<UnderlyingTy> ? N - 1 : N; + static constexpr intN highest() { return intN((1 << digits) - 1); } + static constexpr intN lowest() { + return std::is_signed_v<UnderlyingTy> ? intN(1) << digits : intN(0); + } + + template <typename T> + explicit constexpr operator T() const { + return static_cast<T>(IntValue()); + } + // NOLINTNEXTLINE(google-explicit-constructor) + constexpr operator std::optional<int64_t>() const { + return static_cast<int64_t>(IntValue()); + } + + constexpr intN operator-() const { return intN(-v_); } + constexpr intN operator+(const intN& other) const { + return intN(v_ + other.v_); + } + constexpr intN operator-(const intN& other) const { + return intN(v_ - other.v_); + } + constexpr intN operator*(const intN& other) const { + return intN(v_ * other.v_); + } + constexpr intN operator/(const intN& other) const { + return intN(IntValue() / other.IntValue()); + } + constexpr intN operator%(const intN& other) const { + return intN((IntValue() % other.IntValue())); + } + + constexpr intN operator&(const intN& other) const { + return intN(v_ & other.v_); + } + constexpr intN operator|(const intN& other) const { + return intN(v_ | other.v_); + } + constexpr intN operator^(const intN& other) const { + return intN(v_ ^ other.v_); + } + constexpr intN operator~() const { return intN(~v_); } + constexpr intN operator>>(int amount) const { + return intN(IntValue() >> amount); + } + constexpr intN operator<<(int amount) const { return intN(v_ << amount); } + + constexpr bool operator==(const intN& other) const { + return Mask(v_) == Mask(other.v_); + } + constexpr bool operator!=(const intN& other) const { + return Mask(v_) != Mask(other.v_); + } + constexpr bool operator<(const intN& other) const { + return IntValue() < other.IntValue(); + } + constexpr bool operator>(const intN& other) const { + return IntValue() > other.IntValue(); + } + constexpr bool operator<=(const intN& other) const { + return IntValue() <= other.IntValue(); + } + constexpr bool operator>=(const intN& other) const { + return IntValue() >= other.IntValue(); + } + + constexpr bool operator==(int64_t other) const { return IntValue() == other; } + constexpr bool operator!=(int64_t other) const { return IntValue() != other; } + constexpr bool operator<(int64_t other) const { return IntValue() < other; } + constexpr bool operator>(int64_t other) const { return IntValue() > other; } + constexpr bool operator<=(int64_t other) const { return IntValue() <= other; } + constexpr bool operator>=(int64_t other) const { return IntValue() >= other; } + + friend constexpr bool operator==(int64_t a, const intN& b) { + return a == b.IntValue(); + } + friend constexpr bool operator!=(int64_t a, const intN& b) { + return a != b.IntValue(); + } + friend constexpr bool operator<(int64_t a, const intN& b) { + return a < b.IntValue(); + } + friend constexpr bool operator>(int64_t a, const intN& b) { + return a > b.IntValue(); + } + friend constexpr bool operator<=(int64_t a, const intN& b) { + return a <= b.IntValue(); + } + friend constexpr bool operator>=(int64_t a, const intN& b) { + return a >= b.IntValue(); + } + + constexpr intN& operator++() { + v_ = Mask(v_ + 1); + return *this; + } + + constexpr intN operator++(int) { + intN orig = *this; + this->operator++(); + return orig; + } + + constexpr intN& operator--() { + v_ = Mask(v_ - 1); + return *this; + } + + constexpr intN operator--(int) { + intN orig = *this; + this->operator--(); + return orig; + } + + constexpr intN& operator+=(const intN& other) { + *this = *this + other; + return *this; + } + constexpr intN& operator-=(const intN& other) { + *this = *this - other; + return *this; + } + constexpr intN& operator*=(const intN& other) { + *this = *this * other; + return *this; + } + constexpr intN& operator/=(const intN& other) { + *this = *this / other; + return *this; + } + constexpr intN& operator%=(const intN& other) { + *this = *this % other; + return *this; + } + constexpr intN& operator&=(const intN& other) { + *this = *this & other; + return *this; + } + constexpr intN& operator|=(const intN& other) { + *this = *this | other; + return *this; + } + constexpr intN& operator^=(const intN& other) { + *this = *this ^ other; + return *this; + } + constexpr intN& operator>>=(int amount) { + *this = *this >> amount; + return *this; + } + constexpr intN& operator<<=(int amount) { + *this = *this << amount; + return *this; + } + + friend ::std::ostream& operator<<(::std::ostream& os, const intN& num) { + os << static_cast<int16_t>(num); + return os; + } + + std::string ToString() const { + std::ostringstream os; + os << static_cast<int16_t>(*this); + return os.str(); + } +}; + +using int1 = intN<1, int8_t>; +using int2 = intN<2, int8_t>; +using uint1 = intN<1, uint8_t>; +using uint2 = intN<2, uint8_t>; +using int4 = intN<4, int8_t>; +using uint4 = intN<4, uint8_t>; + +namespace internal { + +template <typename intN> +struct intN_numeric_limits_base { + static inline constexpr const bool is_specialized = true; + static inline constexpr const bool is_integer = true; + static inline constexpr const bool is_exact = true; + static inline constexpr const bool has_infinity = false; + static inline constexpr const bool has_quiet_NaN = false; + static inline constexpr const bool has_signaling_NaN = false; + static inline constexpr const std::float_denorm_style has_denorm = + std::denorm_absent; + static inline constexpr const bool has_denorm_loss = false; + static inline constexpr const std::float_round_style round_style = + std::round_toward_zero; + static inline constexpr const bool is_iec559 = false; + static inline constexpr const bool is_bounded = true; + static inline constexpr const int max_digits10 = 0; // Not used for integers. + static inline constexpr const int radix = 2; + static inline constexpr const int min_exponent = 0; + static inline constexpr const int min_exponent10 = 0; + static inline constexpr const int max_exponent = 0; + static inline constexpr const int max_exponent10 = 0; + static inline constexpr const bool traps = true; + static inline constexpr const bool tinyness_before = false; + static inline constexpr const bool is_signed = + std::is_signed_v<typename intN::underlying_type>; + static inline constexpr const bool is_modulo = !is_signed; + static inline constexpr const int digits = intN::digits; + // floor(digits * log10(2)) + static inline constexpr const int digits10 = (digits * 3) / 10; + + static constexpr intN epsilon() noexcept { return intN(0); } + static constexpr intN round_error() noexcept { return intN(0); } + static constexpr intN infinity() noexcept { return intN(0); } + static constexpr intN quiet_NaN() noexcept { return intN(0); } + static constexpr intN signaling_NaN() noexcept { return intN(0); } + static constexpr intN denorm_min() noexcept { return intN(0); } + static constexpr intN min() noexcept { return intN::lowest(); } + static constexpr intN lowest() noexcept { return intN::lowest(); } + static constexpr intN max() noexcept { return intN::highest(); } +}; + +} // namespace internal + +} // namespace ml_dtypes + +namespace std { + +template <> +struct numeric_limits<ml_dtypes::int1> + : public ml_dtypes::internal::intN_numeric_limits_base<ml_dtypes::int1> {}; +template <> +struct numeric_limits<ml_dtypes::uint1> + : public ml_dtypes::internal::intN_numeric_limits_base<ml_dtypes::uint1> {}; +template <> +struct numeric_limits<ml_dtypes::int2> + : public ml_dtypes::internal::intN_numeric_limits_base<ml_dtypes::int2> {}; +template <> +struct numeric_limits<ml_dtypes::uint2> + : public ml_dtypes::internal::intN_numeric_limits_base<ml_dtypes::uint2> {}; +template <> +struct numeric_limits<ml_dtypes::int4> + : public ml_dtypes::internal::intN_numeric_limits_base<ml_dtypes::int4> {}; +template <> +struct numeric_limits<ml_dtypes::uint4> + : public ml_dtypes::internal::intN_numeric_limits_base<ml_dtypes::uint4> {}; + +} // namespace std + +#endif // ML_DTYPES_INTN_H_
diff --git a/third_party/ml_dtypes/src/ml_dtypes/include/mxfloat.h b/third_party/ml_dtypes/src/ml_dtypes/include/mxfloat.h new file mode 100644 index 0000000..01636b5 --- /dev/null +++ b/third_party/ml_dtypes/src/ml_dtypes/include/mxfloat.h
@@ -0,0 +1,386 @@ +/* Copyright 2024 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#ifndef ML_DTYPES_MXFLOAT_H_ +#define ML_DTYPES_MXFLOAT_H_ + +// Microscaling (MX) floating point formats, as described in +// https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf +// +// Note: this implements the underlying raw data types (e.g. E2M1FN), not the +// composite types (e.g. MXFP4). + +#include <cstdint> +#include <limits> + +#include "ml_dtypes/include/float8.h" +#include "Eigen/Core" + +namespace ml_dtypes { +namespace mxfloat_internal { + +// Use 8-bit storage for 6-bit and 4-bit types. +template <typename Derived> +class mxfloat6_base : public float8_internal::float8_base<Derived> { + using Base = float8_internal::float8_base<Derived>; + friend class float8_internal::float8_base<Derived>; + using Base::Base; + + public: + static constexpr int kBits = 6; + + explicit EIGEN_DEVICE_FUNC operator bool() const { + return (Base::rep() & 0x1F) != 0; + } + constexpr Derived operator-() const { + return Derived::FromRep(Base::rep() ^ 0x20); + } + Derived operator-(const Derived& other) const { + return Base::operator-(other); + } +}; + +template <typename Derived> +class mxfloat4_base : public float8_internal::float8_base<Derived> { + using Base = float8_internal::float8_base<Derived>; + friend class float8_internal::float8_base<Derived>; + using Base::Base; + + public: + static constexpr int kBits = 4; + + explicit EIGEN_DEVICE_FUNC operator bool() const { + return (Base::rep() & 0x07) != 0; + } + constexpr Derived operator-() const { + return Derived::FromRep(Base::rep() ^ 0x08); + } + Derived operator-(const Derived& other) const { + return Base::operator-(other); + } +}; + +class float6_e2m3fn : public mxfloat6_base<float6_e2m3fn> { + // Exponent: 2, Mantissa: 3, bias: 1. + // Extended range: no inf, no NaN. + using Base = mxfloat6_base<float6_e2m3fn>; + friend class float8_internal::float8_base<float6_e2m3fn>; + using Base::Base; + + public: + template <typename T, float8_internal::RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float6_e2m3fn(T f8) + : float6_e2m3fn(ConvertFrom(f8)) {} +}; + +class float6_e3m2fn : public mxfloat6_base<float6_e3m2fn> { + // Exponent: 3, Mantissa: 2, bias: 3. + // Extended range: no inf, no NaN. + using Base = mxfloat6_base<float6_e3m2fn>; + friend class float8_internal::float8_base<float6_e3m2fn>; + using Base::Base; + + public: + template <typename T, float8_internal::RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float6_e3m2fn(T f8) + : float6_e3m2fn(ConvertFrom(f8)) {} +}; + +class float4_e2m1fn : public mxfloat4_base<float4_e2m1fn> { + // Exponent: 2, Mantissa: 1, bias: 1. + // Extended range: no inf, no NaN. + using Base = mxfloat4_base<float4_e2m1fn>; + friend class float8_internal::float8_base<float4_e2m1fn>; + using Base::Base; + + public: + template <typename T, float8_internal::RequiresIsDerivedFromFloat8Base<T> = 0> + explicit EIGEN_DEVICE_FUNC float4_e2m1fn(T f8) + : float4_e2m1fn(ConvertFrom(f8)) {} +}; + +// Common properties for specializing std::numeric_limits. +template <int E, int M> +struct numeric_limits_mxfloat_tpl { + protected: + static constexpr int kExponentBias = (1 << (E - 1)) - 1; + static constexpr int kMantissaBits = M; + + public: + // NOLINTBEGIN: these names must match std::numeric_limits. + static constexpr bool is_specialized = true; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr std::float_denorm_style has_denorm = std::denorm_present; + static constexpr bool has_denorm_loss = false; + static constexpr std::float_round_style round_style = std::round_to_nearest; + static constexpr bool is_iec559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr int digits = kMantissaBits + 1; + static constexpr int digits10 = float8_internal::Digits10FromDigits(digits); + static constexpr int max_digits10 = + float8_internal::MaxDigits10FromDigits(digits); + static constexpr int radix = std::numeric_limits<float>::radix; + static constexpr int min_exponent = (1 - kExponentBias) + 1; + static constexpr int min_exponent10 = + float8_internal::MinExponent10FromMinExponent(min_exponent); + static constexpr int max_exponent = kExponentBias + 2; + static constexpr int max_exponent10 = + float8_internal::MaxExponent10FromMaxExponentAndDigits(max_exponent, + digits); + static constexpr bool traps = std::numeric_limits<float>::traps; + static constexpr bool tinyness_before = + std::numeric_limits<float>::tinyness_before; + // NOLINTEND +}; + +struct numeric_limits_float6_e2m3fn : public numeric_limits_mxfloat_tpl<2, 3> { + // 1.0 * 2^(0) = 1 + static constexpr float6_e2m3fn min() { + return float6_e2m3fn::FromRep(0b0'01'000); + } + // -1.875 * 2^(2) = -7.5 + static constexpr float6_e2m3fn lowest() { + return float6_e2m3fn::FromRep(0b1'11'111); + } + // 1.875 * 2^(2) = 7.5 + static constexpr float6_e2m3fn max() { + return float6_e2m3fn::FromRep(0b0'11'111); + } + // 0.125 * 2^(0) = 0.125 + static constexpr float6_e2m3fn epsilon() { + return float6_e2m3fn::FromRep(0b0'00'001); + } + // 0.25 * 2^(0) = 0.25 + static constexpr float6_e2m3fn round_error() { + return float6_e2m3fn::FromRep(0b0'00'010); + } + // 0.25 * 2^(0) = 0.125 + static constexpr float6_e2m3fn denorm_min() { + return float6_e2m3fn::FromRep(0b0'00'001); + } + + // Conversion from NaNs is implementation-defined (by MX specification). + static constexpr float6_e2m3fn quiet_NaN() { + return float6_e2m3fn::FromRep(0b1'00'000); + } + static constexpr float6_e2m3fn signaling_NaN() { + return float6_e2m3fn::FromRep(0b1'00'000); + } + static constexpr float6_e2m3fn infinity() { + return float6_e2m3fn::FromRep(0b0'11'111); + } +}; + +struct numeric_limits_float6_e3m2fn : public numeric_limits_mxfloat_tpl<3, 2> { + // 1.0 * 2^(-2) = 0.25 + static constexpr float6_e3m2fn min() { + return float6_e3m2fn::FromRep(0b0'001'00); + } + // -1.75 * 2^(4) = -28 + static constexpr float6_e3m2fn lowest() { + return float6_e3m2fn::FromRep(0b1'111'11); + } + // 1.75 * 2^(4) = 28 + static constexpr float6_e3m2fn max() { + return float6_e3m2fn::FromRep(0b0'111'11); + } + // 1.0 * 2^(-2) = 0.25 + static constexpr float6_e3m2fn epsilon() { + return float6_e3m2fn::FromRep(0b0'001'00); + } + // 1.0 * 2^(0) = 1 + static constexpr float6_e3m2fn round_error() { + return float6_e3m2fn::FromRep(0b0'011'00); + } + // 0.25 * 2^(-2) = 0.0625 + static constexpr float6_e3m2fn denorm_min() { + return float6_e3m2fn::FromRep(0b0'000'01); + } + + // Conversion from NaNs is implementation-defined (by MX specification). + static constexpr float6_e3m2fn quiet_NaN() { + return float6_e3m2fn::FromRep(0b1'000'00); + } + static constexpr float6_e3m2fn signaling_NaN() { + return float6_e3m2fn::FromRep(0b1'000'00); + } + static constexpr float6_e3m2fn infinity() { + return float6_e3m2fn::FromRep(0b0'111'11); + } +}; + +struct numeric_limits_float4_e2m1fn : public numeric_limits_mxfloat_tpl<2, 1> { + // 1.0 * 2^(0) = 1 + static constexpr float4_e2m1fn min() { + return float4_e2m1fn::FromRep(0b0'01'0); + } + // -1.5 * 2^(2) = -6 + static constexpr float4_e2m1fn lowest() { + return float4_e2m1fn::FromRep(0b1'11'1); + } + // 1.5 * 2^(2) = 6 + static constexpr float4_e2m1fn max() { + return float4_e2m1fn::FromRep(0b0'11'1); + } + // 0.5 * 2^(0) = 0.5 + static constexpr float4_e2m1fn epsilon() { + return float4_e2m1fn::FromRep(0b0'00'1); + } + // 1.0 * 2^(0) = 1 + static constexpr float4_e2m1fn round_error() { + return float4_e2m1fn::FromRep(0b0'01'0); + } + // 0.5 * 2^(0) = 0.5 + static constexpr float4_e2m1fn denorm_min() { + return float4_e2m1fn::FromRep(0b0'00'1); + } + + // Conversion from NaNs is implementation-defined (by MX specification). + static constexpr float4_e2m1fn quiet_NaN() { + return float4_e2m1fn::FromRep(0b1'00'0); + } + static constexpr float4_e2m1fn signaling_NaN() { + return float4_e2m1fn::FromRep(0b1'00'0); + } + static constexpr float4_e2m1fn infinity() { + return float4_e2m1fn::FromRep(0b0'11'1); + } +}; + +// Free-functions for use with ADL and in Eigen. +constexpr inline float6_e2m3fn abs(const float6_e2m3fn& a) { + return float6_e2m3fn::FromRep(a.rep() & 0b0'11'111); +} + +constexpr inline bool(isnan)(const float6_e2m3fn& a) { return false; } + +constexpr inline float6_e3m2fn abs(const float6_e3m2fn& a) { + return float6_e3m2fn::FromRep(a.rep() & 0b0'111'11); +} + +constexpr inline bool(isnan)(const float6_e3m2fn& a) { return false; } + +constexpr inline float4_e2m1fn abs(const float4_e2m1fn& a) { + return float4_e2m1fn::FromRep(a.rep() & 0b0'11'1); +} + +constexpr inline bool(isnan)(const float4_e2m1fn& a) { return false; } + +// Define traits required for floating point conversion. +template <typename T, int E, int M> +struct TraitsBase : public float8_internal::TraitsBase<T> { + static constexpr int kBits = E + M + 1; + static constexpr int kMantissaBits = M; + static constexpr int kExponentBits = E; + static constexpr int kExponentBias = (1 << (E - 1)) - 1; + static constexpr uint8_t kExponentMask = ((1 << E) - 1) << M; +}; + +} // namespace mxfloat_internal + +// Exported types. +using float6_e2m3fn = mxfloat_internal::float6_e2m3fn; +using float6_e3m2fn = mxfloat_internal::float6_e3m2fn; +using float4_e2m1fn = mxfloat_internal::float4_e2m1fn; + +} // namespace ml_dtypes + +// Standard library overrides. +namespace std { + +template <> +struct numeric_limits<ml_dtypes::mxfloat_internal::float6_e2m3fn> + : public ml_dtypes::mxfloat_internal::numeric_limits_float6_e2m3fn {}; + +template <> +struct numeric_limits<ml_dtypes::mxfloat_internal::float6_e3m2fn> + : public ml_dtypes::mxfloat_internal::numeric_limits_float6_e3m2fn {}; + +template <> +struct numeric_limits<ml_dtypes::mxfloat_internal::float4_e2m1fn> + : public ml_dtypes::mxfloat_internal::numeric_limits_float4_e2m1fn {}; + +} // namespace std + +// Conversion traits. +namespace ml_dtypes { +namespace float8_internal { + +template <> +struct Traits<float6_e2m3fn> + : public mxfloat_internal::TraitsBase<float6_e2m3fn, 2, 3> {}; + +template <> +struct Traits<float6_e3m2fn> + : public mxfloat_internal::TraitsBase<float6_e3m2fn, 3, 2> {}; + +template <> +struct Traits<float4_e2m1fn> + : public mxfloat_internal::TraitsBase<float4_e2m1fn, 2, 1> {}; + +} // namespace float8_internal +} // namespace ml_dtypes + +// Eigen library overrides. +namespace Eigen { +namespace numext { + +#define MXFLOAT_EIGEN_SIGNBIT_IMPL(Type) \ + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Type signbit(const Type& x) { \ + int8_t t = bit_cast<int8_t, Type>(x) << (8 - Type::kBits); \ + return bit_cast<Type, int8_t>(t >> 7); \ + } + +MXFLOAT_EIGEN_SIGNBIT_IMPL(ml_dtypes::float6_e2m3fn) +MXFLOAT_EIGEN_SIGNBIT_IMPL(ml_dtypes::float6_e3m2fn) +MXFLOAT_EIGEN_SIGNBIT_IMPL(ml_dtypes::float4_e2m1fn) + +#undef MXFLOAT_EIGEN_SIGNBIT_IMPL + +} // namespace numext + +// Work-around for isinf/isnan/isfinite issue on aarch64. +namespace internal { + +#define MXFLOAT_EIGEN_ISFINITE_IMPL(Type) \ + template <> \ + EIGEN_DEVICE_FUNC inline bool isinf_impl<Type>(const Type&) { \ + return false; \ + } \ + template <> \ + EIGEN_DEVICE_FUNC inline bool isnan_impl<Type>(const Type&) { \ + return false; \ + } \ + template <> \ + EIGEN_DEVICE_FUNC inline bool isfinite_impl<Type>(const Type&) { \ + return true; \ + } + +MXFLOAT_EIGEN_ISFINITE_IMPL(ml_dtypes::float6_e2m3fn) +MXFLOAT_EIGEN_ISFINITE_IMPL(ml_dtypes::float6_e3m2fn) +MXFLOAT_EIGEN_ISFINITE_IMPL(ml_dtypes::float4_e2m1fn) + +#undef MXFLOAT_EIGEN_ISFINITE_IMPL + +} // namespace internal +} // namespace Eigen + +#endif // ML_DTYPES_MXFLOAT_H_
diff --git a/third_party/ml_dtypes/update.sh b/third_party/ml_dtypes/update.sh new file mode 100755 index 0000000..37714d8 --- /dev/null +++ b/third_party/ml_dtypes/update.sh
@@ -0,0 +1,32 @@ +#!/bin/bash +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +set -e + +if [ $(basename ${PWD}) != "src" ]; then + echo "Please set the current working directory to chromium/src first!" + exit 1 +fi + +files=( + "LICENSE" + "ml_dtypes/include/float8.h" + "ml_dtypes/include/intn.h" + "ml_dtypes/include/mxfloat.h" +) + +git clone --depth 1 https://github.com/jax-ml/ml_dtypes /tmp/ml_dtypes +rm -rf third_party/ml_dtypes/src/* +pushd third_party/ml_dtypes/src/ > /dev/null + +for file in ${files[@]} ; do + if [ ! -d "$(dirname ${file})" ] ; then + mkdir -p "$(dirname ${file})" + fi + cp "/tmp/ml_dtypes/${file}" "${file}" +done + +popd > /dev/null +rm -rf /tmp/ml_dtypes
diff --git a/third_party/rust/PRESUBMIT.py b/third_party/rust/PRESUBMIT.py index 46ce15bc..ca1de795 100644 --- a/third_party/rust/PRESUBMIT.py +++ b/third_party/rust/PRESUBMIT.py
@@ -12,6 +12,7 @@ import re + def CheckForManualEditsOfGnrtAutogeneratedFiles(input_api, output_api): GNRT_INPUTS = [ "tools/crates/gnrt/.*",
diff --git a/third_party/rust/chromium_crates_io/.style.yapf b/third_party/rust/chromium_crates_io/.style.yapf new file mode 100644 index 0000000..4741fb4 --- /dev/null +++ b/third_party/rust/chromium_crates_io/.style.yapf
@@ -0,0 +1,3 @@ +[style] +based_on_style = pep8 +column_limit = 80
diff --git a/third_party/rust/chromium_crates_io/PRESUBMIT.py b/third_party/rust/chromium_crates_io/PRESUBMIT.py new file mode 100644 index 0000000..96f50a86 --- /dev/null +++ b/third_party/rust/chromium_crates_io/PRESUBMIT.py
@@ -0,0 +1,53 @@ +# Copyright 2024 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Presubmit for //third_party/rust/chromium_crates_io + +See https://www.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API built into depot_tools. +""" + +PRESUBMIT_VERSION = '2.0.0' + + +def CheckGnrtConfig(input_api, output_api): + # `input_files` lists files that are used as input by + # `third_party/rust/chromium_crates_io/check_gnrt_config.py`. + CARGO_LOCK_PATH = "third_party/rust/chromium_crates_io/Cargo.lock" + GNRT_CONFIG_PATH = "third_party/rust/chromium_crates_io/gnrt_config.toml" + input_files = set([CARGO_LOCK_PATH, GNRT_CONFIG_PATH]) + + # Exit early if no `input_files` are affected by the current CL. + affected_paths = set( + map(lambda f: f.UnixLocalPath(), input_api.change.AffectedFiles())) + if not input_files.intersection(affected_paths): + return [] + + # Delegate actual checks to `check_gnrt_config.py` (one reason is that we + # can't apparently `import toml` in `PRESUBMIT.py`). + test_script_path = input_api.os_path.join(input_api.PresubmitLocalPath(), + "check_gnrt_config.py") + cmd_name = '//third_party/rust/chromium_crates_io/check_gnrt_config.py' + test_cmd = input_api.Command( + name=cmd_name, + cmd=[input_api.python_executable, test_script_path], + kwargs={}, + message=output_api.PresubmitError) + if input_api.verbose: + print('Running ' + cmd_name) + return input_api.RunTests([test_cmd]) + + +def CheckPythonUnittestsPass(input_api, output_api): + results = [] + this_dir = input_api.PresubmitLocalPath() + + results += input_api.RunTests( + input_api.canned_checks.GetUnitTestsInDirectory( + input_api, + output_api, + this_dir, + files_to_check=['.*unittest.*\.py$'], + env=None)) + + return results
diff --git a/third_party/rust/chromium_crates_io/check_gnrt_config.py b/third_party/rust/chromium_crates_io/check_gnrt_config.py new file mode 100755 index 0000000..5f4cf51 --- /dev/null +++ b/third_party/rust/chromium_crates_io/check_gnrt_config.py
@@ -0,0 +1,133 @@ +#!/usr/bin/env vpython3 + +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This script checks for issues in: +# * `//third_party/rust/chromium_crates_io/Cargo.lock` and +# * `//third_party/rust/chromium_crates_io/gnrt_config.toml`. +# +# We don't surface these issues earlier (by reporting a fatal error from `gnrt +# vendor`, `gnrt gen`, `gn gen`, or failing the builds), because we want to +# avoid friction when new teams experiment with using Rust. Some of these +# issues may also happen during the crate update rotation and in this case we +# want to allow the `tools/crate/create_update_cl.py` to continue creating CLs +# (that other script uses `git cl upload ... --bypass-hooks`). +# +# This script is typically not invoked directly, but instead is invoked as part +# of `//third_party/rust/PRESUBMIT.py` + +import os +import sys +import toml + +import crate_utils + +CRATES_DIR = os.path.normpath(os.path.dirname(__file__)) +GNRT_CONFIG_PATH = os.path.join(CRATES_DIR, 'gnrt_config.toml') + + +def _GetCrateConfigForCrateName(crate_name, gnrt_config): + if gnrt_config and isinstance(gnrt_config, dict): + crates = gnrt_config.get("crate") + if crates and isinstance(crates, dict): + crate_cfg = crates.get(crate_name) + if crate_cfg and isinstance(crate_cfg, dict): + return crate_cfg + return dict() + + +def _GetExtraKvForCrateName(crate_name, gnrt_config): + crate_cfg = _GetCrateConfigForCrateName(crate_name, gnrt_config) + extra_kv = crate_cfg.get("extra_kv") + if extra_kv and isinstance(extra_kv, dict): + return extra_kv + return dict() + + +def CheckMultiversionCrates(crate_ids, gnrt_config): + """Checks that a bug tracks each crate with multiple versions. + + This check has been discussed in https://crbug.com/404867240. Having 2 + or more different versions of a crate in Chromium's dependency tree is + undesirable in general. So we want to detect when a 2nd version is + imported, and require opening a bug + recording the bug in + `gnrt_config.toml` for the given crate. + + Returns an error message if a problem is detected. + Returns an empty string if there are no problems. + """ + + # Group `crate_id`s by their `crate_name`. + crate_name_to_list_of_crate_ids = dict() + for crate_id in crate_ids: + crate_name = crate_utils.ConvertCrateIdToCrateName(crate_id) + if crate_name not in crate_name_to_list_of_crate_ids: + crate_name_to_list_of_crate_ids[crate_name] = [] + crate_name_to_list_of_crate_ids[crate_name] += [crate_id] + + result = [] + for (crate_name, crate_ids) in crate_name_to_list_of_crate_ids.items(): + # Ignore crates where we depend only on a single version. + if len(crate_ids) == 1: + continue + + # Ignore crates that already have a bug to track cleaning up a + # multiversion situation. + extra_kv = _GetExtraKvForCrateName(crate_name, gnrt_config) + if "multiversion_cleanup_bug" in extra_kv: + continue + + # Report a problem for other multiversion crates. + if not result: # Is is the **first** problematic `crate_name`? + result.append("ERROR: Transitive dependency graph includes " + \ + "multiple versions of the same crate. Please " + \ + "open a bug to track removing one of the " + \ + "versions and put a link to the bug into " + \ + "`gnrt_config.toml` like this:") + result.append("") + + result += [ + f" # TODO: Remove multiple versions of the `{crate_name}` crate:", + f" # {', '.join(sorted(crate_ids))}", + f" [crate.{crate_name}.extra_kv]", + f' multiversion_cleanup_bug = "https://crbug.com/<bug number>"\n', + ] + + return "\n".join(result) + + +def main(): + crate_ids = crate_utils.GetCurrentCrateIds() + gnrt_config = toml.load(open(GNRT_CONFIG_PATH)) + + success = True + + def RunChecks(check_impl): + result = check_impl(crate_ids, gnrt_config) + if result: + if not success: + # Add a separator if this is a 2nd, 3rd, or later problem. + print() + print("-" * 72) + print() + success = False + print(result) + + RunChecks(CheckMultiversionCrates) + + # TODO(https://crbug.com/399931417): RunChecks(CheckExplicitAllowUnsafeForAllCrates). + + # TODO(https://crbug.com/399935219): RunChecks(CheckNonapplicableGnrtConfigEntries). + # Move the useless-entry-in-gnrt_config check from `gnrt` into this script. + # Consider also adding CheckNonapplicablePatches. + + if success: + return 0 + else: + return -1 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/third_party/rust/chromium_crates_io/check_gnrt_config_unittests.py b/third_party/rust/chromium_crates_io/check_gnrt_config_unittests.py new file mode 100755 index 0000000..c01ab16 --- /dev/null +++ b/third_party/rust/chromium_crates_io/check_gnrt_config_unittests.py
@@ -0,0 +1,77 @@ +#!/usr/bin/env vpython3 + +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import unittest + +from check_gnrt_config import ( + _GetExtraKvForCrateName, + CheckMultiversionCrates, +) + + +class CheckMultiversionCratesTests(unittest.TestCase): + + def testNoMultiversionCrates(self): + crate_ids = set(["foo@1.2.3", "bar@4.5.6"]) + gnrt_config = {} + self.assertEqual("", CheckMultiversionCrates(crate_ids, gnrt_config)) + + def testBugLinkPresent(self): + crate_ids = set(["foo@1.2.3", "foo@4.5.6"]) + gnrt_config = { + "crate": { + "foo": { + "extra_kv": { + "multiversion_cleanup_bug": "blah" + } + } + } + } + self.assertEqual("", CheckMultiversionCrates(crate_ids, gnrt_config)) + + def testProblemDetection(self): + crate_ids = set(["foo@1.2.3", "foo@4.5.6"]) + gnrt_config = {} + msg = CheckMultiversionCrates(crate_ids, gnrt_config) + self.assertTrue("multiple versions of the same crate" in msg) + self.assertTrue("foo@1.2.3, foo@4.5.6" in msg) + self.assertTrue("[crate.foo.extra_kv]" in msg) + self.assertTrue("multiversion_cleanup_bug = " in msg) + + +class GetExtraKvForCrateNameTests(unittest.TestCase): + + def testHappyPath(self): + gnrt_config = {"crate": {"foo": {"extra_kv": {"entry": 123}}}} + extra_kv = _GetExtraKvForCrateName("foo", gnrt_config) + self.assertEqual({"entry": 123}, extra_kv) + + def testMissingExtraKv(self): + """ Verify an empty dictionary is a fallback when no `extra_kv`. """ + gnrt_config = {"crate": {"foo": {"bar": 123}}} + extra_kv = _GetExtraKvForCrateName("foo", gnrt_config) + self.assertEqual({}, extra_kv) + + def testMissingCrateEntry(self): + gnrt_config = {"crate": {"other_crate": {"extra_kv": {"entry": 123}}}} + extra_kv = _GetExtraKvForCrateName("foo", gnrt_config) + self.assertEqual({}, extra_kv) + + def testMistypedExtraKv(self): + """ Test fallback behavior when `extra_kv` is not a dictionary. """ + gnrt_config = {"crate": {"foo": {"extra_kv": 123}}} + extra_kv = _GetExtraKvForCrateName("foo", gnrt_config) + self.assertEqual({}, extra_kv) + + def testEmptyConfigSuchAsUsedInSomeTestsHere(self): + gnrt_config = {} + extra_kv = _GetExtraKvForCrateName("foo", gnrt_config) + self.assertEqual({}, extra_kv) + + +if __name__ == '__main__': + unittest.main()
diff --git a/third_party/rust/chromium_crates_io/crate_utils.py b/third_party/rust/chromium_crates_io/crate_utils.py new file mode 100755 index 0000000..f8841fe9 --- /dev/null +++ b/third_party/rust/chromium_crates_io/crate_utils.py
@@ -0,0 +1,120 @@ +#!/usr/bin/env vpython3 + +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This module contains utilities for working with information from +# `//third_party/rust/chromium_crates_io/Cargo.lock`. +# +# Throughout the module, the following naming conventions are used (illustrated +# with a crate named `syn` and published as version `2.0.50`): +# +# * `crate_name` : "syn" string +# * `crate_version`: "2.0.50" string +# * `crate_id` : "syn@2.0.50" string (syntax used by `cargo`) +# * `crate_epoch` : "v2" string (syntax used in dir names under +# //third_party/rust/<crate name>/<crate epoch>) +# +# Note that `crate_name` may not be unique (e.g. if there is both `syn@1.0.109` +# and `syn@2.0.50`). Also note that f`{crate_name}@{crate_epoch}` doesn't +# change during a minor version update (such as the one that this script + +import os +import sys +import toml +from typing import Set + +THIS_DIR = os.path.dirname(__file__) +CHROMIUM_DIR = os.path.normpath(os.path.join(THIS_DIR, '..', '..', '..')) +THIRD_PARTY_RUST_DIR = os.path.join(CHROMIUM_DIR, "third_party", "rust") +CRATES_DIR = os.path.join(THIRD_PARTY_RUST_DIR, "chromium_crates_io") +CARGO_LOCK_FILEPATH = os.path.join(CRATES_DIR, 'Cargo.lock') +VENDOR_DIR = os.path.join(CRATES_DIR, "vendor") + + +def GetCurrentCrateIds() -> Set[str]: + """Parses Cargo.lock and returns a set of crate ids. + + Example return value: `set(["serde@1.0.197", "syn@2.0.50", ...])`. + """ + with open(CARGO_LOCK_FILEPATH) as f: + t = toml.load(f) + result = set() + for p in t["package"]: + name = p["name"] + version = p["version"] + crate_id = f"{name}@{version}" + assert crate_id not in result + result.add(crate_id) + return result + + +def ConvertCrateIdToCrateEpoch(crate_id: str) -> str: + crate_version = ConvertCrateIdToCrateVersion(crate_id) + v = crate_version.split('.') + if v[0] == '0': + return f'v0_{v[1]}' + return f'v{v[0]}' + + +def ConvertCrateIdToCrateName(crate_id: str) -> str: + """ Converts a `crate_id` into a `crate_name`.""" + return crate_id[:crate_id.find("@")] + + +def ConvertCrateIdToCrateVersion(crate_id: str) -> str: + """ Converts a `crate_id` into a `crate_version`.""" + crate_version = crate_id[crate_id.find("@") + 1:] + return crate_version + + +def ConvertCrateIdToBuildDir(crate_id: str) -> str: + """ Converts a `crate_id` (e.g. "foo@1.2.3") into a path to an epoch dir. + + Example return value: + `"<path to chromium root>\\third_party\\rust\\foo\\v1"` + """ + return os.path.join( + CHROMIUM_DIR, _ConvertCrateIdToBuildDirRelativeToChromiumRoot(crate_id)) + + +def ConvertCrateIdToVendorDir(crate_id: str) -> str: + """ Converts a `crate_id` (e.g. "foo@1.2.3") into a path to a target dir. + + Example return value: + `"<path to chromium root>\\third_party\\rust\\chromium_crates_io\\vendor\\foo-v1"` + """ + crate_name = ConvertCrateIdToCrateName(crate_id) + crate_epoch = ConvertCrateIdToCrateEpoch(crate_id) + crate_vendor_dir = os.path.join(VENDOR_DIR, f"{crate_name}-{crate_epoch}") + return crate_vendor_dir + + +def ConvertCrateIdToGnLabel(crate_id: str) -> str: + """ Converts a `crate_id` (e.g. "foo@1.2.3") into a GN label. + + See also + https://gn.googlesource.com/gn/+/main/docs/reference.md#labels + + Example return value: `"//third_party/rust/foo/v1:lib"` + """ + dir_name = _ConvertCrateIdToBuildDirRelativeToChromiumRoot(crate_id) + dir_name = dir_name.replace(os.sep, "/") # GN uses `/` as a path separator. + return f"//{dir_name}:lib" + + +def _ConvertCrateIdToBuildDirRelativeToChromiumRoot(crate_id: str) -> str: + """ Converts a `crate_id` (e.g. "foo@1.2.3") into an epoch dir. + + The returned dir is relative to Chromium root. + Example return value: `"//third_party/rust/foo/v1"` + """ + crate_name = ConvertCrateIdToCrateName(crate_id) + crate_name = crate_name.replace("-", "_") + epoch = ConvertCrateIdToCrateEpoch(crate_id) + target = os.path.join("third_party", "rust", crate_name, epoch) + return target + + +assert __name__ != '__main__'
diff --git a/third_party/rust/chromium_crates_io/crate_utils_unittests.py b/third_party/rust/chromium_crates_io/crate_utils_unittests.py new file mode 100755 index 0000000..b453995 --- /dev/null +++ b/third_party/rust/chromium_crates_io/crate_utils_unittests.py
@@ -0,0 +1,73 @@ +#!/usr/bin/env vpython3 + +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import unittest + +from crate_utils import ( + CHROMIUM_DIR, + ConvertCrateIdToCrateEpoch, + ConvertCrateIdToCrateName, + ConvertCrateIdToCrateVersion, + ConvertCrateIdToBuildDir, + ConvertCrateIdToGnLabel, + ConvertCrateIdToVendorDir, + GetCurrentCrateIds, +) + + +class CrateUtilsTests(unittest.TestCase): + + def testGetCurrentCrateIds(self): + crate_ids = GetCurrentCrateIds() + self.assertTrue(crate_ids) + + def testConvertCrateIdToCrateEpoch(self): + self.assertEqual(ConvertCrateIdToCrateEpoch("foo@0.1.2"), "v0_1") + self.assertEqual(ConvertCrateIdToCrateEpoch("foo@1.2.3"), "v1") + + def testConvertCrateIdToBuildDir(self): + actual_dir = ConvertCrateIdToBuildDir("foo-bar@1.2.3") + expected_suffix = os.path.join("third_party", "rust", "foo_bar", "v1") + self.assertEqual(actual_dir, os.path.join(CHROMIUM_DIR, + expected_suffix)) + + actual_dir = ConvertCrateIdToBuildDir("bar_baz@0.12.3") + expected_suffix = os.path.join("third_party", "rust", "bar_baz", + "v0_12") + self.assertEqual(actual_dir, os.path.join(CHROMIUM_DIR, + expected_suffix)) + + def testConvertCrateIdToGnLabel(self): + self.assertEqual(ConvertCrateIdToGnLabel("foo-bar@1.2.3"), + "//third_party/rust/foo_bar/v1:lib") + self.assertEqual(ConvertCrateIdToGnLabel("bar_baz@0.12.3"), + "//third_party/rust/bar_baz/v0_12:lib") + + def testConvertCrateIdToVendorDir(self): + actual_dir = ConvertCrateIdToVendorDir("foo-bar@1.2.3") + expected_suffix = os.path.join("third_party", "rust", + "chromium_crates_io", "vendor", + "foo-bar-v1") + self.assertEqual(actual_dir, os.path.join(CHROMIUM_DIR, + expected_suffix)) + + actual_dir = ConvertCrateIdToVendorDir("bar_baz@0.12.3") + expected_suffix = os.path.join("third_party", "rust", + "chromium_crates_io", "vendor", + "bar_baz-v0_12") + self.assertEqual(actual_dir, os.path.join(CHROMIUM_DIR, + expected_suffix)) + + def testConvertCrateIdToCrateName(self): + self.assertEqual(ConvertCrateIdToCrateName("foo-bar@1.2.3"), "foo-bar") + + def testConvertCrateIdToCrateVersion(self): + self.assertEqual(ConvertCrateIdToCrateVersion("foo-bar@1.2.3"), "1.2.3") + + +if __name__ == '__main__': + unittest.main()
diff --git a/third_party/skia b/third_party/skia index 504ccf4..c140738 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit 504ccf45fba464bf74b396cc686494629f37b718 +Subproject commit c1407387eeaf31674891a4d12505970d3237e86f
diff --git a/tools/accessibility/rebase_dump_accessibility_tree_tests.py b/tools/accessibility/rebase_dump_accessibility_tree_tests.py index 075a2385..bd2c60a 100755 --- a/tools/accessibility/rebase_dump_accessibility_tree_tests.py +++ b/tools/accessibility/rebase_dump_accessibility_tree_tests.py
@@ -140,7 +140,8 @@ capture_output=True, text=True, ).stdout): - raise ValueError('Did not find an issue attached to the current branch.') + raise ValueError('Did not find an issue attached to the current branch. ' + 'Note for Googlers: you might just need to run gcert.') return json.loads(output)
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 420c106..316567b 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -39,8 +39,8 @@ # These fields are written by //tools/clang/scripts/upload_revision.py, and # should not be changed manually. # They are also read by build/config/compiler/BUILD.gn. -CLANG_REVISION = 'llvmorg-21-init-9266-g09006611' -CLANG_SUB_REVISION = 2 +CLANG_REVISION = 'llvmorg-21-init-11777-gfd3fecfc' +CLANG_SUB_REVISION = 1 PACKAGE_VERSION = '%s-%s' % (CLANG_REVISION, CLANG_SUB_REVISION) RELEASE_VERSION = '21'
diff --git a/tools/crates/create_update_cl.py b/tools/crates/create_update_cl.py index c0cf940..3c1d329f 100755 --- a/tools/crates/create_update_cl.py +++ b/tools/crates/create_update_cl.py
@@ -21,8 +21,25 @@ from dataclasses import dataclass from typing import List, Set, Dict -# Throughout the script, the following naming conventions are used (illustrated -# with a crate named `syn` and published as version `2.0.50`): +THIS_DIR = os.path.dirname(__file__) +CHROMIUM_DIR = os.path.normpath(os.path.join(THIS_DIR, '..', '..')) +THIRD_PARTY_RUST = os.path.join(CHROMIUM_DIR, "third_party", "rust") +CRATES_DIR = os.path.join(THIRD_PARTY_RUST, "chromium_crates_io") +VENDOR_DIR = os.path.join(CRATES_DIR, "vendor") +INCLUSIVE_LANG_SCRIPT = os.path.join( + CHROMIUM_DIR, "infra", "update_inclusive_language_presubmit_exempt_dirs.sh") +INCLUSIVE_LANG_CONFIG = os.path.join( + CHROMIUM_DIR, "infra", "inclusive_language_presubmit_exempt_dirs.txt") +RUN_GNRT = os.path.join(THIS_DIR, "run_gnrt.py") +UPDATE_RUST_SCRIPT = os.path.join(CHROMIUM_DIR, "tools", "rust", + "update_rust.py") + +sys.path.append(CRATES_DIR) +import crate_utils + +# As in `third_party/rust/chromium_crates_io/crate_utils.py`, the following +# naming conventions are used in this script (illustrated with a crate named +# `syn` and published as version `2.0.50`): # # * `crate_name` : "syn" string # * `crate_version`: "2.0.50" string @@ -35,20 +52,6 @@ # change during a minor version update (such as the one that this script # produces in `auto` and `single` modes). -THIS_DIR = os.path.dirname(__file__) -CHROMIUM_DIR = os.path.normpath(os.path.join(THIS_DIR, '..', '..')) -THIRD_PARTY_RUST = os.path.join(CHROMIUM_DIR, "third_party", "rust") -CRATES_DIR = os.path.join(THIRD_PARTY_RUST, "chromium_crates_io") -VENDOR_DIR = os.path.join(CRATES_DIR, "vendor") -CARGO_LOCK = os.path.join(CRATES_DIR, "Cargo.lock") -INCLUSIVE_LANG_SCRIPT = os.path.join( - CHROMIUM_DIR, "infra", "update_inclusive_language_presubmit_exempt_dirs.sh") -INCLUSIVE_LANG_CONFIG = os.path.join( - CHROMIUM_DIR, "infra", "inclusive_language_presubmit_exempt_dirs.txt") -RUN_GNRT = os.path.join(THIS_DIR, "run_gnrt.py") -UPDATE_RUST_SCRIPT = os.path.join(CHROMIUM_DIR, "tools", "rust", - "update_rust.py") - g_is_verbose = False timestamp = datetime.datetime.now() @@ -121,10 +124,10 @@ def GnrtUpdateCrate(old_crate_id: str, new_crate_id: str, check_stdout: bool, check_exitcode: bool): - old_crate_version = ConvertCrateIdToCrateVersion(old_crate_id) - new_crate_version = ConvertCrateIdToCrateVersion(new_crate_id) - old_epoch = GetEpoch(old_crate_version) - new_epoch = GetEpoch(new_crate_version) + old_crate_version = crate_utils.ConvertCrateIdToCrateVersion(old_crate_id) + new_crate_version = crate_utils.ConvertCrateIdToCrateVersion(new_crate_id) + old_epoch = crate_utils.ConvertCrateIdToCrateEpoch(old_crate_id) + new_epoch = crate_utils.ConvertCrateIdToCrateEpoch(new_crate_id) is_major_update = (old_epoch != new_epoch) cargo_update_args = [old_crate_id, "--precise", f"{new_crate_version}"] @@ -136,31 +139,19 @@ check_exitcode=check_exitcode) -def GetCurrentCrateIds() -> Set[str]: - """Parses Cargo.lock and returns a set of crate ids - (e.g. "serde@1.0.197", "syn@2.0.50", ...).""" - t = toml.load(open(CARGO_LOCK)) - result = set() - for p in t["package"]: - name = p["name"] - version = p["version"] - crate_id = f"{name}@{version}" - assert crate_id not in result - result.add(crate_id) - return result - - @dataclass(eq=True, order=True) class UpdatedCrate: old_crate_id: str new_crate_id: str def __str__(self): - name = ConvertCrateIdToCrateName(self.old_crate_id) - assert name == ConvertCrateIdToCrateName(self.new_crate_id) + name = crate_utils.ConvertCrateIdToCrateName(self.old_crate_id) + assert name == crate_utils.ConvertCrateIdToCrateName(self.new_crate_id) - old_version = ConvertCrateIdToCrateVersion(self.old_crate_id) - new_version = ConvertCrateIdToCrateVersion(self.new_crate_id) + old_version = crate_utils.ConvertCrateIdToCrateVersion( + self.old_crate_id) + new_version = crate_utils.ConvertCrateIdToCrateVersion( + self.new_crate_id) return f"{name}: {old_version} => {new_version}" @@ -193,10 +184,10 @@ that it will be stable for tracking a crate version across updates.""" result = dict() for crate_id in crate_ids: - name = ConvertCrateIdToCrateName(crate_id) - version = ConvertCrateIdToCrateVersion(crate_id) + name = crate_utils.ConvertCrateIdToCrateName(crate_id) + version = crate_utils.ConvertCrateIdToCrateVersion(crate_id) if only_minor_updates: - epoch = GetEpoch(version) + epoch = crate_utils.ConvertCrateIdToCrateEpoch(crate_id) key = f'{name}@{epoch}' else: key = name @@ -236,62 +227,6 @@ sorted(added_crate_ids)) -def GetEpoch(crate_version: str) -> str: - v = crate_version.split('.') - if v[0] == '0': - return f'v0_{v[1]}' - return f'v{v[0]}' - - -def ConvertCrateIdToCrateName(crate_id: str) -> str: - """ Converts a `crate_id` into a `crate_name`.""" - return crate_id[:crate_id.find("@")] - - -def ConvertCrateIdToCrateVersion(crate_id: str) -> str: - """ Converts a `crate_id` into a `crate_version`.""" - crate_version = crate_id[crate_id.find("@") + 1:] - return crate_version - - -def _ConvertCrateIdToEpochDirRelativeToChromiumRoot(crate_id: str) -> str: - """ Converts a `crate_id` (e.g. "foo@1.2.3") into an epoch dir - (e.g. "third_party/rust/foo/v_1"). The returned dir is relative - to Chromium root. """ - crate_name = ConvertCrateIdToCrateName(crate_id) - crate_name = crate_name.replace("-", "_") - epoch = GetEpoch(ConvertCrateIdToCrateVersion(crate_id)) - target = os.path.join("third_party", "rust", crate_name, epoch) - return target - - -def ConvertCrateIdToEpochDir(crate_id: str) -> str: - """ Converts a `crate_id` (e.g. "foo@1.2.3") into a path to an epoch dir - (e.g. on Windows: "<path to chromium root>\\third_party\\rust\\foo\\v_1"). - """ - return os.path.join( - CHROMIUM_DIR, _ConvertCrateIdToEpochDirRelativeToChromiumRoot(crate_id)) - - -def ConvertCrateIdToVendorDir(crate_id: str) -> str: - """ Converts a `crate_id` (e.g. "foo@1.2.3") into a path to a target dir - (e.g. on Windows: "<path to chromium root>\\third_party\\rust\\foo\\v_1"). - """ - crate_name = ConvertCrateIdToCrateName(crate_id) - crate_epoch = GetEpoch(ConvertCrateIdToCrateVersion(crate_id)) - crate_vendor_dir = os.path.join(VENDOR_DIR, f"{crate_name}-{crate_epoch}") - return crate_vendor_dir - - -def ConvertCrateIdToGnLabel(crate_id: str) -> str: - """ Converts a `crate_id` (e.g. "foo@1.2.3") into - [a GN label](https://gn.googlesource.com/gn/+/main/docs/reference.md#labels) - (e.g. "//third_party/rust/foo/v_1:lib"). """ - dir_name = _ConvertCrateIdToEpochDirRelativeToChromiumRoot(crate_id) - dir_name = dir_name.replace(os.sep, "/") # GN uses `/` as a path separator. - return f"//{dir_name}:lib" - - def DoArgsAskForBreakingChanges(cargo_update_args) -> bool: # Hardcoding implementation details of `cargo update` is a bit icky, but it # helps to ensure that `DiffCrateIds` won't see dictionary key conflicts. @@ -304,17 +239,19 @@ (Idempotent - afterwards it runs `git reset --hard` to undo any changes.)""" print("Checking which crates can be updated...") assert not IsGitDirty() # No local changes expected here. - old_crate_ids = GetCurrentCrateIds() + old_crate_ids = crate_utils.GetCurrentCrateIds() GnrtUpdate(args.remaining_args, check_stdout=False, check_exitcode=False) - new_crate_ids = GetCurrentCrateIds() + new_crate_ids = crate_utils.GetCurrentCrateIds() Git("reset", "--hard") only_minor_updates = not DoArgsAskForBreakingChanges(args.remaining_args) diff = DiffCrateIds(old_crate_ids, new_crate_ids, only_minor_updates) crate_updates = [(update.old_crate_id, update.new_crate_id) for update in diff.updates] if crate_updates: - names = sorted( - [ConvertCrateIdToCrateName(id) for (id, _) in crate_updates]) + names = sorted([ + crate_utils.ConvertCrateIdToCrateName(id) + for (id, _) in crate_updates + ]) names = f"{', '.join(names)}" text = f"Found updates for {len(crate_updates)} crates: {names}" print("\n".join(textwrap.wrap(text, 80))) @@ -330,12 +267,12 @@ print( f"Measuring the delta of updating {old_crate_id} => {new_crate_id}...") assert not IsGitDirty() # No local changes expected here. - old_crate_ids = GetCurrentCrateIds() + old_crate_ids = crate_utils.GetCurrentCrateIds() GnrtUpdateCrate(old_crate_id, new_crate_id, check_stdout=False, check_exitcode=False) - new_crate_ids = GetCurrentCrateIds() + new_crate_ids = crate_utils.GetCurrentCrateIds() Git("reset", "--hard") diff = DiffCrateIds(old_crate_ids, new_crate_ids, only_minor_updates) return diff.size() @@ -355,9 +292,9 @@ def CreateCommitTitle(old_crate_id: str, new_crate_id: str) -> str: - crate_name = ConvertCrateIdToCrateName(old_crate_id) - old_version = ConvertCrateIdToCrateVersion(old_crate_id) - new_version = ConvertCrateIdToCrateVersion(new_crate_id) + crate_name = crate_utils.ConvertCrateIdToCrateName(old_crate_id) + old_version = crate_utils.ConvertCrateIdToCrateVersion(old_crate_id) + new_version = crate_utils.ConvertCrateIdToCrateVersion(new_crate_id) roll_summary = f"{crate_name}: " + \ f"{old_version} => {new_version}" title = f"Roll {roll_summary} in //third_party/rust." @@ -421,13 +358,13 @@ assert not IsGitDirty() # No local changes expected here. # gnrt update - old_crate_ids = GetCurrentCrateIds() + old_crate_ids = crate_utils.GetCurrentCrateIds() print(f" Running `gnrt update` for {old_crate_id} => {new_crate_id} ...") GnrtUpdateCrate(old_crate_id, new_crate_id, check_stdout=True, check_exitcode=True) - new_crate_ids = GetCurrentCrateIds() + new_crate_ids = crate_utils.GetCurrentCrateIds() if old_crate_ids == new_crate_ids: print(" `gnrt update` resulted in no changes - "\ "maybe other steps will handle this crate...") @@ -461,13 +398,15 @@ for update in diff.updates: updated_old_crate_ids.add(update.old_crate_id) - old_dir = ConvertCrateIdToVendorDir(update.old_crate_id) - new_dir = ConvertCrateIdToVendorDir(update.new_crate_id) + old_dir = crate_utils.ConvertCrateIdToVendorDir(update.old_crate_id) + new_dir = crate_utils.ConvertCrateIdToVendorDir(update.new_crate_id) if old_dir != new_dir: Git("mv", "--force", f"{old_dir}", f"{new_dir}") - old_target_dir = ConvertCrateIdToEpochDir(update.old_crate_id) - new_target_dir = ConvertCrateIdToEpochDir(update.new_crate_id) + old_target_dir = crate_utils.ConvertCrateIdToBuildDir( + update.old_crate_id) + new_target_dir = crate_utils.ConvertCrateIdToBuildDir( + update.new_crate_id) if old_target_dir != new_target_dir: Git("mv", "--force", old_target_dir, new_target_dir) GitAddRustFiles() @@ -504,8 +443,10 @@ # (in case this is a major version update) print(f" Removing //third_party/rust/.../<old_epoch> ...") for update in diff.updates: - old_target_dir = ConvertCrateIdToEpochDir(update.old_crate_id) - new_target_dir = ConvertCrateIdToEpochDir(update.new_crate_id) + old_target_dir = crate_utils.ConvertCrateIdToBuildDir( + update.old_crate_id) + new_target_dir = crate_utils.ConvertCrateIdToBuildDir( + update.new_crate_id) if old_target_dir == new_target_dir: continue # Skip minor crate updates @@ -532,8 +473,8 @@ # (in case this is a major version update) print(f" Updating the target name in BUILD.gn files...") for update in diff.updates: - old_target = ConvertCrateIdToGnLabel(update.old_crate_id) - new_target = ConvertCrateIdToGnLabel(update.new_crate_id) + old_target = crate_utils.ConvertCrateIdToGnLabel(update.old_crate_id) + new_target = crate_utils.ConvertCrateIdToGnLabel(update.new_crate_id) if old_target == new_target: continue # `check_exitcode=False` to gracefully handle no hits. grep = RunCommandAndCheckForErrors( @@ -601,8 +542,10 @@ def GitClUpload(*args): - # TODO(https://crbug.com/405980483): Remove `--bypass-hooks`, or document - # why this is still needed. + # `--bypass-hooks` to avoid disrupting the process of creating update CLs by + # `//third_party/rust/PRESUBMIT.py` (e.g. it's okay to add + # `multiversion_cleanup_bug` to `gnrt_config.toml` later, before landing the + # CLs). # # `-o banned-words-skip` is used, because the CL is auto-generated and only # modifies third-party libraries (where any banned words would be purely @@ -632,45 +575,16 @@ return False -def ResolveCrateNameToCrateId(crate_name): - """Parses `Cargo.toml` to resolve `crate_name` into "crate-name@1.2.3". - Throws if `crate_name` can't be resolved. - - Parameters: - crate_name: Either "crate-name" or already "crate-name@1.2.3" - """ - t = toml.load(open(CARGO_LOCK)) - if '@' in crate_name: - resolved_crate_version = ConvertCrateIdToCrateVersion(crate_name) - resolved_crate_name = ConvertCrateIdToCrateName(crate_name) - else: - same_name = [p for p in t["package"] if p["name"] == crate_name] - if len(same_name) == 0: - raise RuntimeError( - f"`Cargo.toml` has no crates matching `{crate_name}`") - elif len(same_name) > 1: - ver1 = same_name[0]["version"] - ver2 = same_name[1]["version"] - raise RuntimeError( - f"Ambiguous argument - specify which old version to update, "\ - f"e.g. `{crate_name}@{ver1}` or `{crate_name}@{ver2}") - resolved_crate_name = crate_name - resolved_crate_version = same_name[0]["version"] - - crate_id = f"{resolved_crate_name}@{resolved_crate_version}" - return crate_id - - def BreakingUpdate(args): only_minor_updates = False # gnrt update - old_crate_ids = GetCurrentCrateIds() + old_crate_ids = crate_utils.GetCurrentCrateIds() print(f"Creating a major version update CL...") joined_remaining_args = ' '.join(args.remaining_args) print(f" Running `gnrt update -- {joined_remaining_args}` ...") GnrtUpdate(args.remaining_args, check_stdout=True, check_exitcode=True) - new_crate_ids = GetCurrentCrateIds() + new_crate_ids = crate_utils.GetCurrentCrateIds() if old_crate_ids == new_crate_ids: print(" `gnrt update` resulted in no changes...") return @@ -707,7 +621,7 @@ if args.skip: todo_crate_updates_without_skips = [] for old_crate_id, new_crate_id in todo_crate_updates: - crate_name = ConvertCrateIdToCrateName(old_crate_id) + crate_name = crate_utils.ConvertCrateIdToCrateName(old_crate_id) if not any( fnmatch.fnmatch(crate_name, pattern) for pattern in args.skip): @@ -740,13 +654,13 @@ branch_number = 1 while todo_crate_updates: - old_crate_ids = GetCurrentCrateIds() + old_crate_ids = crate_utils.GetCurrentCrateIds() for (old_crate_id, new_crate_id) in todo_crate_updates: upstream_branch = UpdateCrate(args, old_crate_id, new_crate_id, upstream_branch, branch_number) branch_number += 1 - new_crate_ids = GetCurrentCrateIds() + new_crate_ids = crate_utils.GetCurrentCrateIds() diff = DiffCrateIds(old_crate_ids, new_crate_ids, only_minor_updates) actually_updated_crate_ids = set([u.old_crate_id for u in diff.updates]) missed_crate_updates = [ @@ -772,9 +686,9 @@ print(f"Post-processing a manual edit of `Cargo.toml`...") print(f" Running `gnrt vendor` to detect `Cargo.lock` changes...") - old_crate_ids = GetCurrentCrateIds() + old_crate_ids = crate_utils.GetCurrentCrateIds() Gnrt("vendor") - new_crate_ids = GetCurrentCrateIds() + new_crate_ids = crate_utils.GetCurrentCrateIds() Git("reset", "--hard") Git("clean", "-d", "--force", "--", f"{THIRD_PARTY_RUST}") diff = DiffCrateIds(old_crate_ids, new_crate_ids, False)
diff --git a/tools/crates/create_update_cl_unittests.py b/tools/crates/create_update_cl_unittests.py index 2444f3ac..8c3d790 100755 --- a/tools/crates/create_update_cl_unittests.py +++ b/tools/crates/create_update_cl_unittests.py
@@ -8,17 +8,10 @@ import unittest from create_update_cl import ( - CHROMIUM_DIR, - ConvertCrateIdToCrateName, - ConvertCrateIdToCrateVersion, - ConvertCrateIdToEpochDir, - ConvertCrateIdToGnLabel, - ConvertCrateIdToVendorDir, CreateCommitDescription, CreateCommitTitle, CreateCommitTitleForBreakingUpdate, DiffCrateIds, - GetEpoch, SortedMarkdownList, ) @@ -134,49 +127,6 @@ class OtherTests(unittest.TestCase): - def testGetEpoch(self): - self.assertEqual(GetEpoch("0.1.2"), "v0_1") - self.assertEqual(GetEpoch("1.2.3"), "v1") - - def testConvertCrateIdToEpochDir(self): - actual_dir = ConvertCrateIdToEpochDir("foo-bar@1.2.3") - expected_suffix = os.path.join("third_party", "rust", "foo_bar", "v1") - self.assertEqual(actual_dir, os.path.join(CHROMIUM_DIR, - expected_suffix)) - - actual_dir = ConvertCrateIdToEpochDir("bar_baz@0.12.3") - expected_suffix = os.path.join("third_party", "rust", "bar_baz", - "v0_12") - self.assertEqual(actual_dir, os.path.join(CHROMIUM_DIR, - expected_suffix)) - - def testConvertCrateIdToGnLabel(self): - self.assertEqual(ConvertCrateIdToGnLabel("foo-bar@1.2.3"), - "//third_party/rust/foo_bar/v1:lib") - self.assertEqual(ConvertCrateIdToGnLabel("bar_baz@0.12.3"), - "//third_party/rust/bar_baz/v0_12:lib") - - def testConvertCrateIdToVendorDir(self): - actual_dir = ConvertCrateIdToVendorDir("foo-bar@1.2.3") - expected_suffix = os.path.join("third_party", "rust", - "chromium_crates_io", "vendor", - "foo-bar-v1") - self.assertEqual(actual_dir, os.path.join(CHROMIUM_DIR, - expected_suffix)) - - actual_dir = ConvertCrateIdToVendorDir("bar_baz@0.12.3") - expected_suffix = os.path.join("third_party", "rust", - "chromium_crates_io", "vendor", - "bar_baz-v0_12") - self.assertEqual(actual_dir, os.path.join(CHROMIUM_DIR, - expected_suffix)) - - def testConvertCrateIdToCrateName(self): - self.assertEqual(ConvertCrateIdToCrateName("foo-bar@1.2.3"), "foo-bar") - - def testConvertCrateIdToCrateVersion(self): - self.assertEqual(ConvertCrateIdToCrateVersion("foo-bar@1.2.3"), "1.2.3") - def testSortedMarkdownList(self): input = ["bbb " * 25, "aaa " * 30, "ccc " * 35] actual_output = SortedMarkdownList(input)
diff --git a/tools/json_schema_compiler/test/web_idl/basics.idl b/tools/json_schema_compiler/test/web_idl/basics.idl index 32ebe42..370a846 100644 --- a/tools/json_schema_compiler/test/web_idl/basics.idl +++ b/tools/json_schema_compiler/test/web_idl/basics.idl
@@ -17,6 +17,8 @@ static double returnsDouble(); static long returnsLong(); static DOMString returnsDOMString(); + static sequence<DOMString> returnsDOMStringSequence(); + static sequence<ExampleType> returnsCustomTypeSequence(); static undefined takesNoArguments(); static undefined takesDOMString(DOMString stringArgument); @@ -25,6 +27,9 @@ DOMString argument1, optional double argument2); static undefined takesOptionalInnerArgument( DOMString first, optional DOMString optionalInner, DOMString last); + static undefined takesSequenceArgument(sequence<boolean> sequenceArgument); + static undefined takesOptionalSequenceArgument( + optional sequence<boolean> optionalSequenceArgument); static ExampleType returnsCustomType(); static undefined takesCustomType(ExampleType customTypeArgument); @@ -35,8 +40,10 @@ static Promise<DOMString?> nullablePromiseReturn(); static Promise<ExampleType> customTypePromiseReturn(); static Promise<undefined> undefinedPromiseReturn(); + static Promise<sequence<long>> longSequencePromiseReturn(); + static Promise<sequence<ExampleType>> customTypeSequencePromiseReturn(); - // Test items for comment to description processing: + // Items for testing the processing of IDL comments to schema descriptions: static undefined noDescription(); // One line description. @@ -94,6 +101,8 @@ double someNumber; // Comment with HTML comment. <!-- Which should get through --> boolean? optionalBoolean; + // Comment on sequence type. + sequence<boolean> booleanSequence; }; partial interface Browser {
diff --git a/tools/json_schema_compiler/web_idl_schema.py b/tools/json_schema_compiler/web_idl_schema.py index 13fcad5b..733d579 100755 --- a/tools/json_schema_compiler/web_idl_schema.py +++ b/tools/json_schema_compiler/web_idl_schema.py
@@ -301,6 +301,11 @@ # with 'parameters' list that has a single element for the type. properties['parameters'] = self._ExtractParametersFromPromiseType( type_details) + elif type_details.IsA('Sequence'): + properties['type'] = 'array' + # Sequences are used to represent array types, which have an associated + # 'items' key that detail what type the array holds. + properties['items'] = ArrayType(type_details).Process() else: raise SchemaCompilerError('Unsupported type class when processing type.', type_details) @@ -422,6 +427,13 @@ return self.properties +class ArrayType(TypedProperty): + """Handles processing for the type an array (IDL Sequence) consists of.""" + + def Process(self) -> dict: + return self.properties + + class DictionaryMember(TypedProperty): """Handles processing for members of custom types (dictionaries)."""
diff --git a/tools/json_schema_compiler/web_idl_schema_test.py b/tools/json_schema_compiler/web_idl_schema_test.py index 50de0a9..2217d1f 100755 --- a/tools/json_schema_compiler/web_idl_schema_test.py +++ b/tools/json_schema_compiler/web_idl_schema_test.py
@@ -165,6 +165,22 @@ 'name': 'returnsCustomType', '$ref': 'ExampleType' }, getFunctionReturn(schema, 'returnsCustomType')) + self.assertEqual( + { + 'name': 'returnsDOMStringSequence', + 'type': 'array', + 'items': { + 'type': 'string' + } + }, getFunctionReturn(schema, 'returnsDOMStringSequence')) + self.assertEqual( + { + 'name': 'returnsCustomTypeSequence', + 'type': 'array', + 'items': { + '$ref': 'ExampleType' + } + }, getFunctionReturn(schema, 'returnsCustomTypeSequence')) def testPromiseBasedReturn(self): schema = self.idl_basics @@ -198,6 +214,28 @@ 'parameters': [], 'type': 'promise' }, getFunctionAsyncReturn(schema, 'undefinedPromiseReturn')) + self.assertEqual( + { + 'name': 'callback', + 'parameters': [{ + 'type': 'array', + 'items': { + 'type': 'integer' + } + }], + 'type': 'promise' + }, getFunctionAsyncReturn(schema, 'longSequencePromiseReturn')) + self.assertEqual( + { + 'name': 'callback', + 'parameters': [{ + 'type': 'array', + 'items': { + '$ref': 'ExampleType' + } + }], + 'type': 'promise' + }, getFunctionAsyncReturn(schema, 'customTypeSequencePromiseReturn')) # Tests function parameters are processed as expected. def testFunctionParameters(self): @@ -234,6 +272,21 @@ 'type': 'string' }], getFunctionParameters(schema, 'takesOptionalInnerArgument')) self.assertEqual([{ + 'name': 'sequenceArgument', + 'type': 'array', + 'items': { + 'type': 'boolean' + } + }], getFunctionParameters(schema, 'takesSequenceArgument')) + self.assertEqual([{ + 'name': 'optionalSequenceArgument', + 'type': 'array', + 'optional': True, + 'items': { + 'type': 'boolean' + } + }], getFunctionParameters(schema, 'takesOptionalSequenceArgument')) + self.assertEqual([{ 'name': 'customTypeArgument', '$ref': 'ExampleType' }], getFunctionParameters(schema, 'takesCustomType')) @@ -325,47 +378,47 @@ # processed into types on the resulting namespace. def testApiTypesOnNamespace(self): schema = self.idl_basics + custom_type = getType(schema, 'ExampleType') + self.assertEqual('ExampleType', custom_type['id']) + self.assertEqual('object', custom_type['type']) self.assertEqual( { - 'id': 'ExampleType', - 'properties': { - 'someString': { - 'name': - 'someString', - 'type': - 'string', - 'description': - ('Attribute comment attached to ExampleType.someString.'), - }, - 'someNumber': { - 'name': - 'someNumber', - 'type': - 'number', - 'description': - ('Comment where <var>someNumber</var> has some markup.'), - }, - # TODO(crbug.com/379052294): using HTML comments like this is a - # bit of a hack to allow us to add comments in IDL files (e.g. - # for TODOs) and to not have them end up on the documentation - # site. We should probably just filter them out during - # compilation. - 'optionalBoolean': { - 'name': - 'optionalBoolean', - 'type': - 'boolean', - 'optional': - True, - 'description': - ('Comment with HTML comment. <!-- Which should get' - ' through -->'), - }, + 'name': 'someString', + 'type': 'string', + 'description': + 'Attribute comment attached to ExampleType.someString.' + }, custom_type['properties']['someString']) + self.assertEqual( + { + 'name': 'someNumber', + 'type': 'number', + 'description': + 'Comment where <var>someNumber</var> has some markup.' + }, custom_type['properties']['someNumber']) + # TODO(crbug.com/379052294): using HTML comments like this is a bit of a + # hack to allow us to add comments in IDL files (e.g. for TODOs) and to not + # have them end up on the documentation site. We should probably just filter + # them out during compilation. + self.assertEqual( + { + 'name': + 'optionalBoolean', + 'type': + 'boolean', + 'optional': + True, + 'description': + 'Comment with HTML comment. <!-- Which should get through -->' + }, custom_type['properties']['optionalBoolean']) + self.assertEqual( + { + 'name': 'booleanSequence', + 'type': 'array', + 'items': { + 'type': 'boolean' }, - 'type': 'object', - }, - getType(schema, 'ExampleType'), - ) + 'description': 'Comment on sequence type.', + }, custom_type['properties']['booleanSequence']) # Tests that a top level API comment is processed into a description # attribute, with HTML paragraph nodes added due to the blank commented line.
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 487878c..fde26c3 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -40133,6 +40133,24 @@ </description> </action> +<action name="Signin_Signin_FromNonModalSigninBookmarkPromo"> + <owner>kanouche@google.com</owner> + <owner>bling-mony-pod@google.com</owner> + <description> + Recorded on sign in start from access point + signin_metrics::AccessPoint::kNonModalSigninBookmarkPromo. + </description> +</action> + +<action name="Signin_Signin_FromNonModalSigninPasswordPromo"> + <owner>kanouche@google.com</owner> + <owner>bling-mony-pod@google.com</owner> + <description> + Recorded on sign in start from access point + signin_metrics::AccessPoint::kNonModalSigninPasswordPromo. + </description> +</action> + <action name="Signin_Signin_FromNotificationsOptInScreenContentToggle"> <owner>hiramahmood@google.com</owner> <owner>scottyoder@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 2de32181..a08dc3c 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -4078,24 +4078,6 @@ </summary> </histogram> -<histogram name="Ash.Frame.ColorChangeCount.{AppType}" units="count" - expires_after="2025-05-11"> - <owner>lingyufeng@google.com</owner> - <owner>arc-framework@google.com</owner> - <summary> - Tracks the number of frame color changes when a {AppType} is launched. The - data is collected once per app launching. - </summary> - <token key="AppType"> - <variant name="ArcApp"/> - <variant name="Browser"/> - <variant name="ChromeApp"/> - <variant name="CrostiniApp"/> - <variant name="Others"/> - <variant name="SystemApp"/> - </token> -</histogram> - <histogram name="Ash.FullRestore.Browser.FirstInputDelay" units="ms" expires_after="2025-11-02"> <owner>esum@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index deda7fbc..1a2e11c 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -70,6 +70,12 @@ summary="Only product description was visible"/> </variants> +<variants name="Autofill.CreditCardBenefitSource"> + <variant name="Amex" summary="American Express"/> + <variant name="Bmo" summary="BMO"/> + <variant name="Curinos" summary="Curinos"/> +</variants> + <variants name="Autofill.CreditCardIssuerId"> <variant name="Amex" summary="card issued by American Express"/> <variant name="Anz" summary="card issued by ANZ"/> @@ -84,11 +90,6 @@ <variant name="Natwest" summary="card issued by Natwest"/> </variants> -<variants name="Autofill.CreditCardIssuerId.WithBenefits"> - <variant name="Amex" summary="card issued by American Express"/> - <variant name="Bmo" summary="card issued by BMO"/> -</variants> - <variants name="Autofill.CreditCardNetwork"> <variant name="Mastercard" summary="card with the Mastercard network."/> <variant name="Visa" summary="card with the Visa network."/> @@ -3079,19 +3080,18 @@ </summary> </histogram> -<histogram name="Autofill.FormEvents.CreditCard.WithBenefits.{CardIssuerId}" +<histogram + name="Autofill.FormEvents.CreditCard.WithBenefits.{CardBenefitSource}" enum="AutofillFormEvent" expires_after="2025-11-09"> - <owner>alexandertekle@google.com</owner> <owner>yishuil@google.com</owner> <summary> Autofill form events for credit card forms that contain at least one suggestion where a card benefit is available. This includes logging for when card suggestions with benefits are shown, selected, filled, and submitted, - and logs at each of those times. Log emission pertains to the credit card - issuer, {CardIssuerId}. + and logs at each of those times. Log emission pertains to credit cards where + the benefit source is {CardBenefitSource}. </summary> - <token key="CardIssuerId" - variants="Autofill.CreditCardIssuerId.WithBenefits"/> + <token key="CardBenefitSource" variants="Autofill.CreditCardBenefitSource"/> </histogram> <histogram name="Autofill.FormEvents.CreditCard.WithOffer"
diff --git a/tools/metrics/histograms/metadata/collaboration_service/enums.xml b/tools/metrics/histograms/metadata/collaboration_service/enums.xml index 0403b0d..d015402 100644 --- a/tools/metrics/histograms/metadata/collaboration_service/enums.xml +++ b/tools/metrics/histograms/metadata/collaboration_service/enums.xml
@@ -161,18 +161,6 @@ <!-- LINT.ThenChange(//components/collaboration/internal/metrics.h:CollaborationServiceShareOrManageEvent) --> -<!-- LINT.IfChange(CollaborationServiceStep) --> - -<enum name="CollaborationServiceStep"> - <int value="0" label="Unknown"/> - <int value="1" label="Time for authentication success"/> - <int value="2" label="Time for services initialization"/> - <int value="3" label="Time for link to be ready after group creation"/> - <int value="4" label="Time for tab group to be fetched after group creation"/> -</enum> - -<!-- LINT.ThenChange(//components/collaboration/internal/metrics.h:CollaborationServiceStep) --> - </enums> </histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/collaboration_service/histograms.xml b/tools/metrics/histograms/metadata/collaboration_service/histograms.xml index 00bda2f..cf71d8a 100644 --- a/tools/metrics/histograms/metadata/collaboration_service/histograms.xml +++ b/tools/metrics/histograms/metadata/collaboration_service/histograms.xml
@@ -22,6 +22,18 @@ <histograms> +<variants name="CollaborationServiceStep"> + <variant name="AuthenticationInitToSuccess" + summary="Authentication initiated to successful completion"/> + <variant name="LinkReadyAfterGroupCreation" + summary="Link ready after group creation"/> + <variant name="TabGroupFetchedAfterPeopleGroupJoined" + summary="Tab group fetched after group creation"/> + <variant name="Unknown" summary="Unknown"/> + <variant name="WaitingForServicesInitialization" + summary="Waiting time for service initialization"/> +</variants> + <histogram name="CollaborationService.JoinFlow" enum="CollaborationServiceJoinEvent" expires_after="2025-10-11"> <owner>dljames@chromium.org</owner> @@ -45,17 +57,18 @@ </summary> </histogram> -<histogram name="CollaborationService.Latency" enum="CollaborationServiceStep" - expires_after="2025-10-11"> +<histogram name="CollaborationService.Latency2.{CollaborationServiceStep}" + units="ms" expires_after="2025-10-11"> <owner>haileywang@google.com</owner> <owner>chrome-tab-group-eng@google.com</owner> <summary> [ All platforms ] Tracks the time in milliseconds between when a flow step is started and finished. - Recorded by the CollaborationService for each step in a collaboration flow - that has user wait time. + Recorded by the CollaborationService for each {CollaborationServiceStep} in + a collaboration flow that has user wait time. </summary> + <token key="CollaborationServiceStep" variants="CollaborationServiceStep"/> </histogram> <histogram name="CollaborationService.ShareOrManageFlow"
diff --git a/tools/metrics/histograms/metadata/enterprise/enums.xml b/tools/metrics/histograms/metadata/enterprise/enums.xml index 8f1d648..ed3fe225 100644 --- a/tools/metrics/histograms/metadata/enterprise/enums.xml +++ b/tools/metrics/histograms/metadata/enterprise/enums.xml
@@ -34,6 +34,7 @@ <enum name="CertificatePrivateKeySource"> <int value="0" label="Unexportable"/> <int value="1" label="Software"/> + <int value="2" label="OsSoftware"/> </enum> <enum name="CertificateProvisioningError">
diff --git a/tools/metrics/histograms/metadata/glic/enums.xml b/tools/metrics/histograms/metadata/glic/enums.xml index 837bd02..7f47872 100644 --- a/tools/metrics/histograms/metadata/glic/enums.xml +++ b/tools/metrics/histograms/metadata/glic/enums.xml
@@ -56,6 +56,28 @@ <!-- LINT.ThenChange(//chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_utils.h:DeepScanAccessPoint) --> +<!-- LINT.IfChange(FreWebUiState) --> + +<enum name="FreWebUiState"> + <int value="0" label="Glic fre app controller not started."/> + <int value="1" label="Web client begins loading; no visible UI."/> + <int value="2" + label="Loading panel is displayed. This state, combined with the + `hold-loading` state, will be held for `kMinHoldLoadingTimeMs` + if entered."/> + <int value="3" + label="Loading panel is still displayed, but the web client is ready. + This state will be held for the remainder of + `kMinHoldLoadingTimeMs`."/> + <int value="4" + label="Loading panel is displayed until web client is ready, or until"/> + <int value="5" label="'Something went wrong' error panel is displayed."/> + <int value="6" label="Connection offline panel is displayed."/> + <int value="7" label="Web view is displayed."/> +</enum> + +<!-- LINT.ThenChange(//chrome/browser/glic/fre/glic_fre.mojom:FreWebUiState) --> + <!-- LINT.IfChange(GlicAttachChangeReason) --> <enum name="GlicAttachChangeReason">
diff --git a/tools/metrics/histograms/metadata/glic/histograms.xml b/tools/metrics/histograms/metadata/glic/histograms.xml index 59e4d26..195ac2a2 100644 --- a/tools/metrics/histograms/metadata/glic/histograms.xml +++ b/tools/metrics/histograms/metadata/glic/histograms.xml
@@ -166,6 +166,13 @@ </summary> </histogram> +<histogram name="Glic.FreModalWebUiState.FinishState" enum="FreWebUiState" + expires_after="2026-01-15"> + <owner>cuianthony@google.com</owner> + <owner>iwells@google.com</owner> + <summary>Record the current state of the FRE modal when it closes.</summary> +</histogram> + <histogram name="Glic.FrePresentationTime" units="ms" expires_after="2026-01-15"> <owner>dewittj@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/net/enums.xml b/tools/metrics/histograms/metadata/net/enums.xml index 6e602ce..a1c9a8b 100644 --- a/tools/metrics/histograms/metadata/net/enums.xml +++ b/tools/metrics/histograms/metadata/net/enums.xml
@@ -273,6 +273,17 @@ <!-- LINT.ThenChange(//net/device_bound_sessions/session_error.h:DeviceBoundSessionError) --> +<!-- LINT.IfChange(DeviceBoundSessionUsage) --> + +<enum name="DeviceBoundSessionUsage"> + <int value="0" label="Unknown"/> + <int value="1" label="Not in scope of any session"/> + <int value="2" label="In scope but not deferred"/> + <int value="3" label="In scope and deferred"/> +</enum> + +<!-- LINT.ThenChange(//net/device_bound_sessions/session_usage.h:DeviceBoundSessionUsage) --> + <enum name="DNS.AttemptType"> <int value="0" label="DnsUDPAttempt"/> <int value="1" label="DnsTCPAttempt due to low UDP entropy"/>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml index f654280..947ca38c 100644 --- a/tools/metrics/histograms/metadata/net/histograms.xml +++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -1538,7 +1538,20 @@ <summary> This records how many times a request was deferred due to a Device Bound Session (https://github.com/w3c/webappsec-dbsc/blob/main/README.md). This is - logged once for every network request. + logged once for most network requests that can add a cookie header; requests + that attempt to refresh but fail are omitted. + </summary> +</histogram> + +<histogram name="Net.DeviceBoundSessions.RequestDeferralDecision" + enum="DeviceBoundSessionUsage" expires_after="2025-11-13"> + <owner>thefrog@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + This records whether a request was deferred due to a Device Bound Session + (https://github.com/w3c/webappsec-dbsc/blob/main/README.md) and the reason + for that decision. This is logged once for most network requests that can + add a cookie header; requests that attempt to refresh but fail are omitted. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml index be5fd27..a4f38c4f 100644 --- a/tools/metrics/histograms/metadata/optimization/histograms.xml +++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -2195,8 +2195,8 @@ <histogram name="OptimizationGuide.TextSafetyChecker.InferenceResult" enum="OptimizationGuideTextSafetyInferenceResult" expires_after="2025-10-26"> - <owner>rockot@google.com</owner> - <owner>sophiechange@chromium.org</owner> + <owner>holte@google.com</owner> + <owner>sophiechang@chromium.org</owner> <summary> The result of a text safety inference request. Recorded once for each such request. @@ -2205,8 +2205,8 @@ <histogram name="OptimizationGuide.TextSafetyChecker.InitTime" units="ms" expires_after="2025-10-19"> - <owner>rockot@google.com</owner> - <owner>sophiechange@chromium.org</owner> + <owner>holte@google.com</owner> + <owner>sophiechang@chromium.org</owner> <summary> The duration of the text safety checker's initialization time. Recorded once for each new model execution session. @@ -2215,8 +2215,8 @@ <histogram name="OptimizationGuide.TextSafetyChecker.ModelCreationTime" units="ms" expires_after="2025-10-19"> - <owner>rockot@google.com</owner> - <owner>sophiechange@chromium.org</owner> + <owner>holte@google.com</owner> + <owner>sophiechang@chromium.org</owner> <summary> The duration elapsed during text safety model creation. Recorded once for each text safety inference request. @@ -2225,8 +2225,8 @@ <histogram name="OptimizationGuide.TextSafetyChecker.ModelExecutionTime" units="ms" expires_after="M145"> - <owner>rockot@google.com</owner> - <owner>sophiechange@chromium.org</owner> + <owner>holte@google.com</owner> + <owner>sophiechang@chromium.org</owner> <summary> The duration of text safety model execution. Recorded once for each text safety inference request. @@ -2235,8 +2235,8 @@ <histogram name="OptimizationGuide.TextSafetyChecker.TokensPerSecond" units="counts" expires_after="2025-10-26"> - <owner>rockot@google.com</owner> - <owner>sophiechange@chromium.org</owner> + <owner>holte@google.com</owner> + <owner>sophiechang@chromium.org</owner> <summary> An estimate of the text safety model's inference throughput in tokens per second. Recorded once for each text safety inference request.
diff --git a/tools/metrics/histograms/metadata/signin/enums.xml b/tools/metrics/histograms/metadata/signin/enums.xml index 9fd5191..8ff089e 100644 --- a/tools/metrics/histograms/metadata/signin/enums.xml +++ b/tools/metrics/histograms/metadata/signin/enums.xml
@@ -763,6 +763,10 @@ <int value="81" label="History sync educational tip module (Android only)"/> <int value="82" label="Managed profile was automatically signed in (iOS only)"/> + <int value="83" + label="Contextual non modal sign-in password promo (iOS only)"/> + <int value="84" + label="Contextual non modal sign-in bookmark promo (iOS only)"/> </enum> <enum name="SigninAccountReconcilorState">
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml index 8301b77..36e67a8 100644 --- a/tools/metrics/histograms/metadata/tab/histograms.xml +++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -3573,6 +3573,26 @@ </summary> </histogram> +<histogram name="TabStrip.Tab.ContextMenuReloadCount" units="tabs" + expires_after="2025-11-14"> + <owner>agale@chromium.org</owner> + <owner>top-chrome-desktop-ui@google.com</owner> + <summary> + When the user reloads a tab using the tab context menu, records the number + of tabs being reloaded. + </summary> +</histogram> + +<histogram name="TabStrip.Tab.ReloadCount" units="tabs" + expires_after="2025-11-14"> + <owner>agale@chromium.org</owner> + <owner>top-chrome-desktop-ui@google.com</owner> + <summary> + When the user reloads a tab using the toolbar button, hotkey, or contents + context menu, records the number of tabs being reloaded. + </summary> +</histogram> + <histogram name="TabStrip.Tab.{Framework}.ActivationAction" enum="TabActivationTypes" expires_after="2025-09-14"> <owner>yuhengh@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 1559545..5a93941 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@ }, "win": { "hash": "51491773ab5c0cecb7f5dfa9cd5003db755da0f3", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/9fa4d6fe6c2b7e26c3a87d2c0adee33f2898030c/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/6690560f58167a82a9302a6df05303324f0e91bb/trace_processor_shell.exe" }, "linux_arm": { "hash": "99f971ca131f6d11c73f4b918099d434bdd8093c",
diff --git a/tools/rust/update_rust.py b/tools/rust/update_rust.py index e4cf4e0c..805a9c6e 100755 --- a/tools/rust/update_rust.py +++ b/tools/rust/update_rust.py
@@ -32,7 +32,7 @@ # These fields are written by //tools/clang/scripts/upload_revision.py, and # should not be changed manually. # They are also read by build/config/compiler/BUILD.gn. -RUST_REVISION = 'c8f94230282a8e8c1148f3e657f0199aad909228' +RUST_REVISION = '4a0969e06dbeaaa43914d2d00b2e843d49aa3886' RUST_SUB_REVISION = 1 # The revision of Crubit to use from https://github.com/google/crubit @@ -47,7 +47,7 @@ # Hash of src/stage0.json, which itself contains the stage0 toolchain hashes. # We trust the Rust build system checks, but to ensure it is not tampered with # itself check the hash. -STAGE0_JSON_SHA256 = '1113296e1412c791d09f3033355001061e7ca36e06e796ff0f1f798791a6d93b' +STAGE0_JSON_SHA256 = '981bcaeac1c5f7035166cd59941e4a8e2070c9eb977bc9ef881e656b60c79055' THIS_DIR = os.path.abspath(os.path.dirname(__file__)) CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..'))
diff --git a/ui/android/javatests/src/org/chromium/ui/test/util/RenderTestRule.java b/ui/android/javatests/src/org/chromium/ui/test/util/RenderTestRule.java index b9208161..d8daecd 100644 --- a/ui/android/javatests/src/org/chromium/ui/test/util/RenderTestRule.java +++ b/ui/android/javatests/src/org/chromium/ui/test/util/RenderTestRule.java
@@ -140,6 +140,7 @@ Component.UI_BROWSER_AUTOFILL, Component.UI_BROWSER_BOOKMARKS, Component.UI_BROWSER_BUBBLES_PAGE_INFO, + Component.UI_BROWSER_CHROME_TABS_CHROME_TAB_GROUPS_SHARED_TAB_GROUPS, Component.UI_BROWSER_CONTENT_SUGGESTIONS, Component.UI_BROWSER_CONTENT_SUGGESTIONS_FEED, Component.UI_BROWSER_CONTENT_SUGGESTIONS_HISTORY, @@ -174,7 +175,7 @@ Component.UI_BROWSER_TOOLBAR, Component.UI_BROWSER_THUMBNAIL, Component.UI_BROWSER_WEB_APP_INSTALLS, - Component.UI_SETTINGS_PRIVACY + Component.UI_SETTINGS_PRIVACY, }) @Retention(RetentionPolicy.SOURCE) public @interface Component { @@ -190,6 +191,8 @@ String UI_BROWSER_AUTOFILL = "UI>Browser>Autofill"; String UI_BROWSER_BOOKMARKS = "UI>Browser>Bookmarks"; String UI_BROWSER_BUBBLES_PAGE_INFO = "UI>Browser>Bubbles>PageInfo"; + String UI_BROWSER_CHROME_TABS_CHROME_TAB_GROUPS_SHARED_TAB_GROUPS = + "UI>Browser>ChromeTabs>ChromeTabGroups>SharedTabGroups"; String UI_BROWSER_CONTENT_SUGGESTIONS = "UI>Browser>ContentSuggestions"; String UI_BROWSER_CONTENT_SUGGESTIONS_FEED = "UI>Browser>ContentSuggestions>Feed"; String UI_BROWSER_CONTENT_SUGGESTIONS_HISTORY = "UI>Browser>ContentSuggestions>History";
diff --git a/ui/gfx/buffer_types.h b/ui/gfx/buffer_types.h index b9745cf..9de8271ca 100644 --- a/ui/gfx/buffer_types.h +++ b/ui/gfx/buffer_types.h
@@ -7,8 +7,6 @@ #include <stdint.h> -#include <tuple> - namespace gfx { // The format needs to be taken into account when mapping a buffer into the @@ -75,7 +73,7 @@ : usage(usage), format(format) {} bool operator==(const BufferUsageAndFormat& other) const { - return std::tie(usage, format) == std::tie(other.usage, other.format); + return usage == other.usage && format == other.format; } BufferUsage usage;
diff --git a/ui/menus/android/menu_model_bridge.cc b/ui/menus/android/menu_model_bridge.cc index 5d49cfe..da2a4c4 100644 --- a/ui/menus/android/menu_model_bridge.cc +++ b/ui/menus/android/menu_model_bridge.cc
@@ -26,6 +26,9 @@ JNIEnv* env = base::android::AttachCurrentThread(); java_obj_ = Java_MenuModelBridge_create(env); } + +MenuModelBridge::~MenuModelBridge() = default; + void MenuModelBridge::AddExtensionItems(ui::MenuModel* menu_model) { JNIEnv* env = base::android::AttachCurrentThread(); for (size_t i = 0; i < menu_model->GetItemCount(); ++i) {
diff --git a/url/url_canon.h b/url/url_canon.h index 9de4f64a..c93dbf68 100644 --- a/url/url_canon.h +++ b/url/url_canon.h
@@ -345,13 +345,11 @@ // // The 8-bit version requires UTF-8 encoding. COMPONENT_EXPORT(URL) -bool CanonicalizeScheme(const char* spec, - const Component& scheme, +bool CanonicalizeScheme(std::optional<std::string_view> input, CanonOutput* output, Component* out_scheme); COMPONENT_EXPORT(URL) -bool CanonicalizeScheme(const char16_t* spec, - const Component& scheme, +bool CanonicalizeScheme(std::optional<std::u16string_view> input, CanonOutput* output, Component* out_scheme);
diff --git a/url/url_canon_etc.cc b/url/url_canon_etc.cc index dcb5e3f..96b98303 100644 --- a/url/url_canon_etc.cc +++ b/url/url_canon_etc.cc
@@ -118,17 +118,18 @@ } template <typename CHAR, typename UCHAR> -bool DoScheme(const CHAR* spec, - const Component& scheme, +bool DoScheme(std::optional<std::basic_string_view<CHAR>> input, CanonOutput* output, Component* out_scheme) { - if (scheme.is_empty()) { + if (!input.has_value() || input->empty()) { // Scheme is unspecified or empty, convert to empty by appending a colon. *out_scheme = Component(output->length(), 0); output->push_back(':'); return false; } + auto input_value = input.value(); + // The output scheme starts from the current position. out_scheme->begin = output->length(); @@ -138,13 +139,11 @@ // FindAndCompareScheme, which could cause some security checks on // schemes to be incorrect. bool success = true; - size_t begin = static_cast<size_t>(scheme.begin); - size_t end = static_cast<size_t>(scheme.end()); - for (size_t i = begin; i < end; i++) { - UCHAR ch = static_cast<UCHAR>(spec[i]); + for (size_t i = 0; i < input_value.length(); i++) { + UCHAR ch = static_cast<UCHAR>(input_value[i]); char replacement = 0; if (ch < 0x80) { - if (i == begin) { + if (i == 0) { // Need to do a special check for the first letter of the scheme. if (IsSchemeFirstChar(static_cast<unsigned char>(ch))) replacement = kSchemeCanonical[ch]; @@ -167,7 +166,8 @@ // This will escape the output and also handle encoding issues. // Ignore the return value since we already failed. - AppendUTF8EscapedChar(spec, &i, end, output); + AppendUTF8EscapedChar(input_value.data(), &i, input_value.length(), + output); } } @@ -363,18 +363,16 @@ return kSchemeCanonical[ch]; } -bool CanonicalizeScheme(const char* spec, - const Component& scheme, +bool CanonicalizeScheme(std::optional<std::string_view> input, CanonOutput* output, Component* out_scheme) { - return DoScheme<char, unsigned char>(spec, scheme, output, out_scheme); + return DoScheme<char, unsigned char>(input, output, out_scheme); } -bool CanonicalizeScheme(const char16_t* spec, - const Component& scheme, +bool CanonicalizeScheme(std::optional<std::u16string_view> input, CanonOutput* output, Component* out_scheme) { - return DoScheme<char16_t, char16_t>(spec, scheme, output, out_scheme); + return DoScheme<char16_t, char16_t>(input, output, out_scheme); } bool CanonicalizeUserInfo(const char* username_source,
diff --git a/url/url_canon_non_special_url.cc b/url/url_canon_non_special_url.cc index 8c55bac1..9a6b856 100644 --- a/url/url_canon_non_special_url.cc +++ b/url/url_canon_non_special_url.cc
@@ -32,8 +32,9 @@ DCHECK(!parsed.has_opaque_path); // Scheme: this will append the colon. - bool success = CanonicalizeScheme(source.scheme, parsed.scheme, &output, - &new_parsed.scheme); + bool success = + CanonicalizeScheme(parsed.scheme.maybe_as_string_view_on(source.scheme), + &output, &new_parsed.scheme); bool have_authority = (parsed.username.is_valid() || parsed.password.is_valid() || parsed.host.is_valid() || parsed.port.is_valid());
diff --git a/url/url_canon_pathurl.cc b/url/url_canon_pathurl.cc index 17269084..0798270 100644 --- a/url/url_canon_pathurl.cc +++ b/url/url_canon_pathurl.cc
@@ -59,8 +59,9 @@ CanonOutput* output, Parsed* new_parsed) { // Scheme: this will append the colon. - bool success = CanonicalizeScheme(source.scheme, parsed.scheme, - output, &new_parsed->scheme); + bool success = + CanonicalizeScheme(parsed.scheme.maybe_as_string_view_on(source.scheme), + output, &new_parsed->scheme); // We assume there's no authority for path URLs. Note that hosts should never // have -1 length.
diff --git a/url/url_canon_stdurl.cc b/url/url_canon_stdurl.cc index 659d0ee..eeb14e6 100644 --- a/url/url_canon_stdurl.cc +++ b/url/url_canon_stdurl.cc
@@ -28,8 +28,9 @@ DCHECK(!parsed.has_opaque_path); // Scheme: this will append the colon. - bool success = CanonicalizeScheme(source.scheme, parsed.scheme, - output, &new_parsed->scheme); + bool success = + CanonicalizeScheme(parsed.scheme.maybe_as_string_view_on(source.scheme), + output, &new_parsed->scheme); bool scheme_supports_user_info = (scheme_type == SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION);
diff --git a/url/url_canon_unittest.cc b/url/url_canon_unittest.cc index b297c7c2..f1b27b6c 100644 --- a/url/url_canon_unittest.cc +++ b/url/url_canon_unittest.cc
@@ -334,8 +334,8 @@ out_str.clear(); StdStringCanonOutput output1(&out_str); - bool success = - CanonicalizeScheme(scheme_case.input, in_comp, &output1, &out_comp); + bool success = CanonicalizeScheme( + in_comp.as_string_view_on(scheme_case.input), &output1, &out_comp); output1.Complete(); EXPECT_EQ(scheme_case.expected_success, success); @@ -349,8 +349,8 @@ std::u16string wide_input(base::UTF8ToUTF16(scheme_case.input)); in_comp.len = static_cast<int>(wide_input.length()); - success = CanonicalizeScheme(wide_input.c_str(), in_comp, &output2, - &out_comp); + success = CanonicalizeScheme(in_comp.as_string_view_on(wide_input.c_str()), + &output2, &out_comp); output2.Complete(); EXPECT_EQ(scheme_case.expected_success, success); @@ -365,7 +365,8 @@ out_str.clear(); StdStringCanonOutput output(&out_str); - EXPECT_FALSE(CanonicalizeScheme("", Component(0, -1), &output, &out_comp)); + EXPECT_FALSE(CanonicalizeScheme(std::optional<std::string_view>(std::nullopt), + &output, &out_comp)); output.Complete(); EXPECT_EQ(":", out_str);
diff --git a/url/url_util.cc b/url/url_util.cc index 67c4c5f..e09d63e 100644 --- a/url/url_util.cc +++ b/url/url_util.cc
@@ -458,8 +458,8 @@ // the existing spec. STACK_UNINITIALIZED RawCanonOutput<128> scheme_replaced; Component scheme_replaced_parsed; - CanonicalizeScheme(replacements.sources().scheme, - replacements.components().scheme, + CanonicalizeScheme(replacements.components().scheme.as_string_view_on( + replacements.sources().scheme), &scheme_replaced, &scheme_replaced_parsed); // We can assume that the input is canonicalized, which means it always has
diff --git a/v8 b/v8 index 5532a66..a6505e5 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit 5532a667175e9b1a2597111ab674e8ba09c8d505 +Subproject commit a6505e5f6d22a63788a3ee59f44ca539774fbe4c